summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'cpu')
-rw-r--r--cpu/74xx_7xx/Makefile23
-rw-r--r--cpu/74xx_7xx/cpu.c3
-rw-r--r--cpu/74xx_7xx/start.S3
-rw-r--r--cpu/arm1136/Makefile18
-rw-r--r--cpu/arm720t/Makefile18
-rw-r--r--cpu/arm920t/Makefile18
-rw-r--r--cpu/arm920t/at91rm9200/Makefile21
-rw-r--r--cpu/arm920t/imx/Makefile17
-rw-r--r--cpu/arm920t/ks8695/Makefile21
-rw-r--r--cpu/arm920t/s3c24x0/Makefile17
-rw-r--r--cpu/arm920t/s3c24x0/i2c.c2
-rw-r--r--cpu/arm920t/s3c24x0/interrupts.c4
-rw-r--r--cpu/arm925t/Makefile18
-rw-r--r--cpu/arm926ejs/Makefile18
-rw-r--r--cpu/arm926ejs/cpuinfo.c244
-rw-r--r--cpu/arm926ejs/omap/Makefile22
-rw-r--r--cpu/arm926ejs/versatile/Makefile22
-rw-r--r--cpu/arm946es/Makefile18
-rw-r--r--cpu/arm_intcm/Makefile18
-rw-r--r--cpu/bf533/Makefile18
-rw-r--r--cpu/i386/Makefile23
-rw-r--r--cpu/i386/sc520.c18
-rw-r--r--cpu/i386/sc520_asm.S52
-rw-r--r--cpu/ixp/Makefile18
-rw-r--r--cpu/ixp/config.mk2
-rw-r--r--cpu/ixp/cpu.c61
-rw-r--r--cpu/ixp/interrupts.c115
-rw-r--r--cpu/ixp/npe/IxEthAcc.c261
-rw-r--r--cpu/ixp/npe/IxEthAccCommon.c1049
-rw-r--r--cpu/ixp/npe/IxEthAccControlInterface.c533
-rw-r--r--cpu/ixp/npe/IxEthAccDataPlane.c2483
-rw-r--r--cpu/ixp/npe/IxEthAccMac.c2641
-rw-r--r--cpu/ixp/npe/IxEthAccMii.c410
-rw-r--r--cpu/ixp/npe/IxEthDBAPI.c448
-rw-r--r--cpu/ixp/npe/IxEthDBAPISupport.c678
-rw-r--r--cpu/ixp/npe/IxEthDBCore.c463
-rw-r--r--cpu/ixp/npe/IxEthDBEvents.c520
-rw-r--r--cpu/ixp/npe/IxEthDBFeatures.c662
-rw-r--r--cpu/ixp/npe/IxEthDBFirewall.c266
-rw-r--r--cpu/ixp/npe/IxEthDBHashtable.c642
-rw-r--r--cpu/ixp/npe/IxEthDBLearning.c149
-rw-r--r--cpu/ixp/npe/IxEthDBMem.c649
-rw-r--r--cpu/ixp/npe/IxEthDBNPEAdaptor.c719
-rw-r--r--cpu/ixp/npe/IxEthDBPortUpdate.c740
-rw-r--r--cpu/ixp/npe/IxEthDBReports.c652
-rw-r--r--cpu/ixp/npe/IxEthDBSearch.c327
-rw-r--r--cpu/ixp/npe/IxEthDBSpanningTree.c107
-rw-r--r--cpu/ixp/npe/IxEthDBUtil.c120
-rw-r--r--cpu/ixp/npe/IxEthDBVlan.c1179
-rw-r--r--cpu/ixp/npe/IxEthDBWiFi.c480
-rw-r--r--cpu/ixp/npe/IxEthMii.c497
-rw-r--r--cpu/ixp/npe/IxFeatureCtrl.c422
-rw-r--r--cpu/ixp/npe/IxNpeDl.c972
-rw-r--r--cpu/ixp/npe/IxNpeDlImageMgr.c675
-rw-r--r--cpu/ixp/npe/IxNpeDlNpeMgr.c936
-rw-r--r--cpu/ixp/npe/IxNpeDlNpeMgrUtils.c806
-rw-r--r--cpu/ixp/npe/IxNpeMh.c582
-rw-r--r--cpu/ixp/npe/IxNpeMhConfig.c608
-rw-r--r--cpu/ixp/npe/IxNpeMhReceive.c320
-rw-r--r--cpu/ixp/npe/IxNpeMhSend.c307
-rw-r--r--cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c358
-rw-r--r--cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c246
-rw-r--r--cpu/ixp/npe/IxOsalBufferMgt.c800
-rw-r--r--cpu/ixp/npe/IxOsalIoMem.c332
-rw-r--r--cpu/ixp/npe/IxOsalOsCacheMMU.c67
-rw-r--r--cpu/ixp/npe/IxOsalOsMsgQ.c79
-rw-r--r--cpu/ixp/npe/IxOsalOsSemaphore.c233
-rw-r--r--cpu/ixp/npe/IxOsalOsServices.c251
-rw-r--r--cpu/ixp/npe/IxOsalOsThread.c98
-rw-r--r--cpu/ixp/npe/IxQMgrAqmIf.c963
-rw-r--r--cpu/ixp/npe/IxQMgrDispatcher.c1347
-rw-r--r--cpu/ixp/npe/IxQMgrInit.c233
-rw-r--r--cpu/ixp/npe/IxQMgrQAccess.c796
-rw-r--r--cpu/ixp/npe/IxQMgrQCfg.c543
-rw-r--r--cpu/ixp/npe/Makefile100
-rw-r--r--cpu/ixp/npe/include/IxAssert.h71
-rw-r--r--cpu/ixp/npe/include/IxAtmSch.h504
-rw-r--r--cpu/ixp/npe/include/IxAtmTypes.h409
-rw-r--r--cpu/ixp/npe/include/IxAtmdAcc.h1194
-rw-r--r--cpu/ixp/npe/include/IxAtmdAccCtrl.h1958
-rw-r--r--cpu/ixp/npe/include/IxAtmm.h795
-rw-r--r--cpu/ixp/npe/include/IxDmaAcc.h260
-rw-r--r--cpu/ixp/npe/include/IxEthAcc.h2512
-rw-r--r--cpu/ixp/npe/include/IxEthAccDataPlane_p.h245
-rw-r--r--cpu/ixp/npe/include/IxEthAccMac_p.h248
-rw-r--r--cpu/ixp/npe/include/IxEthAccMii_p.h97
-rw-r--r--cpu/ixp/npe/include/IxEthAccQueueAssign_p.h137
-rw-r--r--cpu/ixp/npe/include/IxEthAcc_p.h325
-rw-r--r--cpu/ixp/npe/include/IxEthDB.h2373
-rw-r--r--cpu/ixp/npe/include/IxEthDBLocks_p.h122
-rw-r--r--cpu/ixp/npe/include/IxEthDBLog_p.h227
-rw-r--r--cpu/ixp/npe/include/IxEthDBMessages_p.h258
-rw-r--r--cpu/ixp/npe/include/IxEthDBPortDefs.h163
-rw-r--r--cpu/ixp/npe/include/IxEthDBQoS.h154
-rw-r--r--cpu/ixp/npe/include/IxEthDB_p.h712
-rw-r--r--cpu/ixp/npe/include/IxEthMii.h270
-rw-r--r--cpu/ixp/npe/include/IxEthMii_p.h185
-rw-r--r--cpu/ixp/npe/include/IxEthNpe.h695
-rw-r--r--cpu/ixp/npe/include/IxFeatureCtrl.h742
-rw-r--r--cpu/ixp/npe/include/IxHssAcc.h1316
-rw-r--r--cpu/ixp/npe/include/IxI2cDrv.h867
-rw-r--r--cpu/ixp/npe/include/IxNpeA.h782
-rw-r--r--cpu/ixp/npe/include/IxNpeDl.h980
-rw-r--r--cpu/ixp/npe/include/IxNpeDlImageMgr_p.h363
-rw-r--r--cpu/ixp/npe/include/IxNpeDlMacros_p.h414
-rw-r--r--cpu/ixp/npe/include/IxNpeDlNpeMgrEcRegisters_p.h893
-rw-r--r--cpu/ixp/npe/include/IxNpeDlNpeMgrUtils_p.h405
-rw-r--r--cpu/ixp/npe/include/IxNpeDlNpeMgr_p.h260
-rw-r--r--cpu/ixp/npe/include/IxNpeMh.h497
-rw-r--r--cpu/ixp/npe/include/IxNpeMhConfig_p.h555
-rw-r--r--cpu/ixp/npe/include/IxNpeMhMacros_p.h296
-rw-r--r--cpu/ixp/npe/include/IxNpeMhReceive_p.h139
-rw-r--r--cpu/ixp/npe/include/IxNpeMhSend_p.h163
-rw-r--r--cpu/ixp/npe/include/IxNpeMhSolicitedCbMgr_p.h171
-rw-r--r--cpu/ixp/npe/include/IxNpeMhUnsolicitedCbMgr_p.h169
-rw-r--r--cpu/ixp/npe/include/IxNpeMicrocode.h296
-rw-r--r--cpu/ixp/npe/include/IxOsBufLib.h55
-rw-r--r--cpu/ixp/npe/include/IxOsBuffMgt.h52
-rw-r--r--cpu/ixp/npe/include/IxOsBuffPoolMgt.h74
-rw-r--r--cpu/ixp/npe/include/IxOsCacheMMU.h60
-rw-r--r--cpu/ixp/npe/include/IxOsPrintf.h102
-rw-r--r--cpu/ixp/npe/include/IxOsServices.h55
-rw-r--r--cpu/ixp/npe/include/IxOsServicesComponents.h134
-rw-r--r--cpu/ixp/npe/include/IxOsServicesEndianess.h52
-rw-r--r--cpu/ixp/npe/include/IxOsServicesMemAccess.h52
-rw-r--r--cpu/ixp/npe/include/IxOsServicesMemMap.h54
-rw-r--r--cpu/ixp/npe/include/IxOsal.h1517
-rw-r--r--cpu/ixp/npe/include/IxOsalAssert.h81
-rw-r--r--cpu/ixp/npe/include/IxOsalBackward.h65
-rw-r--r--cpu/ixp/npe/include/IxOsalBackwardAssert.h54
-rw-r--r--cpu/ixp/npe/include/IxOsalBackwardBufferMgt.h159
-rw-r--r--cpu/ixp/npe/include/IxOsalBackwardCacheMMU.h69
-rw-r--r--cpu/ixp/npe/include/IxOsalBackwardMemMap.h141
-rw-r--r--cpu/ixp/npe/include/IxOsalBackwardOsServices.h125
-rw-r--r--cpu/ixp/npe/include/IxOsalBackwardOssl.h272
-rw-r--r--cpu/ixp/npe/include/IxOsalBufferMgt.h621
-rw-r--r--cpu/ixp/npe/include/IxOsalBufferMgtDefault.h88
-rw-r--r--cpu/ixp/npe/include/IxOsalConfig.h76
-rw-r--r--cpu/ixp/npe/include/IxOsalEndianess.h134
-rw-r--r--cpu/ixp/npe/include/IxOsalIoMem.h322
-rw-r--r--cpu/ixp/npe/include/IxOsalMemAccess.h494
-rw-r--r--cpu/ixp/npe/include/IxOsalOem.h97
-rw-r--r--cpu/ixp/npe/include/IxOsalOs.h30
-rw-r--r--cpu/ixp/npe/include/IxOsalOsAssert.h10
-rw-r--r--cpu/ixp/npe/include/IxOsalOsBufferMgt.h96
-rw-r--r--cpu/ixp/npe/include/IxOsalOsIxp400.h316
-rw-r--r--cpu/ixp/npe/include/IxOsalOsIxp400CustomizedMapping.h404
-rw-r--r--cpu/ixp/npe/include/IxOsalOsTypes.h60
-rw-r--r--cpu/ixp/npe/include/IxOsalOsUtilitySymbols.h4
-rw-r--r--cpu/ixp/npe/include/IxOsalTypes.h401
-rw-r--r--cpu/ixp/npe/include/IxOsalUtilitySymbols.h51
-rw-r--r--cpu/ixp/npe/include/IxParityENAcc.h785
-rw-r--r--cpu/ixp/npe/include/IxPerfProfAcc.h1358
-rw-r--r--cpu/ixp/npe/include/IxQMgr.h2210
-rw-r--r--cpu/ixp/npe/include/IxQMgrAqmIf_p.h927
-rw-r--r--cpu/ixp/npe/include/IxQMgrDefines_p.h55
-rw-r--r--cpu/ixp/npe/include/IxQMgrDispatcher_p.h106
-rw-r--r--cpu/ixp/npe/include/IxQMgrLog_p.h124
-rw-r--r--cpu/ixp/npe/include/IxQMgrQAccess_p.h96
-rw-r--r--cpu/ixp/npe/include/IxQMgrQCfg_p.h122
-rw-r--r--cpu/ixp/npe/include/IxQueueAssignments.h516
-rw-r--r--cpu/ixp/npe/include/IxSspAcc.h1271
-rw-r--r--cpu/ixp/npe/include/IxTimeSyncAcc.h783
-rw-r--r--cpu/ixp/npe/include/IxTimerCtrl.h263
-rw-r--r--cpu/ixp/npe/include/IxTypes.h86
-rw-r--r--cpu/ixp/npe/include/IxUART.h458
-rw-r--r--cpu/ixp/npe/include/IxVersionId.h155
-rw-r--r--cpu/ixp/npe/include/ix_error.h66
-rw-r--r--cpu/ixp/npe/include/ix_macros.h266
-rw-r--r--cpu/ixp/npe/include/ix_os_type.h65
-rw-r--r--cpu/ixp/npe/include/ix_ossl.h160
-rw-r--r--cpu/ixp/npe/include/ix_symbols.h106
-rw-r--r--cpu/ixp/npe/include/ix_types.h208
-rw-r--r--cpu/ixp/npe/include/npe.h90
-rw-r--r--cpu/ixp/npe/include/os_datatypes.h82
-rw-r--r--cpu/ixp/npe/miiphy.c118
-rw-r--r--cpu/ixp/npe/npe.c694
-rw-r--r--cpu/ixp/start.S28
-rw-r--r--cpu/ixp/timer.c6
-rw-r--r--cpu/lh7a40x/Makefile18
-rw-r--r--cpu/mcf52x2/Makefile18
-rw-r--r--cpu/mcf52x2/cpu.c73
-rw-r--r--cpu/mcf52x2/cpu_init.c258
-rw-r--r--cpu/mcf52x2/fec.c50
-rw-r--r--cpu/mcf52x2/interrupts.c7
-rw-r--r--cpu/mcf52x2/serial.c94
-rw-r--r--cpu/mcf52x2/start.S135
-rw-r--r--cpu/microblaze/Makefile18
-rw-r--r--cpu/mips/Makefile22
-rw-r--r--cpu/mips/config.mk2
-rw-r--r--cpu/mpc5xx/Makefile21
-rw-r--r--cpu/mpc5xxx/Makefile22
-rw-r--r--cpu/mpc5xxx/interrupts.c292
-rw-r--r--cpu/mpc5xxx/serial.c237
-rw-r--r--cpu/mpc8220/Makefile22
-rw-r--r--cpu/mpc8220/pci.c2
-rw-r--r--cpu/mpc824x/Makefile31
-rw-r--r--cpu/mpc824x/drivers/dma/Makefile83
-rw-r--r--cpu/mpc824x/drivers/dma/Makefile_pc89
-rw-r--r--cpu/mpc824x/drivers/dma/README100
-rw-r--r--cpu/mpc824x/drivers/dma/dma.h326
-rw-r--r--cpu/mpc824x/drivers/dma/dma1.c801
-rw-r--r--cpu/mpc824x/drivers/dma/dma2.S42
-rw-r--r--cpu/mpc824x/drivers/dma/dma_export.h100
-rw-r--r--cpu/mpc824x/drivers/dma_export.h100
-rw-r--r--cpu/mpc824x/drivers/i2o.h344
-rw-r--r--cpu/mpc824x/drivers/i2o/Makefile84
-rw-r--r--cpu/mpc824x/drivers/i2o/Makefile_pc90
-rw-r--r--cpu/mpc824x/drivers/i2o/i2o.h345
-rw-r--r--cpu/mpc824x/drivers/i2o/i2o1.c890
-rw-r--r--cpu/mpc824x/drivers/i2o/i2o2.S47
-rw-r--r--cpu/mpc8260/Makefile20
-rw-r--r--cpu/mpc8260/pci.c4
-rw-r--r--cpu/mpc83xx/Makefile30
-rw-r--r--cpu/mpc83xx/i2c.c2
-rw-r--r--cpu/mpc85xx/Makefile18
-rw-r--r--cpu/mpc85xx/cpu.c50
-rw-r--r--cpu/mpc85xx/cpu_init.c1
-rw-r--r--cpu/mpc85xx/pci.c185
-rw-r--r--cpu/mpc86xx/Makefile17
-rw-r--r--cpu/mpc8xx/Makefile22
-rw-r--r--cpu/mpc8xx/cpu_init.c1
-rw-r--r--cpu/mpc8xx/fec.c10
-rw-r--r--cpu/mpc8xx/serial.c7
-rw-r--r--cpu/mpc8xx/speed.c9
-rw-r--r--cpu/nios/Makefile24
-rw-r--r--cpu/nios2/Makefile24
-rw-r--r--cpu/nios2/epcs.c38
-rw-r--r--cpu/nios2/exceptions.S3
-rw-r--r--cpu/nios2/interrupts.c18
-rw-r--r--cpu/nios2/serial.c26
-rw-r--r--cpu/nios2/sysid.c11
-rw-r--r--cpu/ppc4xx/405gp_pci.c30
-rw-r--r--cpu/ppc4xx/440spe_pcie.c962
-rw-r--r--cpu/ppc4xx/440spe_pcie.h171
-rw-r--r--cpu/ppc4xx/4xx_enet.c222
-rw-r--r--cpu/ppc4xx/Makefile23
-rw-r--r--cpu/ppc4xx/cpu.c134
-rw-r--r--cpu/ppc4xx/cpu_init.c120
-rw-r--r--cpu/ppc4xx/interrupts.c158
-rw-r--r--cpu/ppc4xx/miiphy.c65
-rw-r--r--cpu/ppc4xx/ndfc.c175
-rw-r--r--cpu/ppc4xx/sdram.c2
-rw-r--r--cpu/ppc4xx/serial.c240
-rw-r--r--cpu/ppc4xx/spd_sdram.c6
-rw-r--r--cpu/ppc4xx/speed.c257
-rw-r--r--cpu/ppc4xx/start.S213
-rw-r--r--cpu/ppc4xx/usb_ohci.c8
-rw-r--r--cpu/ppc4xx/usbdev.c20
-rw-r--r--cpu/ppc4xx/vecnum.h130
-rw-r--r--cpu/pxa/Makefile18
-rw-r--r--cpu/s3c44b0/Makefile18
-rw-r--r--cpu/sa1100/Makefile18
253 files changed, 74445 insertions, 4212 deletions
diff --git a/cpu/74xx_7xx/Makefile b/cpu/74xx_7xx/Makefile
index 0e10d3a..e82fffc 100644
--- a/cpu/74xx_7xx/Makefile
+++ b/cpu/74xx_7xx/Makefile
@@ -1,4 +1,7 @@
#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
# (C) Copyright 2001
# Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
#
@@ -23,22 +26,26 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-ASOBJS = cache.o kgdb.o io.o
-OBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o
+SOBJS = cache.o kgdb.o io.o
+COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o
+
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-all: .depend $(START) $(ASOBJS) $(LIB)
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(ASOBJS) $(OBJS)
+ $(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(ASOBJS:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/74xx_7xx/cpu.c b/cpu/74xx_7xx/cpu.c
index 706c880..ca45e17 100644
--- a/cpu/74xx_7xx/cpu.c
+++ b/cpu/74xx_7xx/cpu.c
@@ -215,7 +215,8 @@ soft_restart(unsigned long addr)
#if !defined(CONFIG_PCIPPC2) && \
!defined(CONFIG_BAB7xx) && \
- !defined(CONFIG_ELPPC)
+ !defined(CONFIG_ELPPC) && \
+ !defined(CONFIG_PPMC7XX)
/* no generic way to do board reset. simply call soft_reset. */
void
do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
diff --git a/cpu/74xx_7xx/start.S b/cpu/74xx_7xx/start.S
index ff1cce5..1fc0fe6 100644
--- a/cpu/74xx_7xx/start.S
+++ b/cpu/74xx_7xx/start.S
@@ -756,7 +756,8 @@ in_ram:
#if defined(CONFIG_AMIGAONEG3SE) || \
defined(CONFIG_DB64360) || \
defined(CONFIG_DB64460) || \
- defined(CONFIG_CPCI750)
+ defined(CONFIG_CPCI750) || \
+ defined(CONFIG_PPMC7XX)
mr r4, r9 /* Use RAM copy of the global data */
#endif
bl after_reloc
diff --git a/cpu/arm1136/Makefile b/cpu/arm1136/Makefile
index 203278e..5d2c7eb 100644
--- a/cpu/arm1136/Makefile
+++ b/cpu/arm1136/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2003
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = interrupts.o cpu.o
+COBJS = interrupts.o cpu.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm720t/Makefile b/cpu/arm720t/Makefile
index f273d92..539a48c 100644
--- a/cpu/arm720t/Makefile
+++ b/cpu/arm720t/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = serial.o serial_netarm.o interrupts.o cpu.o
+COBJS = serial.o serial_netarm.o interrupts.o cpu.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm920t/Makefile b/cpu/arm920t/Makefile
index 8f256e9..199fe0c 100644
--- a/cpu/arm920t/Makefile
+++ b/cpu/arm920t/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000, 2001, 2002
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = cpu.o interrupts.o
+COBJS = cpu.o interrupts.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm920t/at91rm9200/Makefile b/cpu/arm920t/at91rm9200/Makefile
index aec9cb6..26b0b94 100644
--- a/cpu/arm920t/at91rm9200/Makefile
+++ b/cpu/arm920t/at91rm9200/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2005
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,22 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(SOC).a
+LIB = $(obj)lib$(SOC).a
-OBJS = bcm5221.o dm9161.o ether.o i2c.o interrupts.o \
+COBJS = bcm5221.o dm9161.o ether.o i2c.o interrupts.o \
lxt972.o serial.o usb_ohci.o
SOBJS = lowlevel_init.o
-all: .depend $(LIB)
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
-$(LIB): $(OBJS) $(SOBJS)
- $(AR) crv $@ $(OBJS) $(SOBJS)
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm920t/imx/Makefile b/cpu/arm920t/imx/Makefile
index 8865f82..e238fc0 100644
--- a/cpu/arm920t/imx/Makefile
+++ b/cpu/arm920t/imx/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000, 2001, 2002
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,20 +23,23 @@
include $(TOPDIR)/config.mk
-LIB = lib$(SOC).a
+LIB = $(obj)lib$(SOC).a
-OBJS = generic.o interrupts.o serial.o speed.o
+COBJS = generic.o interrupts.o serial.o speed.o
-all: .depend $(LIB)
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+all: $(obj).depend $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm920t/ks8695/Makefile b/cpu/arm920t/ks8695/Makefile
index ac49060..6342435 100644
--- a/cpu/arm920t/ks8695/Makefile
+++ b/cpu/arm920t/ks8695/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2005
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,24 @@
include $(TOPDIR)/config.mk
-LIB = lib$(SOC).a
+LIB = $(obj)lib$(SOC).a
-OBJS = interrupts.o serial.o
+COBJS = interrupts.o serial.o
SOBJS = lowlevel_init.o
-all: .depend $(LIB)
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
-$(LIB): $(OBJS) $(SOBJS)
- $(AR) crv $@ $(OBJS) $(SOBJS)
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm920t/s3c24x0/Makefile b/cpu/arm920t/s3c24x0/Makefile
index af9e4ef..557298e 100644
--- a/cpu/arm920t/s3c24x0/Makefile
+++ b/cpu/arm920t/s3c24x0/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000, 2001, 2002
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,24 @@
include $(TOPDIR)/config.mk
-LIB = lib$(SOC).a
+LIB = $(obj)lib$(SOC).a
-OBJS = i2c.o interrupts.o serial.o speed.o \
+COBJS = i2c.o interrupts.o serial.o speed.o \
usb_ohci.o
-all: .depend $(LIB)
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+all: $(obj).depend $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm920t/s3c24x0/i2c.c b/cpu/arm920t/s3c24x0/i2c.c
index ef56cd1..374b683 100644
--- a/cpu/arm920t/s3c24x0/i2c.c
+++ b/cpu/arm920t/s3c24x0/i2c.c
@@ -153,7 +153,7 @@ void i2c_init (int speed, int slaveadd)
#endif
#ifdef CONFIG_S3C2400
/* set I2CSDA and I2CSCL (PG5, PG6) to GPIO */
- gpio->PGCON = (gpio->PGCON & ~0x00003c00) | 0x00000c00;
+ gpio->PGCON = (gpio->PGCON & ~0x00003c00) | 0x00001000;
#endif
/* toggle I2CSCL until bus idle */
diff --git a/cpu/arm920t/s3c24x0/interrupts.c b/cpu/arm920t/s3c24x0/interrupts.c
index 3ec9b54..1b36412 100644
--- a/cpu/arm920t/s3c24x0/interrupts.c
+++ b/cpu/arm920t/s3c24x0/interrupts.c
@@ -176,7 +176,9 @@ ulong get_tbclk (void)
#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
tbclk = timer_load_val * 100;
-#elif defined(CONFIG_SMDK2410) || defined(CONFIG_VCMA9)
+#elif defined(CONFIG_SBC2410X) || \
+ defined(CONFIG_SMDK2410) || \
+ defined(CONFIG_VCMA9)
tbclk = CFG_HZ;
#else
# error "tbclk not configured"
diff --git a/cpu/arm925t/Makefile b/cpu/arm925t/Makefile
index a1db818..086b1a3 100644
--- a/cpu/arm925t/Makefile
+++ b/cpu/arm925t/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2003
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = interrupts.o cpu.o omap925.o
+COBJS = interrupts.o cpu.o omap925.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm926ejs/Makefile b/cpu/arm926ejs/Makefile
index 203278e..a410c2f 100644
--- a/cpu/arm926ejs/Makefile
+++ b/cpu/arm926ejs/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2003
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = interrupts.o cpu.o
+COBJS = interrupts.o cpu.o cpuinfo.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm926ejs/cpuinfo.c b/cpu/arm926ejs/cpuinfo.c
new file mode 100644
index 0000000..8c98631
--- /dev/null
+++ b/cpu/arm926ejs/cpuinfo.c
@@ -0,0 +1,244 @@
+/*
+ * OMAP1 CPU identification code
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <arm926ejs.h>
+
+#if defined(CONFIG_DISPLAY_CPUINFO) && defined(CONFIG_OMAP)
+
+#define omap_readw(x) *(volatile unsigned short *)(x)
+#define omap_readl(x) *(volatile unsigned long *)(x)
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+#define OMAP_DIE_ID_0 0xfffe1800
+#define OMAP_DIE_ID_1 0xfffe1804
+#define OMAP_PRODUCTION_ID_0 0xfffe2000
+#define OMAP_PRODUCTION_ID_1 0xfffe2004
+#define OMAP32_ID_0 0xfffed400
+#define OMAP32_ID_1 0xfffed404
+
+struct omap_id {
+ u16 jtag_id; /* Used to determine OMAP type */
+ u8 die_rev; /* Processor revision */
+ u32 omap_id; /* OMAP revision */
+ u32 type; /* Cpu id bits [31:08], cpu class bits [07:00] */
+};
+
+/* Register values to detect the OMAP version */
+static struct omap_id omap_ids[] = {
+ { .jtag_id = 0xb574, .die_rev = 0x2, .omap_id = 0x03310315, .type = 0x03100000},
+ { .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100},
+ { .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300},
+ { .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000},
+ { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x16100000},
+ { .jtag_id = 0xb576, .die_rev = 0x2, .omap_id = 0x03320100, .type = 0x16110000},
+ { .jtag_id = 0xb576, .die_rev = 0x3, .omap_id = 0x03320100, .type = 0x16100c00},
+ { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320200, .type = 0x16100d00},
+ { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00},
+ { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00},
+ { .jtag_id = 0xb576, .die_rev = 0x1, .omap_id = 0x03320100, .type = 0x16110000},
+ { .jtag_id = 0xb58c, .die_rev = 0x2, .omap_id = 0x03320200, .type = 0x16110b00},
+ { .jtag_id = 0xb58c, .die_rev = 0x3, .omap_id = 0x03320200, .type = 0x16110c00},
+ { .jtag_id = 0xb65f, .die_rev = 0x0, .omap_id = 0x03320400, .type = 0x16212300},
+ { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320400, .type = 0x16212300},
+ { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320500, .type = 0x16212300},
+ { .jtag_id = 0xb5f7, .die_rev = 0x0, .omap_id = 0x03330000, .type = 0x17100000},
+ { .jtag_id = 0xb5f7, .die_rev = 0x1, .omap_id = 0x03330100, .type = 0x17100000},
+ { .jtag_id = 0xb5f7, .die_rev = 0x2, .omap_id = 0x03330100, .type = 0x17100000},
+};
+
+/*
+ * Get OMAP type from PROD_ID.
+ * 1710 has the PROD_ID in bits 15:00, not in 16:01 as documented in TRM.
+ * 1510 PROD_ID is empty, and 1610 PROD_ID does not make sense.
+ * Undocumented register in TEST BLOCK is used as fallback; This seems to
+ * work on 1510, 1610 & 1710. The official way hopefully will work in future
+ * processors.
+ */
+static u16 omap_get_jtag_id(void)
+{
+ u32 prod_id, omap_id;
+
+ prod_id = omap_readl(OMAP_PRODUCTION_ID_1);
+ omap_id = omap_readl(OMAP32_ID_1);
+
+ /* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730 */
+ if (((prod_id >> 20) == 0) || (prod_id == omap_id))
+ prod_id = 0;
+ else
+ prod_id &= 0xffff;
+
+ if (prod_id)
+ return prod_id;
+
+ /* Use OMAP32_ID_1 as fallback */
+ prod_id = ((omap_id >> 12) & 0xffff);
+
+ return prod_id;
+}
+
+/*
+ * Get OMAP revision from DIE_REV.
+ * Early 1710 processors may have broken OMAP_DIE_ID, it contains PROD_ID.
+ * Undocumented register in the TEST BLOCK is used as fallback.
+ * REVISIT: This does not seem to work on 1510
+ */
+static u8 omap_get_die_rev(void)
+{
+ u32 die_rev;
+
+ die_rev = omap_readl(OMAP_DIE_ID_1);
+
+ /* Check for broken OMAP_DIE_ID on early 1710 */
+ if (((die_rev >> 12) & 0xffff) == omap_get_jtag_id())
+ die_rev = 0;
+
+ die_rev = (die_rev >> 17) & 0xf;
+ if (die_rev)
+ return die_rev;
+
+ die_rev = (omap_readl(OMAP32_ID_1) >> 28) & 0xf;
+
+ return die_rev;
+}
+
+static unsigned long dpll1(void)
+{
+ unsigned short pll_ctl_val = omap_readw(DPLL_CTL_REG);
+ unsigned long rate;
+
+ rate = CONFIG_SYS_CLK_FREQ; /* Base xtal rate */
+ if (pll_ctl_val & 0x10) {
+ /* PLL enabled, apply multiplier and divisor */
+ if (pll_ctl_val & 0xf80)
+ rate *= (pll_ctl_val & 0xf80) >> 7;
+ rate /= ((pll_ctl_val & 0x60) >> 5) + 1;
+ } else {
+ /* PLL disabled, apply bypass divisor */
+ switch (pll_ctl_val & 0xc) {
+ case 0:
+ break;
+ case 0x4:
+ rate /= 2;
+ break;
+ default:
+ rate /= 4;
+ break;
+ }
+ }
+
+ return rate;
+}
+
+static unsigned long armcore(void)
+{
+ unsigned short arm_ckctl = omap_readw(ARM_CKCTL);
+
+ return (dpll1() >> ((arm_ckctl & 0x0030) >> 4));
+}
+
+int print_cpuinfo (void)
+{
+ int i;
+ u16 jtag_id;
+ u8 die_rev;
+ u32 omap_id;
+ u8 cpu_type;
+ u32 system_serial_high;
+ u32 system_serial_low;
+ u32 system_rev = 0;
+
+ jtag_id = omap_get_jtag_id();
+ die_rev = omap_get_die_rev();
+ omap_id = omap_readl(OMAP32_ID_0);
+
+#ifdef DEBUG
+ printf("OMAP_DIE_ID_0: 0x%08x\n", omap_readl(OMAP_DIE_ID_0));
+ printf("OMAP_DIE_ID_1: 0x%08x DIE_REV: %i\n",
+ omap_readl(OMAP_DIE_ID_1),
+ (omap_readl(OMAP_DIE_ID_1) >> 17) & 0xf);
+ printf("OMAP_PRODUCTION_ID_0: 0x%08x\n", omap_readl(OMAP_PRODUCTION_ID_0));
+ printf("OMAP_PRODUCTION_ID_1: 0x%08x JTAG_ID: 0x%04x\n",
+ omap_readl(OMAP_PRODUCTION_ID_1),
+ omap_readl(OMAP_PRODUCTION_ID_1) & 0xffff);
+ printf("OMAP32_ID_0: 0x%08x\n", omap_readl(OMAP32_ID_0));
+ printf("OMAP32_ID_1: 0x%08x\n", omap_readl(OMAP32_ID_1));
+ printf("JTAG_ID: 0x%04x DIE_REV: %i\n", jtag_id, die_rev);
+#endif
+
+ system_serial_high = omap_readl(OMAP_DIE_ID_0);
+ system_serial_low = omap_readl(OMAP_DIE_ID_1);
+
+ /* First check only the major version in a safe way */
+ for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
+ if (jtag_id == (omap_ids[i].jtag_id)) {
+ system_rev = omap_ids[i].type;
+ break;
+ }
+ }
+
+ /* Check if we can find the die revision */
+ for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
+ if (jtag_id == omap_ids[i].jtag_id && die_rev == omap_ids[i].die_rev) {
+ system_rev = omap_ids[i].type;
+ break;
+ }
+ }
+
+ /* Finally check also the omap_id */
+ for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
+ if (jtag_id == omap_ids[i].jtag_id
+ && die_rev == omap_ids[i].die_rev
+ && omap_id == omap_ids[i].omap_id) {
+ system_rev = omap_ids[i].type;
+ break;
+ }
+ }
+
+ /* Add the cpu class info (7xx, 15xx, 16xx, 24xx) */
+ cpu_type = system_rev >> 24;
+
+ switch (cpu_type) {
+ case 0x07:
+ system_rev |= 0x07;
+ break;
+ case 0x03:
+ case 0x15:
+ system_rev |= 0x15;
+ break;
+ case 0x16:
+ case 0x17:
+ system_rev |= 0x16;
+ break;
+ case 0x24:
+ system_rev |= 0x24;
+ break;
+ default:
+ printf("Unknown OMAP cpu type: 0x%02x\n", cpu_type);
+ }
+
+ printf("CPU: OMAP%04x", system_rev >> 16);
+ if ((system_rev >> 8) & 0xff)
+ printf("%x", (system_rev >> 8) & 0xff);
+#ifdef DEBUG
+ printf(" revision %i handled as %02xxx id: %08x%08x",
+ die_rev, system_rev & 0xff, system_serial_low, system_serial_high);
+#endif
+ printf(" at %ld.%01ld MHz (DPLL1=%ld.%01ld MHz)\n",
+ armcore() / 1000000, (armcore() / 100000) % 10,
+ dpll1() / 1000000, (dpll1() / 100000) % 10);
+
+ return 0;
+}
+
+#endif /* #if defined(CONFIG_DISPLAY_CPUINFO) && defined(CONFIG_OMAP) */
diff --git a/cpu/arm926ejs/omap/Makefile b/cpu/arm926ejs/omap/Makefile
index f9d3378..7eca2f0 100644
--- a/cpu/arm926ejs/omap/Makefile
+++ b/cpu/arm926ejs/omap/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2005
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(SOC).a
+LIB = $(obj)lib$(SOC).a
-OBJS = timer.o
+COBJS = timer.o
SOBJS = reset.o
-all: .depend $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
-$(LIB): $(OBJS) $(SOBJS)
- $(AR) crv $@ $(OBJS) $(SOBJS)
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm926ejs/versatile/Makefile b/cpu/arm926ejs/versatile/Makefile
index f9d3378..7eca2f0 100644
--- a/cpu/arm926ejs/versatile/Makefile
+++ b/cpu/arm926ejs/versatile/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2005
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(SOC).a
+LIB = $(obj)lib$(SOC).a
-OBJS = timer.o
+COBJS = timer.o
SOBJS = reset.o
-all: .depend $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
-$(LIB): $(OBJS) $(SOBJS)
- $(AR) crv $@ $(OBJS) $(SOBJS)
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm946es/Makefile b/cpu/arm946es/Makefile
index 203278e..5d2c7eb 100644
--- a/cpu/arm946es/Makefile
+++ b/cpu/arm946es/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2003
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = interrupts.o cpu.o
+COBJS = interrupts.o cpu.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm_intcm/Makefile b/cpu/arm_intcm/Makefile
index 203278e..5d2c7eb 100644
--- a/cpu/arm_intcm/Makefile
+++ b/cpu/arm_intcm/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2003
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = interrupts.o cpu.o
+COBJS = interrupts.o cpu.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/bf533/Makefile b/cpu/bf533/Makefile
index c63a8f6..a5c48dc 100644
--- a/cpu/bf533/Makefile
+++ b/cpu/bf533/Makefile
@@ -2,7 +2,7 @@
#
# Copyright (c) 2005 blackfin.uclinux.org
#
-# (C) Copyright 2000-2004
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -26,21 +26,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o start1.o interrupt.o cache.o cplbhdlr.o cplbmgr.o flush.o
-OBJS = cpu.o traps.o ints.o serial.o interrupts.o
+COBJS = cpu.o traps.o ints.o serial.o interrupts.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/i386/Makefile b/cpu/i386/Makefile
index c44412a..cd46dea 100644
--- a/cpu/i386/Makefile
+++ b/cpu/i386/Makefile
@@ -1,4 +1,7 @@
#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
# (C) Copyright 2002
# Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
#
@@ -23,22 +26,26 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o start16.o reset.o
COBJS = serial.o interrupts.o cpu.o timer.o sc520.o
-AOBJS = sc520_asm.o
+SOBJS = sc520_asm.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-$(LIB): $(COBJS) $(AOBJS)
- $(AR) crv $@ $(COBJS) $(AOBJS)
+all: $(obj).depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(COBJS:.o=.c) $(AOBJS:.o=.S)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(COBJS:.o=.c) $(AOBJS:.o=.S) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/i386/sc520.c b/cpu/i386/sc520.c
index c83f0bb..d0a7341 100644
--- a/cpu/i386/sc520.c
+++ b/cpu/i386/sc520.c
@@ -31,7 +31,9 @@
#include <common.h>
#include <config.h>
#include <pci.h>
+#ifdef CONFIG_SC520_SSI
#include <ssi.h>
+#endif
#include <asm/io.h>
#include <asm/pci.h>
#include <asm/ic/sc520.h>
@@ -143,7 +145,15 @@ unsigned long init_sc520_dram(void)
u32 dram_present=0;
u32 dram_ctrl;
-
+#ifdef CFG_SDRAM_DRCTMCTL
+ /* these memory control registers are set up in the assember part,
+ * in sc520_asm.S, during 'mem_init'. If we muck with them here,
+ * after we are running a stack in RAM, we have troubles. Besides,
+ * these refresh and delay values are better ? simply specified
+ * outright in the include/configs/{cfg} file since the HW designer
+ * simply dictates it.
+ */
+#else
int val;
int cas_precharge_delay = CFG_SDRAM_PRECHARGE_DELAY;
@@ -162,6 +172,7 @@ unsigned long init_sc520_dram(void)
} else {
val = 3; /* 62.4us */
}
+
write_mmcr_byte(SC520_DRCCTL, (read_mmcr_byte(SC520_DRCCTL) & 0xcf) | (val<<4));
val = read_mmcr_byte(SC520_DRCTMCTL);
@@ -181,13 +192,12 @@ unsigned long init_sc520_dram(void)
val |= 1;
}
write_mmcr_byte(SC520_DRCTMCTL, val);
-
+#endif
/* We read-back the configuration of the dram
* controller that the assembly code wrote */
dram_ctrl = read_mmcr_long(SC520_DRCBENDADR);
-
bd->bi_dram[0].start = 0;
if (dram_ctrl & 0x80) {
/* bank 0 enabled */
@@ -274,7 +284,7 @@ int pci_sc520_set_irq(int pci_pin, int irq)
{
int i;
-# if 0
+# if 1
printf("set_irq(): map INT%c to IRQ%d\n", pci_pin + 'A', irq);
#endif
if (irq < 0 || irq > 15) {
diff --git a/cpu/i386/sc520_asm.S b/cpu/i386/sc520_asm.S
index 80464fa..8fc713d 100644
--- a/cpu/i386/sc520_asm.S
+++ b/cpu/i386/sc520_asm.S
@@ -113,6 +113,7 @@
.equ DRCCFG, 0x0fffef014 /* DRAM bank configuration register */
.equ DRCBENDADR, 0x0fffef018 /* DRAM bank ending address register */
.equ ECCCTL, 0x0fffef020 /* DRAM ECC control register */
+.equ ECCINT, 0x0fffefd18 /* DRAM ECC nmi-INT mapping */
.equ DBCTL, 0x0fffef040 /* DRAM buffer control register */
.equ CACHELINESZ, 0x00000010 /* size of our cache line (read buffer) */
@@ -459,6 +460,12 @@ emptybank:
incl %edi
loop cleanuplp
+#if defined CFG_SDRAM_DRCTMCTL
+ /* just have your hardware desinger _GIVE_ you what you need here! */
+ movl $DRCTMCTL, %edi
+ movb $CFG_SDRAM_DRCTMCTL,%al
+ movb (%edi), %al
+#else
#if defined(CFG_SDRAM_CAS_LATENCY_2T) || defined(CFG_SDRAM_CAS_LATENCY_3T)
/* set the CAS latency now since it is hard to do
* when we run from the RAM */
@@ -472,6 +479,7 @@ emptybank:
#endif
movb %al, (%edi)
#endif
+#endif
movl $DRCCTL, %edi /* DRAM Control register */
movb $0x3,%al /* Load mode register cmd */
movb %al, (%edi)
@@ -528,9 +536,49 @@ bank0: movl (%edi), %eax
shll $22, %eax
movl %eax, %ebx
-done: movl %ebx, %eax
+done:
+ movl %ebx, %eax
+
+#if CFG_SDRAM_ECC_ENABLE
+ /* A nominal memory test: just a byte at each address line */
+ movl %eax, %ecx
+ shrl $0x1, %ecx
+ movl $0x1, %edi
+memtest0:
+ movb $0xa5, (%edi)
+ cmpb $0xa5, (%edi)
+ jne out
+ shrl $1, %ecx
+ andl %ecx,%ecx
+ jz set_ecc
+ shll $1, %edi
+ jmp memtest0
+
+set_ecc:
+ /* clear all ram with a memset */
+ movl %eax, %ecx
+ xorl %esi, %esi
+ xorl %edi, %edi
+ xorl %eax, %eax
+ shrl $2, %ecx
+ cld
+ rep stosl
+ /* enable read, write buffers */
+ movb $0x11, %al
+ movl $DBCTL, %edi
+ movb %al, (%edi)
+ /* enable NMI mapping for ECC */
+ movl $ECCINT, %edi
+ mov $0x10, %al
+ movb %al, (%edi)
+ /* Turn on ECC */
+ movl $ECCCTL, %edi
+ mov $0x05, %al
+ movb %al, (%edi)
+#endif
+out:
+ movl %ebx, %eax
jmp *%ebp
-
#endif /* CONFIG_SC520 */
diff --git a/cpu/ixp/Makefile b/cpu/ixp/Makefile
index ba2e589..2867270 100644
--- a/cpu/ixp/Makefile
+++ b/cpu/ixp/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000, 2002
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = serial.o interrupts.o cpu.o timer.o pci.o
+COBJS = serial.o interrupts.o cpu.o timer.o pci.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/ixp/config.mk b/cpu/ixp/config.mk
index eddda39..a71a20b 100644
--- a/cpu/ixp/config.mk
+++ b/cpu/ixp/config.mk
@@ -27,7 +27,7 @@ BIG_ENDIAN = y
PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
-msoft-float -mbig-endian
-PLATFORM_CPPFLAGS += -mbig-endian -march=armv4 -mtune=strongarm1100
+PLATFORM_CPPFLAGS += -mbig-endian -march=armv5te -mtune=strongarm1100
# =========================================================================
#
# Supply options according to compiler version
diff --git a/cpu/ixp/cpu.c b/cpu/ixp/cpu.c
index 2a2bd50..7f9f334 100644
--- a/cpu/ixp/cpu.c
+++ b/cpu/ixp/cpu.c
@@ -34,10 +34,47 @@
#include <command.h>
#include <asm/arch/ixp425.h>
+ulong loops_per_jiffy;
+
#ifdef CONFIG_USE_IRQ
DECLARE_GLOBAL_DATA_PTR;
#endif
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo (void)
+{
+ unsigned long id;
+ int speed = 0;
+
+ asm ("mrc p15, 0, %0, c0, c0, 0":"=r" (id));
+
+ puts("CPU: Intel IXP425 at ");
+ switch ((id & 0x000003f0) >> 4) {
+ case 0x1c:
+ loops_per_jiffy = 887467;
+ speed = 533;
+ break;
+
+ case 0x1d:
+ loops_per_jiffy = 666016;
+ speed = 400;
+ break;
+
+ case 0x1f:
+ loops_per_jiffy = 442901;
+ speed = 266;
+ break;
+ }
+
+ if (speed)
+ printf("%d MHz\n", speed);
+ else
+ puts("unknown revision\n");
+
+ return 0;
+}
+#endif /* CONFIG_DISPLAY_CPUINFO */
+
int cpu_init (void)
{
/*
@@ -48,7 +85,9 @@ int cpu_init (void)
FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
#endif
+#if (CONFIG_COMMANDS & CFG_CMD_PCI) || defined (CONFIG_PCI)
pci_init();
+#endif
return 0;
}
@@ -154,3 +193,25 @@ void pci_init(void)
return;
}
*/
+
+#ifdef CONFIG_BOOTCOUNT_LIMIT
+
+void bootcount_store (ulong a)
+{
+ volatile ulong *save_addr = (volatile ulong *)(CFG_BOOTCOUNT_ADDR);
+
+ save_addr[0] = a;
+ save_addr[1] = BOOTCOUNT_MAGIC;
+}
+
+ulong bootcount_load (void)
+{
+ volatile ulong *save_addr = (volatile ulong *)(CFG_BOOTCOUNT_ADDR);
+
+ if (save_addr[1] != BOOTCOUNT_MAGIC)
+ return 0;
+ else
+ return save_addr[0];
+}
+
+#endif /* CONFIG_BOOTCOUNT_LIMIT */
diff --git a/cpu/ixp/interrupts.c b/cpu/ixp/interrupts.c
index e260dea..2dd9561 100644
--- a/cpu/ixp/interrupts.c
+++ b/cpu/ixp/interrupts.c
@@ -1,5 +1,7 @@
-/* vi: set ts=8 sw=8 noet: */
/*
+ * (C) Copyright 2006
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
@@ -31,22 +33,85 @@
#include <asm/arch/ixp425.h>
#ifdef CONFIG_USE_IRQ
+/*
+ * When interrupts are enabled, use timer 2 for time/delay generation...
+ */
+
+#define FREQ 66666666
+#define CLOCK_TICK_RATE (((FREQ / CFG_HZ & ~IXP425_OST_RELOAD_MASK) + 1) * CFG_HZ)
+#define LATCH ((CLOCK_TICK_RATE + CFG_HZ/2) / CFG_HZ) /* For divider */
+
+struct _irq_handler {
+ void *m_data;
+ void (*m_func)( void *data);
+};
+
+static struct _irq_handler IRQ_HANDLER[N_IRQS];
+
+static volatile ulong timestamp;
+
/* enable IRQ/FIQ interrupts */
-void enable_interrupts (void)
+void enable_interrupts(void)
{
-#error: interrupts not implemented yet
+ unsigned long temp;
+ __asm__ __volatile__("mrs %0, cpsr\n"
+ "bic %0, %0, #0x80\n"
+ "msr cpsr_c, %0"
+ : "=r" (temp)
+ :
+ : "memory");
}
-
/*
* disable IRQ/FIQ interrupts
* returns true if interrupts had been enabled before we disabled them
*/
-int disable_interrupts (void)
+int disable_interrupts(void)
{
-#error: interrupts not implemented yet
+ unsigned long old,temp;
+ __asm__ __volatile__("mrs %0, cpsr\n"
+ "orr %1, %0, #0x80\n"
+ "msr cpsr_c, %1"
+ : "=r" (old), "=r" (temp)
+ :
+ : "memory");
+ return (old & 0x80) == 0;
}
-#else
+
+static void default_isr(void *data)
+{
+ printf("default_isr(): called for IRQ %d, Interrupt Status=%x PR=%x\n",
+ (int)data, *IXP425_ICIP, *IXP425_ICIH);
+}
+
+static int next_irq(void)
+{
+ return (((*IXP425_ICIH & 0x000000fc) >> 2) - 1);
+}
+
+static void timer_isr(void *data)
+{
+ unsigned int *pTime = (unsigned int *)data;
+
+ (*pTime)++;
+
+ /*
+ * Reset IRQ source
+ */
+ *IXP425_OSST = IXP425_OSST_TIMER_2_PEND;
+}
+
+ulong get_timer (ulong base)
+{
+ return timestamp - base;
+}
+
+void reset_timer (void)
+{
+ timestamp = 0;
+}
+
+#else /* #ifdef CONFIG_USE_IRQ */
void enable_interrupts (void)
{
return;
@@ -55,8 +120,7 @@ int disable_interrupts (void)
{
return 0;
}
-#endif
-
+#endif /* #ifdef CONFIG_USE_IRQ */
void bad_mode (void)
{
@@ -140,19 +204,46 @@ void do_fiq (struct pt_regs *pt_regs)
{
printf ("fast interrupt request\n");
show_regs (pt_regs);
- bad_mode ();
+ printf("IRQ=%08lx FIQ=%08lx\n", *IXP425_ICIH, *IXP425_ICFH);
}
void do_irq (struct pt_regs *pt_regs)
{
+#ifdef CONFIG_USE_IRQ
+ int irq = next_irq();
+
+ IRQ_HANDLER[irq].m_func(IRQ_HANDLER[irq].m_data);
+#else
printf ("interrupt request\n");
show_regs (pt_regs);
bad_mode ();
+#endif
}
-
int interrupt_init (void)
{
- /* nothing happens here - we don't setup any IRQs */
+#ifdef CONFIG_USE_IRQ
+ int i;
+
+ /* install default interrupt handlers */
+ for (i = 0; i < N_IRQS; i++) {
+ IRQ_HANDLER[i].m_data = (void *)i;
+ IRQ_HANDLER[i].m_func = default_isr;
+ }
+
+ /* install interrupt handler for timer */
+ IRQ_HANDLER[IXP425_TIMER_2_IRQ].m_data = (void *)&timestamp;
+ IRQ_HANDLER[IXP425_TIMER_2_IRQ].m_func = timer_isr;
+
+ /* setup the Timer counter value */
+ *IXP425_OSRT2 = (LATCH & ~IXP425_OST_RELOAD_MASK) | IXP425_OST_ENABLE;
+
+ /* configure interrupts for IRQ mode */
+ *IXP425_ICLR = 0x00000000;
+
+ /* enable timer irq */
+ *IXP425_ICMR = (1 << IXP425_TIMER_2_IRQ);
+#endif
+
return (0);
}
diff --git a/cpu/ixp/npe/IxEthAcc.c b/cpu/ixp/npe/IxEthAcc.c
new file mode 100644
index 0000000..d981649
--- /dev/null
+++ b/cpu/ixp/npe/IxEthAcc.c
@@ -0,0 +1,261 @@
+/**
+ * @file IxEthAcc.c
+ *
+ * @author Intel Corporation
+ * @date 20-Feb-2001
+ *
+ * @brief This file contains the implementation of the IXP425 Ethernet Access Component
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+
+#include "IxEthAcc.h"
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+#include "IxEthDB.h"
+#endif
+#include "IxFeatureCtrl.h"
+
+#include "IxEthAcc_p.h"
+#include "IxEthAccMac_p.h"
+#include "IxEthAccMii_p.h"
+
+/**
+ * @addtogroup IxEthAcc
+ *@{
+ */
+
+
+/**
+ * @brief System-wide information data strucure.
+ *
+ * @ingroup IxEthAccPri
+ *
+ */
+
+IxEthAccInfo ixEthAccDataInfo;
+extern PUBLIC IxEthAccMacState ixEthAccMacState[];
+extern PUBLIC IxOsalMutex ixEthAccControlInterfaceMutex;
+
+/**
+ * @brief System-wide information
+ *
+ * @ingroup IxEthAccPri
+ *
+ */
+BOOL ixEthAccServiceInit = FALSE;
+
+/* global filtering bit mask */
+PUBLIC UINT32 ixEthAccNewSrcMask;
+
+/**
+ * @brief Per port information data strucure.
+ *
+ * @ingroup IxEthAccPri
+ *
+ */
+
+IxEthAccPortDataInfo ixEthAccPortData[IX_ETH_ACC_NUMBER_OF_PORTS];
+
+PUBLIC IxEthAccStatus ixEthAccInit()
+{
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+ /*
+ * Initialize Control plane
+ */
+ if (ixEthDBInit() != IX_ETH_ACC_SUCCESS)
+ {
+ IX_ETH_ACC_WARNING_LOG("ixEthAccInit: EthDB init failed\n", 0, 0, 0, 0, 0, 0);
+
+ return IX_ETH_ACC_FAIL;
+ }
+#endif
+
+ if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
+ {
+ ixEthAccNewSrcMask = (~0); /* want all the bits */
+ }
+ else
+ {
+ ixEthAccNewSrcMask = (~IX_ETHACC_NE_NEWSRCMASK); /* want all but the NewSrc bit */
+ }
+
+ /*
+ * Initialize Data plane
+ */
+ if ( ixEthAccInitDataPlane() != IX_ETH_ACC_SUCCESS )
+ {
+ IX_ETH_ACC_WARNING_LOG("ixEthAccInit: data plane init failed\n", 0, 0, 0, 0, 0, 0);
+
+ return IX_ETH_ACC_FAIL;
+ }
+
+
+ if ( ixEthAccQMgrQueuesConfig() != IX_ETH_ACC_SUCCESS )
+ {
+ IX_ETH_ACC_WARNING_LOG("ixEthAccInit: queue config failed\n", 0, 0, 0, 0, 0, 0);
+
+ return IX_ETH_ACC_FAIL;
+ }
+
+ /*
+ * Initialize MII
+ */
+ if ( ixEthAccMiiInit() != IX_ETH_ACC_SUCCESS )
+ {
+ IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Mii init failed\n", 0, 0, 0, 0, 0, 0);
+
+ return IX_ETH_ACC_FAIL;
+ }
+
+ /*
+ * Initialize MAC I/O memory
+ */
+ if (ixEthAccMacMemInit() != IX_ETH_ACC_SUCCESS)
+ {
+ IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Mac init failed\n", 0, 0, 0, 0, 0, 0);
+
+ return IX_ETH_ACC_FAIL;
+ }
+
+ /*
+ * Initialize control plane interface lock
+ */
+ if (ixOsalMutexInit(&ixEthAccControlInterfaceMutex) != IX_SUCCESS)
+ {
+ IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Control plane interface lock initialization failed\n", 0, 0, 0, 0, 0, 0);
+
+ return IX_ETH_ACC_FAIL;
+ }
+
+ /* initialiasation is complete */
+ ixEthAccServiceInit = TRUE;
+
+ return IX_ETH_ACC_SUCCESS;
+
+}
+
+PUBLIC void ixEthAccUnload(void)
+{
+ IxEthAccPortId portId;
+
+ if ( IX_ETH_ACC_IS_SERVICE_INITIALIZED() )
+ {
+ /* check none of the port is still active */
+ for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+ {
+ if ( IX_ETH_IS_PORT_INITIALIZED(portId) )
+ {
+ if (ixEthAccMacState[portId].portDisableState == ACTIVE)
+ {
+ IX_ETH_ACC_WARNING_LOG("ixEthAccUnload: port %u still active, bail out\n", portId, 0, 0, 0, 0, 0);
+ return;
+ }
+ }
+ }
+
+ /* unmap the memory areas */
+ ixEthAccMiiUnload();
+ ixEthAccMacUnload();
+
+ /* set all ports as uninitialized */
+ for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+ {
+ ixEthAccPortData[portId].portInitialized = FALSE;
+ }
+
+ /* uninitialize the service */
+ ixEthAccServiceInit = FALSE;
+ }
+}
+
+PUBLIC IxEthAccStatus ixEthAccPortInit( IxEthAccPortId portId)
+{
+
+ IxEthAccStatus ret=IX_ETH_ACC_SUCCESS;
+
+ if ( ! IX_ETH_ACC_IS_SERVICE_INITIALIZED() )
+ {
+ return(IX_ETH_ACC_FAIL);
+ }
+
+ /*
+ * Check for valid port
+ */
+
+ if ( ! IX_ETH_ACC_IS_PORT_VALID(portId) )
+ {
+ return (IX_ETH_ACC_INVALID_PORT);
+ }
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot initialize Eth port.\n",(INT32) portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if ( IX_ETH_IS_PORT_INITIALIZED(portId) )
+ {
+ /* Already initialized */
+ return(IX_ETH_ACC_FAIL);
+ }
+
+ if(ixEthAccMacInit(portId)!=IX_ETH_ACC_SUCCESS)
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+
+ /*
+ * Set the port init flag.
+ */
+
+ ixEthAccPortData[portId].portInitialized = TRUE;
+
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+ /* init learning/filtering database structures for this port */
+ ixEthDBPortInit(portId);
+#endif
+
+ return(ret);
+}
+
+
diff --git a/cpu/ixp/npe/IxEthAccCommon.c b/cpu/ixp/npe/IxEthAccCommon.c
new file mode 100644
index 0000000..bda2c44
--- /dev/null
+++ b/cpu/ixp/npe/IxEthAccCommon.c
@@ -0,0 +1,1049 @@
+/**
+ * @file IxEthAccCommon.c
+ *
+ * @author Intel Corporation
+ * @date 12-Feb-2002
+ *
+ * @brief This file contains the implementation common support routines for the component
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/*
+ * Component header files
+ */
+
+#include "IxOsal.h"
+#include "IxEthAcc.h"
+#include "IxEthDB.h"
+#include "IxNpeMh.h"
+#include "IxEthDBPortDefs.h"
+#include "IxFeatureCtrl.h"
+#include "IxEthAcc_p.h"
+#include "IxEthAccQueueAssign_p.h"
+
+#include "IxEthAccDataPlane_p.h"
+#include "IxEthAccMii_p.h"
+
+/**
+ * @addtogroup IxEthAccPri
+ *@{
+ */
+
+extern IxEthAccInfo ixEthAccDataInfo;
+
+/**
+ *
+ * @brief Maximum number of RX queues set to be the maximum number
+ * of traffic calsses.
+ *
+ */
+#define IX_ETHACC_MAX_RX_QUEUES \
+ (IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY \
+ - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY \
+ + 1)
+
+/**
+ *
+ * @brief Maximum number of 128 entry RX queues
+ *
+ */
+#define IX_ETHACC_MAX_LARGE_RX_QUEUES 4
+
+/**
+ *
+ * @brief Data structure template for Default RX Queues
+ *
+ */
+IX_ETH_ACC_PRIVATE
+IxEthAccQregInfo ixEthAccQmgrRxDefaultTemplate =
+ {
+ IX_ETH_ACC_RX_FRAME_ETH_Q, /**< Queue ID */
+ "Eth Rx Q",
+ ixEthRxFrameQMCallback, /**< Functional callback */
+ (IxQMgrCallbackId) 0, /**< Callback tag */
+ IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */
+ IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */
+ TRUE, /**< Enable Q notification at startup */
+ IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE,/**< Q Condition to drive callback */
+ IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */
+ IX_QMGR_Q_WM_LEVEL1, /**< Q High water mark - needed by NPE */
+ };
+
+/**
+ *
+ * @brief Data structure template for Small RX Queues
+ *
+ */
+IX_ETH_ACC_PRIVATE
+IxEthAccQregInfo ixEthAccQmgrRxSmallTemplate =
+ {
+ IX_ETH_ACC_RX_FRAME_ETH_Q, /**< Queue ID */
+ "Eth Rx Q",
+ ixEthRxFrameQMCallback, /**< Functional callback */
+ (IxQMgrCallbackId) 0, /**< Callback tag */
+ IX_QMGR_Q_SIZE64, /**< Allocate Smaller Q */
+ IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */
+ TRUE, /**< Enable Q notification at startup */
+ IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE,/**< Q Condition to drive callback */
+ IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */
+ IX_QMGR_Q_WM_LEVEL1, /**< Q High water mark - needed by NPE */
+ };
+
+
+/**
+ *
+ * @brief Data structure used to register & initialize the Queues
+ *
+ */
+IX_ETH_ACC_PRIVATE
+IxEthAccQregInfo ixEthAccQmgrStaticInfo[]=
+{
+ {
+ IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q,
+ "Eth Rx Fr Q 1",
+ ixEthRxFreeQMCallback,
+ (IxQMgrCallbackId) IX_ETH_PORT_1,
+ IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */
+ IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */
+ FALSE, /**< Disable Q notification at startup */
+ IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE, /**< Q Condition to drive callback */
+ IX_QMGR_Q_WM_LEVEL0, /***< Q Low water mark */
+ IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */
+ },
+
+ {
+ IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q,
+ "Eth Rx Fr Q 2",
+ ixEthRxFreeQMCallback,
+ (IxQMgrCallbackId) IX_ETH_PORT_2,
+ IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */
+ IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */
+ FALSE, /**< Disable Q notification at startup */
+ IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE, /**< Q Condition to drive callback */
+ IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */
+ IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */
+ },
+#ifdef __ixp46X
+ {
+ IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q,
+ "Eth Rx Fr Q 3",
+ ixEthRxFreeQMCallback,
+ (IxQMgrCallbackId) IX_ETH_PORT_3,
+ IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */
+ IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */
+ FALSE, /**< Disable Q notification at startup */
+ IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE, /**< Q Condition to drive callback */
+ IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */
+ IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */
+ },
+#endif
+ {
+ IX_ETH_ACC_TX_FRAME_ENET0_Q,
+ "Eth Tx Q 1",
+ ixEthTxFrameQMCallback,
+ (IxQMgrCallbackId) IX_ETH_PORT_1,
+ IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */
+ IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */
+ FALSE, /**< Disable Q notification at startup */
+ IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE, /**< Q Condition to drive callback */
+ IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */
+ IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */
+ },
+
+ {
+ IX_ETH_ACC_TX_FRAME_ENET1_Q,
+ "Eth Tx Q 2",
+ ixEthTxFrameQMCallback,
+ (IxQMgrCallbackId) IX_ETH_PORT_2,
+ IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */
+ IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */
+ FALSE, /**< Disable Q notification at startup */
+ IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE, /**< Q Condition to drive callback */
+ IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */
+ IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */
+ },
+#ifdef __ixp46X
+ {
+ IX_ETH_ACC_TX_FRAME_ENET2_Q,
+ "Eth Tx Q 3",
+ ixEthTxFrameQMCallback,
+ (IxQMgrCallbackId) IX_ETH_PORT_3,
+ IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */
+ IX_QMGR_Q_ENTRY_SIZE1, /** Queue Entry Sizes - all Q entries are single ord entries */
+ FALSE, /** Disable Q notification at startup */
+ IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE, /** Q Condition to drive callback */
+ IX_QMGR_Q_WM_LEVEL0, /* No queues use almost empty */
+ IX_QMGR_Q_WM_LEVEL64, /** Q High water mark - needed used */
+ },
+#endif
+ {
+ IX_ETH_ACC_TX_FRAME_DONE_ETH_Q,
+ "Eth Tx Done Q",
+ ixEthTxFrameDoneQMCallback,
+ (IxQMgrCallbackId) 0,
+ IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */
+ IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */
+ TRUE, /**< Enable Q notification at startup */
+ IX_ETH_ACC_TX_FRAME_DONE_ETH_Q_SOURCE, /**< Q Condition to drive callback */
+ IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */
+ IX_QMGR_Q_WM_LEVEL2, /**< Q High water mark - needed by NPE */
+ },
+
+ { /* Null Termination entry
+ */
+ (IxQMgrQId)0,
+ (char *) NULL,
+ (IxQMgrCallback) NULL,
+ (IxQMgrCallbackId) 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }
+
+};
+
+/**
+ *
+ * @brief Data structure used to register & initialize the Queues
+ *
+ * The structure will be filled at run time depending on the NPE
+ * image already loaded and the QoS configured in ethDB.
+ *
+ */
+IX_ETH_ACC_PRIVATE
+IxEthAccQregInfo ixEthAccQmgrRxQueuesInfo[IX_ETHACC_MAX_RX_QUEUES+1]=
+{
+ { /* PlaceHolder for rx queues
+ * depending on the QoS configured
+ */
+ (IxQMgrQId)0,
+ (char *) NULL,
+ (IxQMgrCallback) NULL,
+ (IxQMgrCallbackId) 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ },
+
+ { /* PlaceHolder for rx queues
+ * depending on the QoS configured
+ */
+ (IxQMgrQId)0,
+ (char *) NULL,
+ (IxQMgrCallback) NULL,
+ (IxQMgrCallbackId) 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ },
+
+ { /* PlaceHolder for rx queues
+ * depending on the QoS configured
+ */
+ (IxQMgrQId)0,
+ (char *) NULL,
+ (IxQMgrCallback) NULL,
+ (IxQMgrCallbackId) 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ },
+
+ { /* PlaceHolder for rx queues
+ * depending on the QoS configured
+ */
+ (IxQMgrQId)0,
+ (char *) NULL,
+ (IxQMgrCallback) NULL,
+ (IxQMgrCallbackId) 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ },
+
+ { /* PlaceHolder for rx queues
+ * depending on the QoS configured
+ */
+ (IxQMgrQId)0,
+ (char *) NULL,
+ (IxQMgrCallback) NULL,
+ (IxQMgrCallbackId) 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ },
+
+ { /* PlaceHolder for rx queues
+ * depending on the QoS configured
+ */
+ (IxQMgrQId)0,
+ (char *) NULL,
+ (IxQMgrCallback) NULL,
+ (IxQMgrCallbackId) 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ },
+
+ { /* PlaceHolder for rx queues
+ * depending on the QoS configured
+ */
+ (IxQMgrQId)0,
+ (char *) NULL,
+ (IxQMgrCallback) NULL,
+ (IxQMgrCallbackId) 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ },
+
+ { /* PlaceHolder for rx queues
+ * depending on the QoS configured
+ */
+ (IxQMgrQId)0,
+ (char *) NULL,
+ (IxQMgrCallback) NULL,
+ (IxQMgrCallbackId) 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ },
+
+ { /* Null Termination entry
+ */
+ (IxQMgrQId)0,
+ (char *) NULL,
+ (IxQMgrCallback) NULL,
+ (IxQMgrCallbackId) 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }
+
+};
+
+/* forward declarations */
+IX_ETH_ACC_PRIVATE IxEthAccStatus
+ixEthAccQMgrQueueSetup(IxEthAccQregInfo *qInfoDes);
+
+/**
+ * @fn ixEthAccQMgrQueueSetup(void)
+ *
+ * @brief Setup one queue and its event, and register the callback required
+ * by this component to the QMgr
+ *
+ * @internal
+ */
+IX_ETH_ACC_PRIVATE IxEthAccStatus
+ixEthAccQMgrQueueSetup(IxEthAccQregInfo *qInfoDes)
+{
+ /*
+ * Configure each Q.
+ */
+ if ( ixQMgrQConfig( qInfoDes->qName,
+ qInfoDes->qId,
+ qInfoDes->qSize,
+ qInfoDes->qWords) != IX_SUCCESS)
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+
+ if ( ixQMgrWatermarkSet( qInfoDes->qId,
+ qInfoDes->AlmostEmptyThreshold,
+ qInfoDes->AlmostFullThreshold
+ ) != IX_SUCCESS)
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+
+ /*
+ * Set dispatcher priority.
+ */
+ if ( ixQMgrDispatcherPrioritySet( qInfoDes->qId,
+ IX_ETH_ACC_QM_QUEUE_DISPATCH_PRIORITY)
+ != IX_SUCCESS)
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+
+ /*
+ * Register callbacks for each Q.
+ */
+ if ( ixQMgrNotificationCallbackSet(qInfoDes->qId,
+ qInfoDes->qCallback,
+ qInfoDes->callbackTag)
+ != IX_SUCCESS )
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+
+ /*
+ * Set notification condition for Q
+ */
+ if ( qInfoDes->qNotificationEnableAtStartup == TRUE )
+ {
+ if ( ixQMgrNotificationEnable(qInfoDes->qId,
+ qInfoDes->qConditionSource)
+ != IX_SUCCESS )
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+ }
+
+ return(IX_ETH_ACC_SUCCESS);
+}
+
+/**
+ * @fn ixEthAccQMgrQueuesConfig(void)
+ *
+ * @brief Setup all the queues and register all callbacks required
+ * by this component to the QMgr
+ *
+ * The RxFree queues, tx queues, rx queues are configured statically
+ *
+ * Rx queues configuration is driven by QoS setup.
+ * Many Rx queues may be required when QoS is enabled (this depends
+ * on IxEthDB setup and the images being downloaded). The configuration
+ * of the rxQueues is done in many steps as follows:
+ *
+ * @li select all Rx queues as configured by ethDB for all ports
+ * @li sort the queues by traffic class
+ * @li build the priority dependency for all queues
+ * @li fill the configuration for all rx queues
+ * @li configure all statically configured queues
+ * @li configure all dynamically configured queues
+ *
+ * @param none
+ *
+ * @return IxEthAccStatus
+ *
+ * @internal
+ */
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccQMgrQueuesConfig(void)
+{
+ struct
+ {
+ int npeCount;
+ UINT32 npeId;
+ IxQMgrQId qId;
+ IxEthDBProperty trafficClass;
+ } rxQueues[IX_ETHACC_MAX_RX_QUEUES];
+
+ UINT32 rxQueue = 0;
+ UINT32 rxQueueCount = 0;
+ IxQMgrQId ixQId =IX_QMGR_MAX_NUM_QUEUES;
+ IxEthDBStatus ixEthDBStatus = IX_ETH_DB_SUCCESS;
+ IxEthDBPortId ixEthDbPortId = 0;
+ IxEthAccPortId ixEthAccPortId = 0;
+ UINT32 ixNpeId = 0;
+ UINT32 ixHighestNpeId = 0;
+ UINT32 sortIterations = 0;
+ IxEthAccStatus ret = IX_ETH_ACC_SUCCESS;
+ IxEthAccQregInfo *qInfoDes = NULL;
+ IxEthDBProperty ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY;
+ IxEthDBPropertyType ixEthDBPropertyType = IX_ETH_DB_INTEGER_PROPERTY;
+ UINT32 ixEthDBParameter = 0;
+ BOOL completelySorted = FALSE;
+
+ /* Fill the corspondance between ports and queues
+ * This defines the mapping from port to queue Ids.
+ */
+
+ ixEthAccPortData[IX_ETH_PORT_1].ixEthAccRxData.rxFreeQueue
+ = IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q;
+ ixEthAccPortData[IX_ETH_PORT_2].ixEthAccRxData.rxFreeQueue
+ = IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q;
+#ifdef __ixp46X
+ ixEthAccPortData[IX_ETH_PORT_3].ixEthAccRxData.rxFreeQueue
+ = IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q;
+#endif
+ ixEthAccPortData[IX_ETH_PORT_1].ixEthAccTxData.txQueue
+ = IX_ETH_ACC_TX_FRAME_ENET0_Q;
+ ixEthAccPortData[IX_ETH_PORT_2].ixEthAccTxData.txQueue
+ = IX_ETH_ACC_TX_FRAME_ENET1_Q;
+#ifdef __ixp46X
+ ixEthAccPortData[IX_ETH_PORT_3].ixEthAccTxData.txQueue
+ = IX_ETH_ACC_TX_FRAME_ENET2_Q;
+#endif
+ /* Fill the corspondance between ports and NPEs
+ * This defines the mapping from port to npeIds.
+ */
+
+ ixEthAccPortData[IX_ETH_PORT_1].npeId = IX_NPEMH_NPEID_NPEB;
+ ixEthAccPortData[IX_ETH_PORT_2].npeId = IX_NPEMH_NPEID_NPEC;
+#ifdef __ixp46X
+ ixEthAccPortData[IX_ETH_PORT_3].npeId = IX_NPEMH_NPEID_NPEA;
+#endif
+ /* set the default rx scheduling discipline */
+ ixEthAccDataInfo.schDiscipline = FIFO_NO_PRIORITY;
+
+ /*
+ * Queue Selection step:
+ *
+ * The following code selects all the queues and build
+ * a temporary array which contains for each queue
+ * - the queue Id,
+ * - the highest traffic class (in case of many
+ * priorities configured for the same queue on different
+ * ports)
+ * - the number of different Npes which are
+ * configured to write to this queue.
+ *
+ * The output of this loop is a temporary array of RX queues
+ * in any order.
+ *
+ */
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+ for (ixEthAccPortId = 0;
+ (ixEthAccPortId < IX_ETH_ACC_NUMBER_OF_PORTS)
+ && (ret == IX_ETH_ACC_SUCCESS);
+ ixEthAccPortId++)
+ {
+ /* map between ethDb and ethAcc port Ids */
+ ixEthDbPortId = (IxEthDBPortId)ixEthAccPortId;
+
+ /* map between npeId and ethAcc port Ids */
+ ixNpeId = IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId);
+
+ /* Iterate thru the different priorities */
+ for (ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY;
+ ixEthDBTrafficClass <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY;
+ ixEthDBTrafficClass++)
+ {
+ ixEthDBStatus = ixEthDBFeaturePropertyGet(
+ ixEthDbPortId,
+ IX_ETH_DB_VLAN_QOS,
+ ixEthDBTrafficClass,
+ &ixEthDBPropertyType,
+ (void *)&ixEthDBParameter);
+
+ if (ixEthDBStatus == IX_ETH_DB_SUCCESS)
+ {
+ /* This port and QoS class are mapped to
+ * a RX queue.
+ */
+ if (ixEthDBPropertyType == IX_ETH_DB_INTEGER_PROPERTY)
+ {
+ /* remember the highest npe Id supporting ethernet */
+ if (ixNpeId > ixHighestNpeId)
+ {
+ ixHighestNpeId = ixNpeId;
+ }
+
+ /* search the queue in the list of queues
+ * already used by an other port or QoS
+ */
+ for (rxQueue = 0;
+ rxQueue < rxQueueCount;
+ rxQueue++)
+ {
+ if (rxQueues[rxQueue].qId == (IxQMgrQId)ixEthDBParameter)
+ {
+ /* found an existing setup, update the number of ports
+ * for this queue if the port maps to
+ * a different NPE.
+ */
+ if (rxQueues[rxQueue].npeId != ixNpeId)
+ {
+ rxQueues[rxQueue].npeCount++;
+ rxQueues[rxQueue].npeId = ixNpeId;
+ }
+ /* get the highest traffic class for this queue */
+ if (rxQueues[rxQueue].trafficClass > ixEthDBTrafficClass)
+ {
+ rxQueues[rxQueue].trafficClass = ixEthDBTrafficClass;
+ }
+ break;
+ }
+ }
+ if (rxQueue == rxQueueCount)
+ {
+ /* new queue not found in the current list,
+ * add a new entry.
+ */
+ IX_OSAL_ASSERT(rxQueueCount < IX_ETHACC_MAX_RX_QUEUES);
+ rxQueues[rxQueueCount].qId = ixEthDBParameter;
+ rxQueues[rxQueueCount].npeCount = 1;
+ rxQueues[rxQueueCount].npeId = ixNpeId;
+ rxQueues[rxQueueCount].trafficClass = ixEthDBTrafficClass;
+ rxQueueCount++;
+ }
+ }
+ else
+ {
+ /* unexpected property type (not Integer) */
+ ret = IX_ETH_ACC_FAIL;
+
+ IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: unexpected property type returned by EthDB\n", 0, 0, 0, 0, 0, 0);
+
+ /* no point to continue to iterate */
+ break;
+ }
+ }
+ else
+ {
+ /* No Rx queue configured for this port
+ * and this traffic class. Do nothing.
+ */
+ }
+ }
+
+ /* notify EthDB that queue initialization is complete and traffic class allocation is frozen */
+ ixEthDBFeaturePropertySet(ixEthDbPortId,
+ IX_ETH_DB_VLAN_QOS,
+ IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE,
+ NULL /* ignored */);
+ }
+
+#else
+
+ ixNpeId = IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId);
+ rxQueues[0].qId = 4;
+ rxQueues[0].npeCount = 1;
+ rxQueues[0].npeId = ixNpeId;
+ rxQueues[0].trafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY;
+ rxQueueCount++;
+
+#endif
+
+ /* check there is at least 1 rx queue : there is no point
+ * to continue if there is no rx queue configured
+ */
+ if ((rxQueueCount == 0) || (ret == IX_ETH_ACC_FAIL))
+ {
+ IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: no queues configured, bailing out\n", 0, 0, 0, 0, 0, 0);
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ /* Queue sort step:
+ *
+ * Re-order the array of queues by decreasing traffic class
+ * using a bubble sort. (trafficClass 0 is the lowest
+ * priority traffic, trafficClass 7 is the highest priority traffic)
+ *
+ * Primary sort order is traffic class
+ * Secondary sort order is npeId
+ *
+ * Note that a bubble sort algorithm is not very efficient when
+ * the number of queues grows . However, this is not a very bad choice
+ * considering the very small number of entries to sort. Also, bubble
+ * sort is extremely fast when the list is already sorted.
+ *
+ * The output of this loop is a sorted array of queues.
+ *
+ */
+ sortIterations = 0;
+ do
+ {
+ sortIterations++;
+ completelySorted = TRUE;
+ for (rxQueue = 0;
+ rxQueue < rxQueueCount - sortIterations;
+ rxQueue++)
+ {
+ /* compare adjacent elements */
+ if ((rxQueues[rxQueue].trafficClass <
+ rxQueues[rxQueue+1].trafficClass)
+ || ((rxQueues[rxQueue].trafficClass ==
+ rxQueues[rxQueue+1].trafficClass)
+ &&(rxQueues[rxQueue].npeId <
+ rxQueues[rxQueue+1].npeId)))
+ {
+ /* swap adjacent elements */
+ int npeCount = rxQueues[rxQueue].npeCount;
+ UINT32 npeId = rxQueues[rxQueue].npeId;
+ IxQMgrQId qId = rxQueues[rxQueue].qId;
+ IxEthDBProperty trafficClass = rxQueues[rxQueue].trafficClass;
+ rxQueues[rxQueue].npeCount = rxQueues[rxQueue+1].npeCount;
+ rxQueues[rxQueue].npeId = rxQueues[rxQueue+1].npeId;
+ rxQueues[rxQueue].qId = rxQueues[rxQueue+1].qId;
+ rxQueues[rxQueue].trafficClass = rxQueues[rxQueue+1].trafficClass;
+ rxQueues[rxQueue+1].npeCount = npeCount;
+ rxQueues[rxQueue+1].npeId = npeId;
+ rxQueues[rxQueue+1].qId = qId;
+ rxQueues[rxQueue+1].trafficClass = trafficClass;
+ completelySorted = FALSE;
+ }
+ }
+ }
+ while (!completelySorted);
+
+ /* Queue traffic class list:
+ *
+ * Fill an array of rx queues linked by ascending traffic classes.
+ *
+ * If the queues are configured as follows
+ * qId 6 -> traffic class 0 (lowest)
+ * qId 7 -> traffic class 0
+ * qId 8 -> traffic class 6
+ * qId 12 -> traffic class 7 (highest)
+ *
+ * Then the output of this loop will be
+ *
+ * higherPriorityQueue[6] = 8
+ * higherPriorityQueue[7] = 8
+ * higherPriorityQueue[8] = 12
+ * higherPriorityQueue[12] = Invalid queueId
+ * higherPriorityQueue[...] = Invalid queueId
+ *
+ * Note that this queue ordering does not handle all possibilities
+ * that could result from different rules associated with different
+ * ports, and inconsistencies in the rules. In all cases, the
+ * output of this algorithm is a simple linked list of queues,
+ * without closed circuit.
+
+ * This list is implemented as an array with invalid values initialized
+ * with an "invalid" queue id which is the maximum number of queues.
+ *
+ */
+
+ /*
+ * Initialise the rx queue list.
+ */
+ for (rxQueue = 0; rxQueue < IX_QMGR_MAX_NUM_QUEUES; rxQueue++)
+ {
+ ixEthAccDataInfo.higherPriorityQueue[rxQueue] = IX_QMGR_MAX_NUM_QUEUES;
+ }
+
+ /* build the linked list for this NPE.
+ */
+ for (ixNpeId = 0;
+ ixNpeId <= ixHighestNpeId;
+ ixNpeId++)
+ {
+ /* iterate thru the sorted list of queues
+ */
+ ixQId = IX_QMGR_MAX_NUM_QUEUES;
+ for (rxQueue = 0;
+ rxQueue < rxQueueCount;
+ rxQueue++)
+ {
+ if (rxQueues[rxQueue].npeId == ixNpeId)
+ {
+ ixEthAccDataInfo.higherPriorityQueue[rxQueues[rxQueue].qId] = ixQId;
+ /* iterate thru queues with the same traffic class
+ * than the current queue. (queues are ordered by descending
+ * traffic classes and npeIds).
+ */
+ while ((rxQueue < rxQueueCount - 1)
+ && (rxQueues[rxQueue].trafficClass
+ == rxQueues[rxQueue+1].trafficClass)
+ && (ixNpeId == rxQueues[rxQueue].npeId))
+ {
+ rxQueue++;
+ ixEthAccDataInfo.higherPriorityQueue[rxQueues[rxQueue].qId] = ixQId;
+ }
+ ixQId = rxQueues[rxQueue].qId;
+ }
+ }
+ }
+
+ /* point on the first dynamic queue description */
+ qInfoDes = ixEthAccQmgrRxQueuesInfo;
+
+ /* update the list of queues with the rx queues */
+ for (rxQueue = 0;
+ (rxQueue < rxQueueCount) && (ret == IX_ETH_ACC_SUCCESS);
+ rxQueue++)
+ {
+ /* Don't utilize more than IX_ETHACC_MAX_LARGE_RX_QUEUES queues
+ * with the full 128 entries. For the lower priority queues, use
+ * a smaller number of entries. This ensures queue resources
+ * remain available for other components.
+ */
+ if( (rxQueueCount > IX_ETHACC_MAX_LARGE_RX_QUEUES) &&
+ (rxQueue < rxQueueCount - IX_ETHACC_MAX_LARGE_RX_QUEUES) )
+ {
+ /* add the small RX Queue setup template to the list of queues */
+ memcpy(qInfoDes, &ixEthAccQmgrRxSmallTemplate, sizeof(*qInfoDes));
+ } else {
+ /* add the default RX Queue setup template to the list of queues */
+ memcpy(qInfoDes, &ixEthAccQmgrRxDefaultTemplate, sizeof(*qInfoDes));
+ }
+
+ /* setup the RxQueue ID */
+ qInfoDes->qId = rxQueues[rxQueue].qId;
+
+ /* setup the RxQueue watermark level
+ *
+ * Each queue can be filled by many NPEs. To avoid the
+ * NPEs to write to a full queue, need to set the
+ * high watermark level for nearly full condition.
+ * (the high watermark level are a power of 2
+ * starting from the top of the queue)
+ *
+ * Number of watermark
+ * ports level
+ * 1 0
+ * 2 1
+ * 3 2
+ * 4 4
+ * 5 4
+ * 6 8
+ * n approx. 2**ceil(log2(n))
+ */
+ if (rxQueues[rxQueue].npeCount == 1)
+ {
+ qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL0;
+ }
+ else if (rxQueues[rxQueue].npeCount == 2)
+ {
+ qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL1;
+ }
+ else if (rxQueues[rxQueue].npeCount == 3)
+ {
+ qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL2;
+ }
+ else
+ {
+ /* reach the maximum number for CSR 2.0 */
+ IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: maximum number of NPEs per queue reached, bailing out\n", 0, 0, 0, 0, 0, 0);
+ ret = IX_ETH_ACC_FAIL;
+ break;
+ }
+
+ /* move to next queue entry */
+ ++qInfoDes;
+ }
+
+ /* configure the static list (RxFree, Tx and TxDone queues) */
+ for (qInfoDes = ixEthAccQmgrStaticInfo;
+ (qInfoDes->qCallback != (IxQMgrCallback) NULL )
+ && (ret == IX_ETH_ACC_SUCCESS);
+ ++qInfoDes)
+ {
+ ret = ixEthAccQMgrQueueSetup(qInfoDes);
+ }
+
+ /* configure the dynamic list (Rx queues) */
+ for (qInfoDes = ixEthAccQmgrRxQueuesInfo;
+ (qInfoDes->qCallback != (IxQMgrCallback) NULL )
+ && (ret == IX_ETH_ACC_SUCCESS);
+ ++qInfoDes)
+ {
+ ret = ixEthAccQMgrQueueSetup(qInfoDes);
+ }
+
+ return(ret);
+}
+
+/**
+ * @fn ixEthAccQMgrRxQEntryGet(UINT32 *rxQueueEntries)
+ *
+ * @brief Add and return the total number of entries in all Rx queues
+ *
+ * @param UINT32 rxQueueEntries[in] number of entries in all queues
+ *
+ * @return void
+ *
+ * @note Rx queues configuration is driven by Qos Setup. There is a
+ * variable number of rx queues which are set at initialisation.
+ *
+ * @internal
+ */
+IX_ETH_ACC_PUBLIC
+void ixEthAccQMgrRxQEntryGet(UINT32 *numRxQueueEntries)
+{
+ UINT32 rxQueueLevel;
+ IxEthAccQregInfo *qInfoDes;;
+
+ *numRxQueueEntries = 0;
+
+ /* iterate thru rx queues */
+ for (qInfoDes = ixEthAccQmgrRxQueuesInfo;
+ qInfoDes->qCallback != (IxQMgrCallback)NULL;
+ ++qInfoDes)
+ {
+ /* retrieve the rx queue level */
+ rxQueueLevel = 0;
+ ixQMgrQNumEntriesGet(qInfoDes->qId, &rxQueueLevel);
+ (*numRxQueueEntries) += rxQueueLevel;
+ }
+}
+
+/**
+ * @fn ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback)
+ *
+ * @brief Change the callback registered to all rx queues.
+ *
+ * @param IxQMgrCallback ixQMgrCallback[in] QMgr callback to register
+ *
+ * @return IxEthAccStatus
+ *
+ * @note The user may decide to use different Rx mechanisms
+ * (e.g. receive many frames at the same time , or receive
+ * one frame at a time, depending on the overall application
+ * performances). A different QMgr callback is registered. This
+ * way, there is no excessive pointer checks in the datapath.
+ *
+ * @internal
+ */
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback)
+{
+ IxEthAccQregInfo *qInfoDes;
+ IxEthAccStatus ret = IX_ETH_ACC_SUCCESS;
+
+ /* parameter check */
+ if (NULL == ixQMgrCallback)
+ {
+ ret = IX_ETH_ACC_FAIL;
+ }
+
+ /* iterate thru rx queues */
+ for (qInfoDes = ixEthAccQmgrRxQueuesInfo;
+ (qInfoDes->qCallback != (IxQMgrCallback) NULL )
+ && (ret == IX_ETH_ACC_SUCCESS);
+ ++qInfoDes)
+ {
+ /* register the rx callback for all queues */
+ if (ixQMgrNotificationCallbackSet(qInfoDes->qId,
+ ixQMgrCallback,
+ qInfoDes->callbackTag
+ ) != IX_SUCCESS)
+ {
+ ret = IX_ETH_ACC_FAIL;
+ }
+ }
+ return(ret);
+}
+
+/**
+ * @fn ixEthAccSingleEthNpeCheck(IxEthAccPortId portId)
+ *
+ * @brief Check the npe exists for this port
+ *
+ * @param IxEthAccPortId portId[in] port
+ *
+ * @return IxEthAccStatus
+ *
+ * @internal
+ */
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccSingleEthNpeCheck(IxEthAccPortId portId)
+{
+
+ /* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */
+ if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+ (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+ || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+ {
+ if ((IX_ETH_PORT_1 == portId) &&
+ (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
+ IX_FEATURE_CTRL_COMPONENT_ENABLED))
+ {
+ return IX_ETH_ACC_SUCCESS;
+ }
+
+ if ((IX_ETH_PORT_2 == portId) &&
+ (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
+ IX_FEATURE_CTRL_COMPONENT_ENABLED))
+ {
+ return IX_ETH_ACC_SUCCESS;
+ }
+
+ if ((IX_ETH_PORT_3 == portId) &&
+ (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) ==
+ IX_FEATURE_CTRL_COMPONENT_ENABLED))
+ {
+ return IX_ETH_ACC_SUCCESS;
+ }
+
+ return IX_ETH_ACC_FAIL;
+ }
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+/**
+ * @fn ixEthAccStatsShow(void)
+ *
+ * @brief Displays all EthAcc stats
+ *
+ * @return void
+ *
+ */
+void ixEthAccStatsShow(IxEthAccPortId portId)
+{
+ ixEthAccMdioShow();
+
+ printf("\nPort %u\nUnicast MAC : ", portId);
+ ixEthAccPortUnicastAddressShow(portId);
+ ixEthAccPortMulticastAddressShow(portId);
+ printf("\n");
+
+ ixEthAccDataPlaneShow();
+}
+
+
+
diff --git a/cpu/ixp/npe/IxEthAccControlInterface.c b/cpu/ixp/npe/IxEthAccControlInterface.c
new file mode 100644
index 0000000..4432847
--- /dev/null
+++ b/cpu/ixp/npe/IxEthAccControlInterface.c
@@ -0,0 +1,533 @@
+/**
+ * @file IxEthAccControlInterface.c
+ *
+ * @author Intel Corporation
+ * @date
+ *
+ * @brief IX_ETH_ACC_PUBLIC wrappers for control plane functions
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxOsal.h"
+#include "IxEthAcc.h"
+#include "IxEthAcc_p.h"
+
+PUBLIC IxOsalMutex ixEthAccControlInterfaceMutex;
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortEnable(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ printf("EthAcc: (Mac) cannot enable port %d, service not initialized\n", portId);
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortEnablePriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortDisable(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ /* check the context is iinitialized */
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortDisablePriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortEnabledQueryPriv(portId, enabled);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortPromiscuousModeClearPriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortPromiscuousModeSetPriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortUnicastMacAddressSet(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortUnicastMacAddressSetPriv(portId, macAddr);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortUnicastMacAddressGet(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortUnicastMacAddressGetPriv(portId, macAddr);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortMulticastAddressJoin(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortMulticastAddressJoinPriv(portId, macAddr);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortMulticastAddressJoinAll(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortMulticastAddressJoinAllPriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortMulticastAddressLeave(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortMulticastAddressLeavePriv(portId, macAddr);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortMulticastAddressLeaveAll(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortMulticastAddressLeaveAllPriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortUnicastAddressShow(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortUnicastAddressShowPriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC void
+ixEthAccPortMulticastAddressShow(IxEthAccPortId portId)
+{
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return;
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ ixEthAccPortMulticastAddressShowPriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortDuplexModeSet(IxEthAccPortId portId, IxEthAccDuplexMode mode)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortDuplexModeSetPriv(portId, mode);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortDuplexModeGet(IxEthAccPortId portId, IxEthAccDuplexMode *mode)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortDuplexModeGetPriv(portId, mode);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortTxFrameAppendPaddingEnable(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortTxFrameAppendPaddingEnablePriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortTxFrameAppendPaddingDisable(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortTxFrameAppendPaddingDisablePriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortTxFrameAppendFCSEnable(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortTxFrameAppendFCSEnablePriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortTxFrameAppendFCSDisable(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortTxFrameAppendFCSDisablePriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortRxFrameAppendFCSEnable(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortRxFrameAppendFCSEnablePriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortRxFrameAppendFCSDisable(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortRxFrameAppendFCSDisablePriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccTxSchedulingDisciplineSet(IxEthAccPortId portId, IxEthAccSchedulerDiscipline sched)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccTxSchedulingDisciplineSetPriv(portId, sched);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccRxSchedulingDisciplineSetPriv(sched);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortNpeLoopbackEnable(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccNpeLoopbackEnablePriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortTxEnable(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortTxEnablePriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortRxEnable(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortRxEnablePriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccNpeLoopbackDisablePriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortTxDisable(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortTxDisablePriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortRxDisable(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortRxDisablePriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortMacReset(IxEthAccPortId portId)
+{
+ IxEthAccStatus result;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+ result = ixEthAccPortMacResetPriv(portId);
+ ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+ return result;
+}
diff --git a/cpu/ixp/npe/IxEthAccDataPlane.c b/cpu/ixp/npe/IxEthAccDataPlane.c
new file mode 100644
index 0000000..e46fc9b
--- /dev/null
+++ b/cpu/ixp/npe/IxEthAccDataPlane.c
@@ -0,0 +1,2483 @@
+/**
+ * @file IxEthDataPlane.c
+ *
+ * @author Intel Corporation
+ * @date 12-Feb-2002
+ *
+ * @brief This file contains the implementation of the IXPxxx
+ * Ethernet Access Data plane component
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxNpeMh.h"
+#include "IxEthAcc.h"
+#include "IxEthDB.h"
+#include "IxOsal.h"
+#include "IxEthDBPortDefs.h"
+#include "IxFeatureCtrl.h"
+#include "IxEthAcc_p.h"
+#include "IxEthAccQueueAssign_p.h"
+
+extern PUBLIC IxEthAccMacState ixEthAccMacState[];
+extern PUBLIC UINT32 ixEthAccNewSrcMask;
+
+/**
+ * private functions prototype
+ */
+PRIVATE IX_OSAL_MBUF *
+ixEthAccEntryFromQConvert(UINT32 qEntry, UINT32 mask);
+
+PRIVATE UINT32
+ixEthAccMbufRxQPrepare(IX_OSAL_MBUF *mbuf);
+
+PRIVATE UINT32
+ixEthAccMbufTxQPrepare(IX_OSAL_MBUF *mbuf);
+
+PRIVATE IxEthAccStatus
+ixEthAccTxSwQHighestPriorityGet(IxEthAccPortId portId,
+ IxEthAccTxPriority *priorityPtr);
+
+PRIVATE IxEthAccStatus
+ixEthAccTxFromSwQ(IxEthAccPortId portId,
+ IxEthAccTxPriority priority);
+
+PRIVATE IxEthAccStatus
+ixEthAccRxFreeFromSwQ(IxEthAccPortId portId);
+
+PRIVATE void
+ixEthAccMbufFromTxQ(IX_OSAL_MBUF *mbuf);
+
+PRIVATE void
+ixEthAccMbufFromRxQ(IX_OSAL_MBUF *mbuf);
+
+PRIVATE IX_STATUS
+ixEthAccQmgrLockTxWrite(IxEthAccPortId portId,
+ UINT32 qBuffer);
+
+PRIVATE IX_STATUS
+ixEthAccQmgrLockRxWrite(IxEthAccPortId portId,
+ UINT32 qBuffer);
+
+PRIVATE IX_STATUS
+ixEthAccQmgrTxWrite(IxEthAccPortId portId,
+ UINT32 qBuffer,
+ UINT32 priority);
+
+/**
+ * @addtogroup IxEthAccPri
+ *@{
+ */
+
+/* increment a counter only when stats are enabled */
+#define TX_STATS_INC(port,field) \
+ IX_ETH_ACC_STATS_INC(ixEthAccPortData[port].ixEthAccTxData.stats.field)
+#define RX_STATS_INC(port,field) \
+ IX_ETH_ACC_STATS_INC(ixEthAccPortData[port].ixEthAccRxData.stats.field)
+
+/* always increment the counter (mainly used for unexpected errors) */
+#define TX_INC(port,field) \
+ ixEthAccPortData[port].ixEthAccTxData.stats.field++
+#define RX_INC(port,field) \
+ ixEthAccPortData[port].ixEthAccRxData.stats.field++
+
+PRIVATE IxEthAccDataPlaneStats ixEthAccDataStats;
+
+extern IxEthAccPortDataInfo ixEthAccPortData[];
+extern IxEthAccInfo ixEthAccDataInfo;
+
+PRIVATE IxOsalFastMutex txWriteMutex[IX_ETH_ACC_NUMBER_OF_PORTS];
+PRIVATE IxOsalFastMutex rxWriteMutex[IX_ETH_ACC_NUMBER_OF_PORTS];
+
+/**
+ *
+ * @brief Mbuf header conversion macros : they implement the
+ * different conversions using a temporary value. They also double-check
+ * that the parameters can be converted to/from NPE format.
+ *
+ */
+#if defined(__wince) && !defined(IN_KERNEL)
+#define PTR_VIRT2NPE(ptrSrc,dst) \
+ do { UINT32 temp; \
+ IX_OSAL_ENSURE(sizeof(ptrSrc) == sizeof(UINT32), "Wrong parameter type"); \
+ IX_OSAL_ENSURE(sizeof(dst) == sizeof(UINT32), "Wrong parameter type"); \
+ temp = (UINT32)IX_OSAL_MBUF_MBUF_VIRTUAL_TO_PHYSICAL_TRANSLATION((IX_OSAL_MBUF*)ptrSrc); \
+ (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \
+ while(0)
+
+#define PTR_NPE2VIRT(type,src,ptrDst) \
+ do { void *temp; \
+ IX_OSAL_ENSURE(sizeof(type) == sizeof(UINT32), "Wrong parameter type"); \
+ IX_OSAL_ENSURE(sizeof(src) == sizeof(UINT32), "Wrong parameter type"); \
+ IX_OSAL_ENSURE(sizeof(ptrDst) == sizeof(UINT32), "Wrong parameter type"); \
+ temp = (void *)IX_OSAL_SWAP_BE_SHARED_LONG(src); \
+ (ptrDst) = (type)IX_OSAL_MBUF_MBUF_PHYSICAL_TO_VIRTUAL_TRANSLATION(temp); } \
+ while(0)
+#else
+#define PTR_VIRT2NPE(ptrSrc,dst) \
+ do { UINT32 temp; \
+ IX_OSAL_ENSURE(sizeof(ptrSrc) == sizeof(UINT32), "Wrong parameter type"); \
+ IX_OSAL_ENSURE(sizeof(dst) == sizeof(UINT32), "Wrong parameter type"); \
+ temp = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS(ptrSrc); \
+ (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \
+ while(0)
+
+#define PTR_NPE2VIRT(type,src,ptrDst) \
+ do { void *temp; \
+ IX_OSAL_ENSURE(sizeof(type) == sizeof(UINT32), "Wrong parameter type"); \
+ IX_OSAL_ENSURE(sizeof(src) == sizeof(UINT32), "Wrong parameter type"); \
+ IX_OSAL_ENSURE(sizeof(ptrDst) == sizeof(UINT32), "Wrong parameter type"); \
+ temp = (void *)IX_OSAL_SWAP_BE_SHARED_LONG(src); \
+ (ptrDst) = (type)IX_OSAL_MMU_PHYS_TO_VIRT(temp); } \
+ while(0)
+#endif
+
+/**
+ *
+ * @brief Mbuf payload pointer conversion macros : Wince has its own
+ * method to convert the buffer pointers
+ */
+#if defined(__wince) && !defined(IN_KERNEL)
+#define DATAPTR_VIRT2NPE(ptrSrc,dst) \
+ do { UINT32 temp; \
+ temp = (UINT32)IX_OSAL_MBUF_DATA_VIRTUAL_TO_PHYSICAL_TRANSLATION(ptrSrc); \
+ (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \
+ while(0)
+
+#else
+#define DATAPTR_VIRT2NPE(ptrSrc,dst) PTR_VIRT2NPE(IX_OSAL_MBUF_MDATA(ptrSrc),dst)
+#endif
+
+
+/* Flush the shared part of the mbuf header */
+#define IX_ETHACC_NE_CACHE_FLUSH(mbufPtr) \
+ do { \
+ IX_OSAL_CACHE_FLUSH(IX_ETHACC_NE_SHARED(mbufPtr), \
+ sizeof(IxEthAccNe)); \
+ } \
+ while(0)
+
+/* Invalidate the shared part of the mbuf header */
+#define IX_ETHACC_NE_CACHE_INVALIDATE(mbufPtr) \
+ do { \
+ IX_OSAL_CACHE_INVALIDATE(IX_ETHACC_NE_SHARED(mbufPtr), \
+ sizeof(IxEthAccNe)); \
+ } \
+ while(0)
+
+/* Preload one cache line (shared mbuf headers are aligned
+ * and their size is 1 cache line)
+ *
+ * IX_OSAL_CACHED is defined when the mbuf headers are
+ * allocated from cached memory.
+ *
+ * Other processor on emulation environment may not implement
+ * preload function
+ */
+#ifdef IX_OSAL_CACHED
+ #if (CPU!=SIMSPARCSOLARIS) && !defined (__wince)
+ #define IX_ACC_DATA_CACHE_PRELOAD(ptr) \
+ do { /* preload a cache line (Xscale Processor) */ \
+ __asm__ (" pld [%0]\n": : "r" (ptr)); \
+ } \
+ while(0)
+ #else
+ /* preload not implemented on different processor */
+ #define IX_ACC_DATA_CACHE_PRELOAD(mbufPtr) \
+ do { /* nothing */ } while (0)
+ #endif
+#else
+ /* preload not needed if cache is not enabled */
+ #define IX_ACC_DATA_CACHE_PRELOAD(mbufPtr) \
+ do { /* nothing */ } while (0)
+#endif
+
+/**
+ *
+ * @brief function to retrieve the correct pointer from
+ * a queue entry posted by the NPE
+ *
+ * @param qEntry : entry from qmgr queue
+ * mask : applicable mask for this queue
+ * (4 most significant bits are used for additional informations)
+ *
+ * @return IX_OSAL_MBUF * pointer to mbuf header
+ *
+ * @internal
+ */
+PRIVATE IX_OSAL_MBUF *
+ixEthAccEntryFromQConvert(UINT32 qEntry, UINT32 mask)
+{
+ IX_OSAL_MBUF *mbufPtr;
+
+ if (qEntry != 0)
+ {
+ /* mask NPE bits (e.g. priority, port ...) */
+ qEntry &= mask;
+
+#if IX_ACC_DRAM_PHYS_OFFSET != 0
+ /* restore the original address pointer (if PHYS_OFFSET is not 0) */
+ qEntry |= (IX_ACC_DRAM_PHYS_OFFSET & ~IX_ETHNPE_QM_Q_RXENET_ADDR_MASK);
+#endif
+ /* get the mbuf pointer address from the npe-shared address */
+ qEntry -= offsetof(IX_OSAL_MBUF,ix_ne);
+
+ /* phys2virt mbuf */
+ mbufPtr = (IX_OSAL_MBUF *)IX_OSAL_MMU_PHYS_TO_VIRT(qEntry);
+
+ /* preload the cacheline shared with NPE */
+ IX_ACC_DATA_CACHE_PRELOAD(IX_ETHACC_NE_SHARED(mbufPtr));
+
+ /* preload the cacheline used by xscale */
+ IX_ACC_DATA_CACHE_PRELOAD(mbufPtr);
+ }
+ else
+ {
+ mbufPtr = NULL;
+ }
+
+ return mbufPtr;
+}
+
+/* Convert the mbuf header for NPE transmission */
+PRIVATE UINT32
+ixEthAccMbufTxQPrepare(IX_OSAL_MBUF *mbuf)
+{
+ UINT32 qbuf;
+ UINT32 len;
+
+ /* endianess swap for tci and flags
+ note: this is done only once, even for chained buffers */
+ IX_ETHACC_NE_FLAGS(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_FLAGS(mbuf));
+ IX_ETHACC_NE_VLANTCI(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_VLANTCI(mbuf));
+
+ /* test for unchained mbufs */
+ if (IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) == NULL)
+ {
+ /* "best case" scenario : unchained mbufs */
+ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedTxMBufs);
+
+ /* payload pointer conversion */
+ DATAPTR_VIRT2NPE(mbuf, IX_ETHACC_NE_DATA(mbuf));
+
+ /* unchained mbufs : the frame length is the mbuf length
+ * and the 2 identical lengths are stored in the same
+ * word.
+ */
+ len = IX_OSAL_MBUF_MLEN(mbuf);
+
+ /* set the length in both length and pktLen 16-bits fields */
+ len |= (len << IX_ETHNPE_ACC_LENGTH_OFFSET);
+ IX_ETHACC_NE_LEN(mbuf) = IX_OSAL_SWAP_BE_SHARED_LONG(len);
+
+ /* unchained mbufs : next contains 0 */
+ IX_ETHACC_NE_NEXT(mbuf) = 0;
+
+ /* flush shared header after all address conversions */
+ IX_ETHACC_NE_CACHE_FLUSH(mbuf);
+ }
+ else
+ {
+ /* chained mbufs */
+ IX_OSAL_MBUF *ptr = mbuf;
+ IX_OSAL_MBUF *nextPtr;
+ UINT32 frmLen;
+
+ /* get the frame length from the header of the first buffer */
+ frmLen = IX_OSAL_MBUF_PKT_LEN(mbuf);
+
+ do
+ {
+ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedTxMBufs);
+
+ /* payload pointer */
+ DATAPTR_VIRT2NPE(ptr,IX_ETHACC_NE_DATA(ptr));
+ /* Buffer length and frame length are stored in the same word */
+ len = IX_OSAL_MBUF_MLEN(ptr);
+ len = frmLen | (len << IX_ETHNPE_ACC_LENGTH_OFFSET);
+ IX_ETHACC_NE_LEN(ptr) = IX_OSAL_SWAP_BE_SHARED_LONG(len);
+
+ /* get the virtual next chain pointer */
+ nextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr);
+ if (nextPtr != NULL)
+ {
+ /* shared pointer of the next buffer is chained */
+ PTR_VIRT2NPE(IX_ETHACC_NE_SHARED(nextPtr),
+ IX_ETHACC_NE_NEXT(ptr));
+ }
+ else
+ {
+ IX_ETHACC_NE_NEXT(ptr) = 0;
+ }
+
+ /* flush shared header after all address conversions */
+ IX_ETHACC_NE_CACHE_FLUSH(ptr);
+
+ /* move to next buffer */
+ ptr = nextPtr;
+
+ /* the frame length field is set only in the first buffer
+ * and is zeroed in the next buffers
+ */
+ frmLen = 0;
+ }
+ while(ptr != NULL);
+
+ }
+
+ /* virt2phys mbuf itself */
+ qbuf = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS(
+ IX_ETHACC_NE_SHARED(mbuf));
+
+ /* Ensure the bits which are reserved to exchange information with
+ * the NPE are cleared
+ *
+ * If the mbuf address is not correctly aligned, or from an
+ * incompatible memory range, there is no point to continue
+ */
+ IX_OSAL_ENSURE(((qbuf & ~IX_ETHNPE_QM_Q_TXENET_ADDR_MASK) == 0),
+ "Invalid address range");
+
+ return qbuf;
+}
+
+/* Convert the mbuf header for NPE reception */
+PRIVATE UINT32
+ixEthAccMbufRxQPrepare(IX_OSAL_MBUF *mbuf)
+{
+ UINT32 len;
+ UINT32 qbuf;
+
+ if (IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) == NULL)
+ {
+ /* "best case" scenario : unchained mbufs */
+ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedRxFreeMBufs);
+
+ /* unchained mbufs : payload pointer */
+ DATAPTR_VIRT2NPE(mbuf, IX_ETHACC_NE_DATA(mbuf));
+
+ /* unchained mbufs : set the buffer length
+ * and the frame length field is zeroed
+ */
+ len = (IX_OSAL_MBUF_MLEN(mbuf) << IX_ETHNPE_ACC_LENGTH_OFFSET);
+ IX_ETHACC_NE_LEN(mbuf) = IX_OSAL_SWAP_BE_SHARED_LONG(len);
+
+ /* unchained mbufs : next pointer is null */
+ IX_ETHACC_NE_NEXT(mbuf) = 0;
+
+ /* flush shared header after all address conversions */
+ IX_ETHACC_NE_CACHE_FLUSH(mbuf);
+
+ /* remove shared header cache line */
+ IX_ETHACC_NE_CACHE_INVALIDATE(mbuf);
+ }
+ else
+ {
+ /* chained mbufs */
+ IX_OSAL_MBUF *ptr = mbuf;
+ IX_OSAL_MBUF *nextPtr;
+
+ do
+ {
+ /* chained mbufs */
+ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedRxFreeMBufs);
+
+ /* we must save virtual next chain pointer */
+ nextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr);
+
+ if (nextPtr != NULL)
+ {
+ /* chaining pointer for NPE */
+ PTR_VIRT2NPE(IX_ETHACC_NE_SHARED(nextPtr),
+ IX_ETHACC_NE_NEXT(ptr));
+ }
+ else
+ {
+ IX_ETHACC_NE_NEXT(ptr) = 0;
+ }
+
+ /* payload pointer */
+ DATAPTR_VIRT2NPE(ptr,IX_ETHACC_NE_DATA(ptr));
+
+ /* buffer length */
+ len = (IX_OSAL_MBUF_MLEN(ptr) << IX_ETHNPE_ACC_LENGTH_OFFSET);
+ IX_ETHACC_NE_LEN(ptr) = IX_OSAL_SWAP_BE_SHARED_LONG(len);
+
+ /* flush shared header after all address conversions */
+ IX_ETHACC_NE_CACHE_FLUSH(ptr);
+
+ /* remove shared header cache line */
+ IX_ETHACC_NE_CACHE_INVALIDATE(ptr);
+
+ /* next mbuf in the chain */
+ ptr = nextPtr;
+ }
+ while(ptr != NULL);
+ }
+
+ /* virt2phys mbuf itself */
+ qbuf = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS(
+ IX_ETHACC_NE_SHARED(mbuf));
+
+ /* Ensure the bits which are reserved to exchange information with
+ * the NPE are cleared
+ *
+ * If the mbuf address is not correctly aligned, or from an
+ * incompatible memory range, there is no point to continue
+ */
+ IX_OSAL_ENSURE(((qbuf & ~IX_ETHNPE_QM_Q_RXENET_ADDR_MASK) == 0),
+ "Invalid address range");
+
+ return qbuf;
+}
+
+/* Convert the mbuf header after NPE transmission
+ * Since there is nothing changed by the NPE, there is no need
+ * to process anything but the update of internal stats
+ * when they are enabled
+*/
+PRIVATE void
+ixEthAccMbufFromTxQ(IX_OSAL_MBUF *mbuf)
+{
+#ifndef NDEBUG
+ /* test for unchained mbufs */
+ if (IX_ETHACC_NE_NEXT(mbuf) == 0)
+ {
+ /* unchained mbufs : update the stats */
+ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedTxDoneMBufs);
+ }
+ else
+ {
+ /* chained mbufs : walk the chain and update the stats */
+ IX_OSAL_MBUF *ptr = mbuf;
+
+ do
+ {
+ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedTxDoneMBufs);
+ ptr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr);
+ }
+ while (ptr != NULL);
+ }
+#endif
+}
+
+/* Convert the mbuf header after NPE reception */
+PRIVATE void
+ixEthAccMbufFromRxQ(IX_OSAL_MBUF *mbuf)
+{
+ UINT32 len;
+
+ /* endianess swap for tci and flags
+ note: this is done only once, even for chained buffers */
+ IX_ETHACC_NE_FLAGS(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_FLAGS(mbuf));
+ IX_ETHACC_NE_VLANTCI(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_VLANTCI(mbuf));
+
+ /* test for unchained mbufs */
+ if (IX_ETHACC_NE_NEXT(mbuf) == 0)
+ {
+ /* unchained mbufs */
+ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedRxMBufs);
+
+ /* get the frame length. it is the same than the buffer length */
+ len = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(mbuf));
+ len &= IX_ETHNPE_ACC_PKTLENGTH_MASK;
+ IX_OSAL_MBUF_PKT_LEN(mbuf) = IX_OSAL_MBUF_MLEN(mbuf) = len;
+
+ /* clears the next packet field */
+ IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) = NULL;
+ }
+ else
+ {
+ IX_OSAL_MBUF *ptr = mbuf;
+ IX_OSAL_MBUF *nextPtr;
+ UINT32 frmLen;
+
+ /* convert the frame length */
+ frmLen = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(mbuf));
+ IX_OSAL_MBUF_PKT_LEN(mbuf) = (frmLen & IX_ETHNPE_ACC_PKTLENGTH_MASK);
+
+ /* chained mbufs */
+ do
+ {
+ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedRxMBufs);
+
+ /* convert the length */
+ len = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(ptr));
+ IX_OSAL_MBUF_MLEN(ptr) = (len >> IX_ETHNPE_ACC_LENGTH_OFFSET);
+
+ /* get the next pointer */
+ PTR_NPE2VIRT(IX_OSAL_MBUF *,IX_ETHACC_NE_NEXT(ptr), nextPtr);
+ if (nextPtr != NULL)
+ {
+ nextPtr = (IX_OSAL_MBUF *)((UINT8 *)nextPtr - offsetof(IX_OSAL_MBUF,ix_ne));
+ }
+ /* set the next pointer */
+ IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr) = nextPtr;
+
+ /* move to the next buffer */
+ ptr = nextPtr;
+ }
+ while (ptr != NULL);
+ }
+}
+
+/* write to qmgr if possible and report an overflow if not possible
+ * Use a fast lock to protect the queue write.
+ * This way, the tx feature is reentrant.
+ */
+PRIVATE IX_STATUS
+ixEthAccQmgrLockTxWrite(IxEthAccPortId portId, UINT32 qBuffer)
+{
+ IX_STATUS qStatus;
+ if (ixOsalFastMutexTryLock(&txWriteMutex[portId]) == IX_SUCCESS)
+ {
+ qStatus = ixQMgrQWrite(
+ IX_ETH_ACC_PORT_TO_TX_Q_ID(portId),
+ &qBuffer);
+#ifndef NDEBUG
+ if (qStatus != IX_SUCCESS)
+ {
+ TX_STATS_INC(portId, txOverflow);
+ }
+#endif
+ ixOsalFastMutexUnlock(&txWriteMutex[portId]);
+ }
+ else
+ {
+ TX_STATS_INC(portId, txLock);
+ qStatus = IX_QMGR_Q_OVERFLOW;
+ }
+ return qStatus;
+}
+
+/* write to qmgr if possible and report an overflow if not possible
+ * Use a fast lock to protect the queue write.
+ * This way, the Rx feature is reentrant.
+ */
+PRIVATE IX_STATUS
+ixEthAccQmgrLockRxWrite(IxEthAccPortId portId, UINT32 qBuffer)
+{
+ IX_STATUS qStatus;
+ if (ixOsalFastMutexTryLock(&rxWriteMutex[portId]) == IX_SUCCESS)
+ {
+ qStatus = ixQMgrQWrite(
+ IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId),
+ &qBuffer);
+#ifndef NDEBUG
+ if (qStatus != IX_SUCCESS)
+ {
+ RX_STATS_INC(portId, rxFreeOverflow);
+ }
+#endif
+ ixOsalFastMutexUnlock(&rxWriteMutex[portId]);
+ }
+ else
+ {
+ RX_STATS_INC(portId, rxFreeLock);
+ qStatus = IX_QMGR_Q_OVERFLOW;
+ }
+ return qStatus;
+}
+
+/*
+ * Set the priority and write to a qmgr queue.
+ */
+PRIVATE IX_STATUS
+ixEthAccQmgrTxWrite(IxEthAccPortId portId, UINT32 qBuffer, UINT32 priority)
+{
+ /* fill the priority field */
+ qBuffer |= (priority << IX_ETHNPE_QM_Q_FIELD_PRIOR_R);
+
+ return ixEthAccQmgrLockTxWrite(portId, qBuffer);
+}
+
+/**
+ *
+ * @brief This function will discover the highest priority S/W Tx Q that
+ * has entries in it
+ *
+ * @param portId - (in) the id of the port whose S/W Tx queues are to be searched
+ * priorityPtr - (out) the priority of the highest priority occupied q will be written
+ * here
+ *
+ * @return IX_ETH_ACC_SUCCESS if an occupied Q is found
+ * IX_ETH_ACC_FAIL if no Q has entries
+ *
+ * @internal
+ */
+PRIVATE IxEthAccStatus
+ixEthAccTxSwQHighestPriorityGet(IxEthAccPortId portId,
+ IxEthAccTxPriority *priorityPtr)
+{
+ if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline
+ == FIFO_NO_PRIORITY)
+ {
+ if(IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId].
+ ixEthAccTxData.txQ[IX_ETH_ACC_TX_DEFAULT_PRIORITY]))
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+ else
+ {
+ *priorityPtr = IX_ETH_ACC_TX_DEFAULT_PRIORITY;
+ TX_STATS_INC(portId,txPriority[*priorityPtr]);
+ return IX_ETH_ACC_SUCCESS;
+ }
+ }
+ else
+ {
+ IxEthAccTxPriority highestPriority = IX_ETH_ACC_TX_PRIORITY_7;
+ while(1)
+ {
+ if(!IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId].
+ ixEthAccTxData.txQ[highestPriority]))
+ {
+
+ *priorityPtr = highestPriority;
+ TX_STATS_INC(portId,txPriority[highestPriority]);
+ return IX_ETH_ACC_SUCCESS;
+
+ }
+ if (highestPriority == IX_ETH_ACC_TX_PRIORITY_0)
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+ highestPriority--;
+ }
+ }
+}
+
+/**
+ *
+ * @brief This function will take a buffer from a TX S/W Q and attempt
+ * to add it to the relevant TX H/W Q
+ *
+ * @param portId - the port whose TX queue is to be written to
+ * priority - identifies the queue from which the entry is to be read
+ *
+ * @internal
+ */
+PRIVATE IxEthAccStatus
+ixEthAccTxFromSwQ(IxEthAccPortId portId,
+ IxEthAccTxPriority priority)
+{
+ IX_OSAL_MBUF *mbuf;
+ IX_STATUS qStatus;
+
+ IX_OSAL_ENSURE((UINT32)priority <= (UINT32)7, "Invalid priority");
+
+ IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD(
+ ixEthAccPortData[portId].ixEthAccTxData.txQ[priority],
+ mbuf);
+
+ if (mbuf != NULL)
+ {
+ /*
+ * Add the Tx buffer to the H/W Tx Q
+ * We do not need to flush here as it is already done
+ * in TxFrameSubmit().
+ */
+ qStatus = ixEthAccQmgrTxWrite(
+ portId,
+ IX_OSAL_MMU_VIRT_TO_PHYS((UINT32)IX_ETHACC_NE_SHARED(mbuf)),
+ priority);
+
+ if (qStatus == IX_SUCCESS)
+ {
+ TX_STATS_INC(portId,txFromSwQOK);
+ return IX_SUCCESS;
+ }
+ else if (qStatus == IX_QMGR_Q_OVERFLOW)
+ {
+ /*
+ * H/W Q overflow, need to save the buffer
+ * back on the s/w Q.
+ * we must put it back on the head of the q to avoid
+ * reordering packet tx
+ */
+ TX_STATS_INC(portId,txFromSwQDelayed);
+ IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(
+ ixEthAccPortData[portId].ixEthAccTxData.txQ[priority],
+ mbuf);
+
+ /*enable Q notification*/
+ qStatus = ixQMgrNotificationEnable(
+ IX_ETH_ACC_PORT_TO_TX_Q_ID(portId),
+ IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(portId));
+
+ if (qStatus != IX_SUCCESS && qStatus != IX_QMGR_WARNING)
+ {
+ TX_INC(portId,txUnexpectedError);
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthAccTxFromSwQ:Unexpected Error: %u\n",
+ qStatus, 0, 0, 0, 0, 0);
+ }
+ }
+ else
+ {
+ TX_INC(portId,txUnexpectedError);
+
+ /* recovery attempt */
+ IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(
+ ixEthAccPortData[portId].ixEthAccTxData.txQ[priority],
+ mbuf);
+
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthAccTxFromSwQ:Error: unexpected QM status 0x%08X\n",
+ qStatus, 0, 0, 0, 0, 0);
+ }
+ }
+ else
+ {
+ /* sw queue is empty */
+ }
+ return IX_ETH_ACC_FAIL;
+}
+
+/**
+ *
+ * @brief This function will take a buffer from a RXfree S/W Q and attempt
+ * to add it to the relevant RxFree H/W Q
+ *
+ * @param portId - the port whose RXFree queue is to be written to
+ *
+ * @internal
+ */
+PRIVATE IxEthAccStatus
+ixEthAccRxFreeFromSwQ(IxEthAccPortId portId)
+{
+ IX_OSAL_MBUF *mbuf;
+ IX_STATUS qStatus = IX_SUCCESS;
+
+ IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD(
+ ixEthAccPortData[portId].ixEthAccRxData.freeBufferList,
+ mbuf);
+ if (mbuf != NULL)
+ {
+ /*
+ * Add The Rx Buffer to the H/W Free buffer Q if possible
+ */
+ qStatus = ixEthAccQmgrLockRxWrite(portId,
+ IX_OSAL_MMU_VIRT_TO_PHYS(
+ (UINT32)IX_ETHACC_NE_SHARED(mbuf)));
+
+ if (qStatus == IX_SUCCESS)
+ {
+ RX_STATS_INC(portId,rxFreeRepFromSwQOK);
+ /*
+ * Buffer added to h/w Q.
+ */
+ return IX_SUCCESS;
+ }
+ else if (qStatus == IX_QMGR_Q_OVERFLOW)
+ {
+ /*
+ * H/W Q overflow, need to save the buffer back on the s/w Q.
+ */
+ RX_STATS_INC(portId,rxFreeRepFromSwQDelayed);
+
+ IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(
+ ixEthAccPortData[portId].ixEthAccRxData.freeBufferList,
+ mbuf);
+ }
+ else
+ {
+ /* unexpected qmgr error */
+ RX_INC(portId,rxUnexpectedError);
+
+ IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(
+ ixEthAccPortData[portId].ixEthAccRxData.freeBufferList,
+ mbuf);
+
+ IX_ETH_ACC_FATAL_LOG("IxEthAccRxFreeFromSwQ:Error: unexpected QM status 0x%08X\n",
+ qStatus, 0, 0, 0, 0, 0);
+ }
+ }
+ else
+ {
+ /* sw queue is empty */
+ }
+ return IX_ETH_ACC_FAIL;
+}
+
+
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccInitDataPlane()
+{
+ UINT32 portId;
+
+ /*
+ * Initialize the service and register callback to other services.
+ */
+
+ IX_ETH_ACC_MEMSET(&ixEthAccDataStats,
+ 0,
+ sizeof(ixEthAccDataStats));
+
+ for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+ {
+ ixOsalFastMutexInit(&txWriteMutex[portId]);
+ ixOsalFastMutexInit(&rxWriteMutex[portId]);
+
+ IX_ETH_ACC_MEMSET(&ixEthAccPortData[portId],
+ 0,
+ sizeof(ixEthAccPortData[portId]));
+
+ ixEthAccPortData[portId].ixEthAccTxData.schDiscipline = FIFO_NO_PRIORITY;
+ }
+
+ return (IX_ETH_ACC_SUCCESS);
+}
+
+
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccPortTxDoneCallbackRegister(IxEthAccPortId portId,
+ IxEthAccPortTxDoneCallback
+ txCallbackFn,
+ UINT32 callbackTag)
+{
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+ if (!IX_ETH_ACC_IS_PORT_VALID(portId))
+ {
+ return (IX_ETH_ACC_INVALID_PORT);
+ }
+
+/* HACK: removing this code to enable NPE-A preliminary testing
+ * if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ * {
+ * IX_ETH_ACC_WARNING_LOG("ixEthAccPortTxDoneCallbackRegister: Unavailable Eth %d: Cannot register TxDone Callback.\n",(INT32)portId,0,0,0,0,0);
+ * return IX_ETH_ACC_SUCCESS ;
+ * }
+ */
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+ if (txCallbackFn == 0)
+ /* Check for null function pointer here. */
+ {
+ return (IX_ETH_ACC_INVALID_ARG);
+ }
+ ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = txCallbackFn;
+ ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = callbackTag;
+ return (IX_ETH_ACC_SUCCESS);
+}
+
+
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccPortRxCallbackRegister(IxEthAccPortId portId,
+ IxEthAccPortRxCallback
+ rxCallbackFn,
+ UINT32 callbackTag)
+{
+ IxEthAccPortId port;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+ if (!IX_ETH_ACC_IS_PORT_VALID(portId))
+ {
+ return (IX_ETH_ACC_INVALID_PORT);
+ }
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("ixEthAccPortRxCallbackRegister: Unavailable Eth %d: Cannot register Rx Callback.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ /* Check for null function pointer here. */
+ if (rxCallbackFn == NULL)
+ {
+ return (IX_ETH_ACC_INVALID_ARG);
+ }
+
+ /* Check the user is not changing the callback type
+ * when the port is enabled.
+ */
+ if (ixEthAccMacState[portId].portDisableState == ACTIVE)
+ {
+ for (port = 0; port < IX_ETH_ACC_NUMBER_OF_PORTS; port++)
+ {
+ if ((ixEthAccMacState[port].portDisableState == ACTIVE)
+ && (ixEthAccPortData[port].ixEthAccRxData.rxMultiBufferCallbackInUse == TRUE))
+ {
+ /* one of the active ports has a different rx callback type.
+ * Changing the callback type when the port is enabled
+ * is not safe
+ */
+ return (IX_ETH_ACC_INVALID_ARG);
+ }
+ }
+ }
+
+ /* update the callback pointer : this is done before
+ * registering the new qmgr callback
+ */
+ ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = rxCallbackFn;
+ ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = callbackTag;
+
+ /* update the qmgr callback for rx queues */
+ if (ixEthAccQMgrRxCallbacksRegister(ixEthRxFrameQMCallback)
+ != IX_ETH_ACC_SUCCESS)
+ {
+ /* unexpected qmgr error */
+ IX_ETH_ACC_FATAL_LOG("ixEthAccPortRxCallbackRegister: unexpected QMgr error, " \
+ "could not register Rx single-buffer callback\n", 0, 0, 0, 0, 0, 0);
+
+ RX_INC(portId,rxUnexpectedError);
+ return (IX_ETH_ACC_INVALID_ARG);
+ }
+
+ ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackInUse = FALSE;
+
+ return (IX_ETH_ACC_SUCCESS);
+}
+
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccPortMultiBufferRxCallbackRegister(
+ IxEthAccPortId portId,
+ IxEthAccPortMultiBufferRxCallback
+ rxCallbackFn,
+ UINT32 callbackTag)
+{
+ IxEthAccPortId port;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+ if (!IX_ETH_ACC_IS_PORT_VALID(portId))
+ {
+ return (IX_ETH_ACC_INVALID_PORT);
+ }
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("ixEthAccPortMultiBufferRxCallbackRegister: Unavailable Eth %d: Cannot register Rx Callback.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ /* Check for null function pointer here. */
+ if (rxCallbackFn == NULL)
+ {
+ return (IX_ETH_ACC_INVALID_ARG);
+ }
+
+ /* Check the user is not changing the callback type
+ * when the port is enabled.
+ */
+ if (ixEthAccMacState[portId].portDisableState == ACTIVE)
+ {
+ for (port = 0; port < IX_ETH_ACC_NUMBER_OF_PORTS; port++)
+ {
+ if ((ixEthAccMacState[port].portDisableState == ACTIVE)
+ && (ixEthAccPortData[port].ixEthAccRxData.rxMultiBufferCallbackInUse == FALSE))
+ {
+ /* one of the active ports has a different rx callback type.
+ * Changing the callback type when the port is enabled
+ * is not safe
+ */
+ return (IX_ETH_ACC_INVALID_ARG);
+ }
+ }
+ }
+
+ /* update the callback pointer : this is done before
+ * registering the new qmgr callback
+ */
+ ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = rxCallbackFn;
+ ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = callbackTag;
+
+ /* update the qmgr callback for rx queues */
+ if (ixEthAccQMgrRxCallbacksRegister(ixEthRxMultiBufferQMCallback)
+ != IX_ETH_ACC_SUCCESS)
+ {
+ /* unexpected qmgr error */
+ RX_INC(portId,rxUnexpectedError);
+
+ IX_ETH_ACC_FATAL_LOG("ixEthAccPortMultiBufferRxCallbackRegister: unexpected QMgr error, " \
+ "could not register Rx multi-buffer callback\n", 0, 0, 0, 0, 0, 0);
+
+ return (IX_ETH_ACC_INVALID_ARG);
+ }
+
+ ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackInUse = TRUE;
+
+ return (IX_ETH_ACC_SUCCESS);
+}
+
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccPortTxFrameSubmit(IxEthAccPortId portId,
+ IX_OSAL_MBUF *buffer,
+ IxEthAccTxPriority priority)
+{
+ IX_STATUS qStatus = IX_SUCCESS;
+ UINT32 qBuffer;
+ IxEthAccTxPriority highestPriority;
+ IxQMgrQStatus txQStatus;
+
+#ifndef NDEBUG
+ if (buffer == NULL)
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+ if (!IX_ETH_ACC_IS_PORT_VALID(portId))
+ {
+ return (IX_ETH_ACC_INVALID_PORT);
+ }
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_FATAL_LOG("ixEthAccPortTxFrameSubmit: Unavailable Eth %d: Cannot submit Tx Frame.\n",
+ (INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_PORT_UNINITIALIZED ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+ if ((UINT32)priority > (UINT32)IX_ETH_ACC_TX_PRIORITY_7)
+ {
+ return (IX_ETH_ACC_INVALID_ARG);
+ }
+#endif
+
+ /*
+ * Need to Flush the MBUF and its contents (data) as it may be
+ * read from the NPE. Convert virtual addresses to physical addresses also.
+ */
+ qBuffer = ixEthAccMbufTxQPrepare(buffer);
+
+ /*
+ * If no fifo priority set on Xscale ...
+ */
+ if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline ==
+ FIFO_NO_PRIORITY)
+ {
+ /*
+ * Add The Tx Buffer to the H/W Tx Q if possible
+ * (the priority is passed to the NPE, because
+ * the NPE is able to reorder the frames
+ * before transmission to the underlying hardware)
+ */
+ qStatus = ixEthAccQmgrTxWrite(portId,
+ qBuffer,
+ IX_ETH_ACC_TX_DEFAULT_PRIORITY);
+
+ if (qStatus == IX_SUCCESS)
+ {
+ TX_STATS_INC(portId,txQOK);
+
+ /*
+ * "best case" scenario : Buffer added to h/w Q.
+ */
+ return (IX_SUCCESS);
+ }
+ else if (qStatus == IX_QMGR_Q_OVERFLOW)
+ {
+ /*
+ * We were unable to write the buffer to the
+ * appropriate H/W Q, Save it in the sw Q.
+ * (use the default priority queue regardless of
+ * input parameter)
+ */
+ priority = IX_ETH_ACC_TX_DEFAULT_PRIORITY;
+ }
+ else
+ {
+ /* unexpected qmgr error */
+ TX_INC(portId,txUnexpectedError);
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthAccPortTxFrameSubmit:Error: qStatus = %u\n",
+ (UINT32)qStatus, 0, 0, 0, 0, 0);
+ return (IX_ETH_ACC_FAIL);
+ }
+ }
+ else if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline ==
+ FIFO_PRIORITY)
+ {
+
+ /*
+ * For priority transmission, put the frame directly on the H/W queue
+ * if the H/W queue is empty, otherwise, put it in a S/W Q
+ */
+ ixQMgrQStatusGet(IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), &txQStatus);
+ if((txQStatus & IX_QMGR_Q_STATUS_E_BIT_MASK) != 0)
+ {
+ /*The tx queue is empty, check whether there are buffers on the s/w queues*/
+ if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority)
+ !=IX_ETH_ACC_FAIL)
+ {
+ /*there are buffers on the s/w queues, submit them*/
+ ixEthAccTxFromSwQ(portId, highestPriority);
+
+ /* the queue was empty, 1 buffer is already supplied
+ * but is likely to be immediately transmitted and the
+ * hw queue is likely to be empty again, so submit
+ * more from the sw queues
+ */
+ if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority)
+ !=IX_ETH_ACC_FAIL)
+ {
+ ixEthAccTxFromSwQ(portId, highestPriority);
+ /*
+ * and force the buffer supplied to be placed
+ * on a priority queue
+ */
+ qStatus = IX_QMGR_Q_OVERFLOW;
+ }
+ else
+ {
+ /*there are no buffers in the s/w queues, submit directly*/
+ qStatus = ixEthAccQmgrTxWrite(portId, qBuffer, priority);
+ }
+ }
+ else
+ {
+ /*there are no buffers in the s/w queues, submit directly*/
+ qStatus = ixEthAccQmgrTxWrite(portId, qBuffer, priority);
+ }
+ }
+ else
+ {
+ qStatus = IX_QMGR_Q_OVERFLOW;
+ }
+ }
+ else
+ {
+ TX_INC(portId,txUnexpectedError);
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthAccPortTxFrameSubmit:Error: wrong schedule discipline setup\n",
+ 0, 0, 0, 0, 0, 0);
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ if(qStatus == IX_SUCCESS )
+ {
+ TX_STATS_INC(portId,txQOK);
+ return IX_ETH_ACC_SUCCESS;
+ }
+ else if(qStatus == IX_QMGR_Q_OVERFLOW)
+ {
+ TX_STATS_INC(portId,txQDelayed);
+ /*
+ * We were unable to write the buffer to the
+ * appropriate H/W Q, Save it in a s/w Q.
+ */
+ IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL(
+ ixEthAccPortData[portId].
+ ixEthAccTxData.txQ[priority],
+ buffer);
+
+ qStatus = ixQMgrNotificationEnable(
+ IX_ETH_ACC_PORT_TO_TX_Q_ID(portId),
+ IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(portId));
+
+ if (qStatus != IX_SUCCESS)
+ {
+ if (qStatus == IX_QMGR_WARNING)
+ {
+ /* notification is enabled for a queue
+ * which is already empty (the condition is already met)
+ * and there will be no more queue event to drain the sw queue
+ */
+ TX_STATS_INC(portId,txLateNotificationEnabled);
+
+ /* pull a buffer from the sw queue */
+ if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority)
+ !=IX_ETH_ACC_FAIL)
+ {
+ /*there are buffers on the s/w queues, submit from them*/
+ ixEthAccTxFromSwQ(portId, highestPriority);
+ }
+ }
+ else
+ {
+ TX_INC(portId,txUnexpectedError);
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthAccPortTxFrameSubmit: unexpected Error: %u\n",
+ qStatus, 0, 0, 0, 0, 0);
+ }
+ }
+ }
+ else
+ {
+ TX_INC(portId,txUnexpectedError);
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthAccPortTxFrameSubmit: unexpected Error: %u\n",
+ qStatus, 0, 0, 0, 0, 0);
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ return (IX_ETH_ACC_SUCCESS);
+}
+
+
+/**
+ *
+ * @brief replenish: convert a chain of mbufs to the format
+ * expected by the NPE
+ *
+ */
+
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccPortRxFreeReplenish(IxEthAccPortId portId,
+ IX_OSAL_MBUF *buffer)
+{
+ IX_STATUS qStatus = IX_SUCCESS;
+ UINT32 qBuffer;
+
+ /*
+ * Check buffer is valid.
+ */
+
+#ifndef NDEBUG
+ /* check parameter value */
+ if (buffer == 0)
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+ if (!IX_ETH_ACC_IS_PORT_VALID(portId))
+ {
+ return (IX_ETH_ACC_INVALID_PORT);
+ }
+
+ /* check initialisation is done */
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_FATAL_LOG(" ixEthAccPortRxFreeReplenish: Unavailable Eth %d: Cannot replenish Rx Free Q.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_PORT_UNINITIALIZED ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+ /* check boundaries and constraints */
+ if (IX_OSAL_MBUF_MLEN(buffer) < IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN)
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+#endif
+
+ qBuffer = ixEthAccMbufRxQPrepare(buffer);
+
+ /*
+ * Add The Rx Buffer to the H/W Free buffer Q if possible
+ */
+ qStatus = ixEthAccQmgrLockRxWrite(portId, qBuffer);
+
+ if (qStatus == IX_SUCCESS)
+ {
+ RX_STATS_INC(portId,rxFreeRepOK);
+ /*
+ * Buffer added to h/w Q.
+ */
+ return (IX_SUCCESS);
+ }
+ else if (qStatus == IX_QMGR_Q_OVERFLOW)
+ {
+ RX_STATS_INC(portId,rxFreeRepDelayed);
+ /*
+ * We were unable to write the buffer to the approprate H/W Q,
+ * Save it in a s/w Q.
+ */
+ IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL(
+ ixEthAccPortData[portId].ixEthAccRxData.freeBufferList,
+ buffer);
+
+ qStatus = ixQMgrNotificationEnable(
+ IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId),
+ IX_ETH_ACC_PORT_TO_RX_FREE_Q_SOURCE(portId));
+
+ if (qStatus != IX_SUCCESS)
+ {
+ if (qStatus == IX_QMGR_WARNING)
+ {
+ /* notification is enabled for a queue
+ * which is already empty (the condition is already met)
+ * and there will be no more queue event to drain the sw queue
+ * move an entry from the sw queue to the hw queue */
+ RX_STATS_INC(portId,rxFreeLateNotificationEnabled);
+ ixEthAccRxFreeFromSwQ(portId);
+ }
+ else
+ {
+ RX_INC(portId,rxUnexpectedError);
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthAccRxPortFreeReplenish:Error: %u\n",
+ qStatus, 0, 0, 0, 0, 0);
+ }
+ }
+ }
+ else
+ {
+ RX_INC(portId,rxUnexpectedError);
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthAccRxPortFreeReplenish:Error: qStatus = %u\n",
+ (UINT32)qStatus, 0, 0, 0, 0, 0);
+ return(IX_ETH_ACC_FAIL);
+ }
+ return (IX_ETH_ACC_SUCCESS);
+}
+
+
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccTxSchedulingDisciplineSetPriv(IxEthAccPortId portId,
+ IxEthAccSchedulerDiscipline
+ sched)
+{
+ if (!IX_ETH_ACC_IS_PORT_VALID(portId))
+ {
+ return (IX_ETH_ACC_INVALID_PORT);
+ }
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("ixEthAccTxSchedulingDisciplineSet: Unavailable Eth %d: Cannot set Tx Scheduling Discipline.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ if (sched != FIFO_PRIORITY && sched != FIFO_NO_PRIORITY)
+ {
+ return (IX_ETH_ACC_INVALID_ARG);
+ }
+
+ ixEthAccPortData[portId].ixEthAccTxData.schDiscipline = sched;
+ return (IX_ETH_ACC_SUCCESS);
+}
+
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccRxSchedulingDisciplineSetPriv(IxEthAccSchedulerDiscipline
+ sched)
+{
+ if (sched != FIFO_PRIORITY && sched != FIFO_NO_PRIORITY)
+ {
+ return (IX_ETH_ACC_INVALID_ARG);
+ }
+
+ ixEthAccDataInfo.schDiscipline = sched;
+
+ return (IX_ETH_ACC_SUCCESS);
+}
+
+
+/**
+ * @fn ixEthRxFrameProcess(IxEthAccPortId portId, IX_OSAL_MBUF *mbufPtr)
+ *
+ * @brief process incoming frame :
+ *
+ * @param @ref IxQMgrCallback IxQMgrMultiBufferCallback
+ *
+ * @return none
+ *
+ * @internal
+ *
+ */
+IX_ETH_ACC_PRIVATE BOOL
+ixEthRxFrameProcess(IxEthAccPortId portId, IX_OSAL_MBUF *mbufPtr)
+{
+ UINT32 flags;
+ IxEthDBStatus result;
+
+#ifndef NDEBUG
+ /* Prudent to at least check the port is within range */
+ if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
+ {
+ ixEthAccDataStats.unexpectedError++;
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthRxFrameProcess: Illegal port: %u\n",
+ (UINT32)portId, 0, 0, 0, 0, 0);
+ return FALSE;
+ }
+#endif
+
+ /* convert fields from mbuf header */
+ ixEthAccMbufFromRxQ(mbufPtr);
+
+ /* check about any special processing for this frame */
+ flags = IX_ETHACC_NE_FLAGS(mbufPtr);
+ if ((flags & (IX_ETHACC_NE_FILTERMASK | IX_ETHACC_NE_NEWSRCMASK)) == 0)
+ {
+ /* "best case" scenario : nothing special to do for this frame */
+ return TRUE;
+ }
+
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+ /* if a new source MAC address is detected by the NPE,
+ * update IxEthDB with the portId and the MAC address.
+ */
+ if ((flags & IX_ETHACC_NE_NEWSRCMASK & ixEthAccNewSrcMask) != 0)
+ {
+ result = ixEthDBFilteringDynamicEntryProvision(portId,
+ (IxEthDBMacAddr *) IX_ETHACC_NE_SOURCEMAC(mbufPtr));
+
+ if (result != IX_ETH_DB_SUCCESS && result != IX_ETH_DB_FEATURE_UNAVAILABLE)
+ {
+ if ((ixEthAccMacState[portId].portDisableState == ACTIVE) && (result != IX_ETH_DB_BUSY))
+ {
+ RX_STATS_INC(portId, rxUnexpectedError);
+ IX_ETH_ACC_FATAL_LOG("ixEthRxFrameProcess: Failed to add source MAC \
+ to the Learning/Filtering database\n", 0, 0, 0, 0, 0, 0);
+ }
+ else
+ {
+ /* we expect this to fail during PortDisable, as EthDB is disabled for
+ * that port and will refuse to learn new addresses
+ */
+ }
+ }
+ else
+ {
+ RX_STATS_INC(portId, rxUnlearnedMacAddress);
+ }
+ }
+#endif
+
+ /* check if this frame should have been filtered
+ * by the NPE and take the appropriate action
+ */
+ if (((flags & IX_ETHACC_NE_FILTERMASK) != 0)
+ && (ixEthAccMacState[portId].portDisableState == ACTIVE))
+ {
+ /* If the mbuf was allocated with a small data size, or the current data pointer is not
+ * within the allocated data area, then the buffer is non-standard and has to be
+ * replenished with the minimum size only
+ */
+ if( (IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr) < IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN)
+ || ((UINT8 *)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr) > IX_OSAL_MBUF_MDATA(mbufPtr))
+ || ((UINT8 *)(IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr) +
+ IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr))
+ < IX_OSAL_MBUF_MDATA(mbufPtr)) )
+ {
+ /* set to minimum length */
+ IX_OSAL_MBUF_MLEN(mbufPtr) = IX_OSAL_MBUF_PKT_LEN(mbufPtr) =
+ IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN;
+ }
+ else
+ {
+ /* restore original length */
+ IX_OSAL_MBUF_MLEN(mbufPtr) = IX_OSAL_MBUF_PKT_LEN(mbufPtr) =
+ ( IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr) -
+ (IX_OSAL_MBUF_MDATA(mbufPtr) - (UINT8 *)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr)) );
+ }
+
+ /* replenish from here */
+ if (ixEthAccPortRxFreeReplenish(portId, mbufPtr) != IX_ETH_ACC_SUCCESS)
+ {
+ IX_ETH_ACC_FATAL_LOG("ixEthRxFrameProcess: Failed to replenish with filtered frame\
+ on port %d\n", portId, 0, 0, 0, 0, 0);
+ }
+
+ RX_STATS_INC(portId, rxFiltered);
+
+ /* indicate that frame should not be subjected to further processing */
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/**
+ * @fn ixEthRxFrameQMCallback
+ *
+ * @brief receive callback for Frame receive Q from NPE
+ *
+ * Frames are passed one-at-a-time to the user
+ *
+ * @param @ref IxQMgrCallback
+ *
+ * @return none
+ *
+ * @internal
+ *
+ * Design note : while processing the entry X, entry X+1 is preloaded
+ * into memory to reduce the number of stall cycles
+ *
+ */
+void ixEthRxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId)
+{
+ IX_OSAL_MBUF *mbufPtr;
+ IX_OSAL_MBUF *nextMbufPtr;
+ UINT32 qEntry;
+ UINT32 nextQEntry;
+ UINT32 *qEntryPtr;
+ UINT32 portId;
+ UINT32 destPortId;
+ UINT32 npeId;
+ UINT32 rxQReadStatus;
+
+ /*
+ * Design note : entries are read in a buffer, This buffer contains
+ * an extra zeroed entry so the loop will
+ * always terminate on a null entry, whatever the result of Burst read is.
+ */
+ UINT32 rxQEntry[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1];
+
+ /*
+ * Indication of the number of times the callback is used.
+ */
+ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackCounter);
+
+ do
+ {
+ /*
+ * Indication of the number of times the queue is drained
+ */
+ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackBurstRead);
+
+ /* ensure the last entry of the array contains a zeroed value */
+ qEntryPtr = rxQEntry;
+ qEntryPtr[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK] = 0;
+
+ rxQReadStatus = ixQMgrQBurstRead(qId,
+ IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK,
+ qEntryPtr);
+
+#ifndef NDEBUG
+ if ((rxQReadStatus != IX_QMGR_Q_UNDERFLOW)
+ && (rxQReadStatus != IX_SUCCESS))
+ {
+ ixEthAccDataStats.unexpectedError++;
+ /*major error*/
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthRxFrameQMCallback:Error: %u\n",
+ (UINT32)rxQReadStatus, 0, 0, 0, 0, 0);
+ return;
+ }
+#endif
+
+ /* convert and preload the next entry
+ * (the conversion function takes care about null pointers which
+ * are used to mark the end of the loop)
+ */
+ nextQEntry = *qEntryPtr;
+ nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry,
+ IX_ETHNPE_QM_Q_RXENET_ADDR_MASK);
+
+ while(nextQEntry != 0)
+ {
+ /* get the next entry */
+ qEntry = nextQEntry;
+ mbufPtr = nextMbufPtr;
+
+#ifndef NDEBUG
+ if (mbufPtr == NULL)
+ {
+ ixEthAccDataStats.unexpectedError++;
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthRxFrameQMCallback: Null Mbuf Ptr\n",
+ 0, 0, 0, 0, 0, 0);
+ return;
+ }
+#endif
+
+ /* convert the next entry
+ * (the conversion function takes care about null pointers which
+ * are used to mark the end of the loop)
+ */
+ nextQEntry = *(++qEntryPtr);
+ nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry,
+ IX_ETHNPE_QM_Q_RXENET_ADDR_MASK);
+
+ /*
+ * Get Port and Npe ID from message.
+ */
+ npeId = ((IX_ETHNPE_QM_Q_RXENET_NPEID_MASK &
+ qEntry) >> IX_ETHNPE_QM_Q_FIELD_NPEID_R);
+ portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
+
+ /* process frame, check the return code and skip the remaining of
+ * the loop if the frame is to be filtered out
+ */
+ if (ixEthRxFrameProcess(portId, mbufPtr))
+ {
+ /* destination portId for this packet */
+ destPortId = IX_ETHACC_NE_DESTPORTID(mbufPtr);
+
+ if (destPortId != IX_ETH_DB_UNKNOWN_PORT)
+ {
+ destPortId = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(destPortId);
+ }
+
+ /* test if QoS is enabled in ethAcc
+ */
+ if (ixEthAccDataInfo.schDiscipline == FIFO_PRIORITY)
+ {
+ /* check if there is a higher priority queue
+ * which may require processing and then process it.
+ */
+ if (ixEthAccDataInfo.higherPriorityQueue[qId] < IX_QMGR_MAX_NUM_QUEUES)
+ {
+ ixEthRxFrameQMCallback(ixEthAccDataInfo.higherPriorityQueue[qId],
+ callbackId);
+ }
+ }
+
+ /*
+ * increment priority stats
+ */
+ RX_STATS_INC(portId,rxPriority[IX_ETHACC_NE_QOS(mbufPtr)]);
+
+ /*
+ * increment callback count stats
+ */
+ RX_STATS_INC(portId,rxFrameClientCallback);
+
+ /*
+ * Call user level callback.
+ */
+ ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn(
+ ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag,
+ mbufPtr,
+ destPortId);
+ }
+ }
+ } while (rxQReadStatus == IX_SUCCESS);
+}
+
+/**
+ * @fn ixEthRxMultiBufferQMCallback
+ *
+ * @brief receive callback for Frame receive Q from NPE
+ *
+ * Frames are passed as an array to the user
+ *
+ * @param @ref IxQMgrCallback
+ *
+ * @return none
+ *
+ * @internal
+ *
+ * Design note : while processing the entry X, entry X+1 is preloaded
+ * into memory to reduce the number of stall cycles
+ *
+ */
+void ixEthRxMultiBufferQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId)
+{
+ IX_OSAL_MBUF *mbufPtr;
+ IX_OSAL_MBUF *nextMbufPtr;
+ UINT32 qEntry;
+ UINT32 nextQEntry;
+ UINT32 *qEntryPtr;
+ UINT32 portId;
+ UINT32 npeId;
+ UINT32 rxQReadStatus;
+ /*
+ * Design note : entries are read in a static buffer, This buffer contains
+ * an extra zeroed entry so the loop will
+ * always terminate on a null entry, whatever the result of Burst read is.
+ */
+ static UINT32 rxQEntry[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1];
+ static IX_OSAL_MBUF *rxMbufPortArray[IX_ETH_ACC_NUMBER_OF_PORTS][IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1];
+ IX_OSAL_MBUF **rxMbufPtr[IX_ETH_ACC_NUMBER_OF_PORTS];
+
+ for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+ {
+ rxMbufPtr[portId] = rxMbufPortArray[portId];
+ }
+
+ /*
+ * Indication of the number of times the callback is used.
+ */
+ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackCounter);
+
+ do
+ {
+ /*
+ * Indication of the number of times the queue is drained
+ */
+ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackBurstRead);
+
+ /* ensure the last entry of the array contains a zeroed value */
+ qEntryPtr = rxQEntry;
+ qEntryPtr[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK] = 0;
+
+ rxQReadStatus = ixQMgrQBurstRead(qId,
+ IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK,
+ qEntryPtr);
+
+#ifndef NDEBUG
+ if ((rxQReadStatus != IX_QMGR_Q_UNDERFLOW)
+ && (rxQReadStatus != IX_SUCCESS))
+ {
+ ixEthAccDataStats.unexpectedError++;
+ /*major error*/
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthRxFrameMultiBufferQMCallback:Error: %u\n",
+ (UINT32)rxQReadStatus, 0, 0, 0, 0, 0);
+ return;
+ }
+#endif
+
+ /* convert and preload the next entry
+ * (the conversion function takes care about null pointers which
+ * are used to mark the end of the loop)
+ */
+ nextQEntry = *qEntryPtr;
+ nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry,
+ IX_ETHNPE_QM_Q_RXENET_ADDR_MASK);
+
+ while(nextQEntry != 0)
+ {
+ /* get the next entry */
+ qEntry = nextQEntry;
+ mbufPtr = nextMbufPtr;
+
+#ifndef NDEBUG
+ if (mbufPtr == NULL)
+ {
+ ixEthAccDataStats.unexpectedError++;
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthRxFrameMultiBufferQMCallback:Error: Null Mbuf Ptr\n",
+ 0, 0, 0, 0, 0, 0);
+ return;
+ }
+#endif
+
+ /* convert the next entry
+ * (the conversion function takes care about null pointers which
+ * are used to mark the end of the loop)
+ */
+ nextQEntry = *(++qEntryPtr);
+ nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry,
+ IX_ETHNPE_QM_Q_RXENET_ADDR_MASK);
+
+ /*
+ * Get Port and Npe ID from message.
+ */
+ npeId = ((IX_ETHNPE_QM_Q_RXENET_NPEID_MASK &
+ qEntry) >>
+ IX_ETHNPE_QM_Q_FIELD_NPEID_R);
+ portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
+
+ /* skip the remaining of the loop if the frame is
+ * to be filtered out
+ */
+ if (ixEthRxFrameProcess(portId, mbufPtr))
+ {
+ /* store a mbuf pointer in an array */
+ *rxMbufPtr[portId]++ = mbufPtr;
+
+ /*
+ * increment priority stats
+ */
+ RX_STATS_INC(portId,rxPriority[IX_ETHACC_NE_QOS(mbufPtr)]);
+ }
+
+ /* test for QoS enabled in ethAcc */
+ if (ixEthAccDataInfo.schDiscipline == FIFO_PRIORITY)
+ {
+ /* check if there is a higher priority queue
+ * which may require processing and then process it.
+ */
+ if (ixEthAccDataInfo.higherPriorityQueue[qId] < IX_QMGR_MAX_NUM_QUEUES)
+ {
+ ixEthRxMultiBufferQMCallback(ixEthAccDataInfo.higherPriorityQueue[qId],
+ callbackId);
+ }
+ }
+ }
+
+ /* check if any of the the arrays contains any entry */
+ for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+ {
+ if (rxMbufPtr[portId] != rxMbufPortArray[portId])
+ {
+ /* add a last NULL pointer at the end of the
+ * array of mbuf pointers
+ */
+ *rxMbufPtr[portId] = NULL;
+
+ /*
+ * increment callback count stats
+ */
+ RX_STATS_INC(portId,rxFrameClientCallback);
+
+ /*
+ * Call user level callback with an array of
+ * buffers (NULL terminated)
+ */
+ ixEthAccPortData[portId].ixEthAccRxData.
+ rxMultiBufferCallbackFn(
+ ixEthAccPortData[portId].ixEthAccRxData.
+ rxMultiBufferCallbackTag,
+ rxMbufPortArray[portId]);
+
+ /* reset the buffer pointer to the beginning of
+ * the array
+ */
+ rxMbufPtr[portId] = rxMbufPortArray[portId];
+ }
+ }
+
+ } while (rxQReadStatus == IX_SUCCESS);
+}
+
+
+/**
+ * @brief rxFree low event handler
+ *
+ */
+void ixEthRxFreeQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId)
+{
+ IxEthAccPortId portId = (IxEthAccPortId) callbackId;
+ int lockVal;
+ UINT32 maxQWritesToPerform = IX_ETH_ACC_MAX_RX_FREE_BUFFERS_LOAD;
+ IX_STATUS qStatus = IX_SUCCESS;
+
+ /*
+ * We have reached a low threshold on one of the Rx Free Qs
+ */
+
+ /*note that due to the fact that we are working off an Empty threshold, this callback
+ need only write a single entry to the Rx Free queue in order to re-arm the notification
+ */
+
+ RX_STATS_INC(portId,rxFreeLowCallback);
+
+ /*
+ * Get buffers from approprite S/W Rx freeBufferList Q.
+ */
+
+#ifndef NDEBUG
+ if (!IX_ETH_ACC_IS_PORT_VALID(portId))
+ {
+ ixEthAccDataStats.unexpectedError++;
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthRxFreeQMCallback:Error: Invalid Port 0x%08X\n",
+ portId, 0, 0, 0, 0, 0);
+ return;
+ }
+#endif
+ IX_ETH_ACC_DATA_PLANE_LOCK(lockVal);
+ if (IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId].
+ ixEthAccRxData.freeBufferList))
+ {
+ /*
+ * Turn off Q callback notification for Q in Question.
+ */
+ qStatus = ixQMgrNotificationDisable(
+ IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId));
+
+
+ IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);
+
+ if (qStatus != IX_SUCCESS)
+ {
+ RX_INC(portId,rxUnexpectedError);
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthRxFreeQMCallback:Error: unexpected QM status 0x%08X\n",
+ qStatus, 0, 0, 0, 0, 0);
+ return;
+ }
+ }
+ else
+ {
+ IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);
+ /*
+ * Load the H/W Q with buffers from the s/w Q.
+ */
+
+ do
+ {
+ /*
+ * Consume Q entries. - Note Q contains Physical addresss,
+ * and have already been flushed to memory,
+ * And endianess converted if required.
+ */
+ if (ixEthAccRxFreeFromSwQ(portId) != IX_SUCCESS)
+ {
+ /*
+ * No more entries in s/w Q.
+ * Turn off Q callback indication
+ */
+
+ IX_ETH_ACC_DATA_PLANE_LOCK(lockVal);
+ if (IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId].
+ ixEthAccRxData.freeBufferList))
+ {
+ qStatus = ixQMgrNotificationDisable(
+ IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId));
+ }
+ IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);
+ break;
+ }
+ }
+ while (--maxQWritesToPerform);
+ }
+}
+/**
+ * @fn Tx queue low event handler
+ *
+ */
+void
+ixEthTxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId)
+{
+ IxEthAccPortId portId = (IxEthAccPortId) callbackId;
+ int lockVal;
+ UINT32 maxQWritesToPerform = IX_ETH_ACC_MAX_TX_FRAME_TX_CONSUME_PER_CALLBACK;
+ IX_STATUS qStatus = IX_SUCCESS;
+ IxEthAccTxPriority highestPriority;
+
+
+ /*
+ * We have reached a low threshold on the Tx Q, and are being asked to
+ * supply a buffer for transmission from our S/W TX queues
+ */
+ TX_STATS_INC(portId,txLowThreshCallback);
+
+ /*
+ * Get buffers from approprite Q.
+ */
+
+#ifndef NDEBUG
+ if (!IX_ETH_ACC_IS_PORT_VALID(portId))
+ {
+ ixEthAccDataStats.unexpectedError++;
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthTxFrameQMCallback:Error: Invalid Port 0x%08X\n",
+ portId, 0, 0, 0, 0, 0);
+ return;
+ }
+#endif
+
+ do
+ {
+ /*
+ * Consume Q entries. - Note Q contains Physical addresss,
+ * and have already been flushed to memory,
+ * and endianess already sone if required.
+ */
+
+ IX_ETH_ACC_DATA_PLANE_LOCK(lockVal);
+
+ if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) ==
+ IX_ETH_ACC_FAIL)
+ {
+ /*
+ * No more entries in s/w Q.
+ * Turn off Q callback indication
+ */
+ qStatus = ixQMgrNotificationDisable(
+ IX_ETH_ACC_PORT_TO_TX_Q_ID(portId));
+
+ IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);
+
+ if (qStatus != IX_SUCCESS)
+ {
+ ixEthAccDataStats.unexpectedError++;
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthTxFrameQMCallback:Error: unexpected QM status 0x%08X\n",
+ qStatus, 0, 0, 0, 0, 0);
+ }
+
+ return;
+ }
+ else
+ {
+ IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);
+ if (ixEthAccTxFromSwQ(portId,highestPriority)!=IX_SUCCESS)
+ {
+ /* nothing left in the sw queue or the hw queues are
+ * full. There is no point to continue to drain the
+ * sw queues
+ */
+ return;
+ }
+ }
+ }
+ while (--maxQWritesToPerform);
+}
+
+/**
+ * @brief TxDone event handler
+ *
+ * Design note : while processing the entry X, entry X+1 is preloaded
+ * into memory to reduce the number of stall cycles
+ *
+ */
+
+void
+ixEthTxFrameDoneQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId)
+{
+ IX_OSAL_MBUF *mbufPtr;
+ UINT32 qEntry;
+ UINT32 *qEntryPtr;
+ UINT32 txDoneQReadStatus;
+ UINT32 portId;
+ UINT32 npeId;
+
+ /*
+ * Design note : entries are read in a static buffer, This buffer contains
+ * an extra entyry (which is zeroed by the compiler), so the loop will
+ * always terminate on a null entry, whatever the result of Burst read is.
+ */
+ static UINT32 txDoneQEntry[IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK + 1];
+
+ /*
+ * Indication that Tx frames have been transmitted from the NPE.
+ */
+
+ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.txDoneCallbackCounter);
+
+ do{
+ qEntryPtr = txDoneQEntry;
+ txDoneQReadStatus = ixQMgrQBurstRead(IX_ETH_ACC_TX_FRAME_DONE_ETH_Q,
+ IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK,
+ qEntryPtr);
+
+#ifndef NDEBUG
+ if (txDoneQReadStatus != IX_QMGR_Q_UNDERFLOW
+ && (txDoneQReadStatus != IX_SUCCESS))
+ {
+ /*major error*/
+ ixEthAccDataStats.unexpectedError++;
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthTxFrameDoneQMCallback:Error: %u\n",
+ (UINT32)txDoneQReadStatus, 0, 0, 0, 0, 0);
+ return;
+ }
+#endif
+
+ qEntry = *qEntryPtr;
+
+ while(qEntry != 0)
+ {
+ mbufPtr = ixEthAccEntryFromQConvert(qEntry,
+ IX_ETHNPE_QM_Q_TXENET_ADDR_MASK);
+
+#ifndef NDEBUG
+ if (mbufPtr == NULL)
+ {
+ ixEthAccDataStats.unexpectedError++;
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthTxFrameDoneQMCallback:Error: Null Mbuf Ptr\n",
+ 0, 0, 0, 0, 0, 0);
+ return;
+ }
+#endif
+
+ /* endianness conversions and stats updates */
+ ixEthAccMbufFromTxQ(mbufPtr);
+
+ /*
+ * Get NPE id from message, then convert to portId.
+ */
+ npeId = ((IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK &
+ qEntry) >>
+ IX_ETHNPE_QM_Q_FIELD_NPEID_R);
+ portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
+
+#ifndef NDEBUG
+ /* Prudent to at least check the port is within range */
+ if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
+ {
+ ixEthAccDataStats.unexpectedError++;
+ IX_ETH_ACC_FATAL_LOG(
+ "ixEthTxFrameDoneQMCallback: Illegal port: %u\n",
+ (UINT32)portId, 0, 0, 0, 0, 0);
+ return;
+ }
+#endif
+
+ TX_STATS_INC(portId,txDoneClientCallback);
+
+ /*
+ * Call user level callback.
+ */
+ ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn(
+ ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag,
+ mbufPtr);
+
+ /* move to next queue entry */
+ qEntry = *(++qEntryPtr);
+
+ }
+ } while( txDoneQReadStatus == IX_SUCCESS );
+}
+
+IX_ETH_ACC_PUBLIC
+void ixEthAccDataPlaneShow(void)
+{
+ UINT32 numTx0Entries;
+ UINT32 numTx1Entries;
+ UINT32 numTxDoneEntries;
+ UINT32 numRxEntries;
+ UINT32 numRxFree0Entries;
+ UINT32 numRxFree1Entries;
+ UINT32 portId;
+#ifdef __ixp46X
+ UINT32 numTx2Entries;
+ UINT32 numRxFree2Entries;
+#endif
+#ifndef NDEBUG
+ UINT32 priority;
+ UINT32 numBuffersInRx=0;
+ UINT32 numBuffersInTx=0;
+ UINT32 numBuffersInSwQ=0;
+ UINT32 totalBuffers=0;
+ UINT32 rxFreeCallbackCounter = 0;
+ UINT32 txCallbackCounter = 0;
+#endif
+ UINT32 key;
+
+ /* snapshot of stats */
+ IxEthAccTxDataStats tx[IX_ETH_ACC_NUMBER_OF_PORTS];
+ IxEthAccRxDataStats rx[IX_ETH_ACC_NUMBER_OF_PORTS];
+ IxEthAccDataPlaneStats stats;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return;
+ }
+
+ /* get a reliable snapshot */
+ key = ixOsalIrqLock();
+
+ numTx0Entries = 0;
+ ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET0_Q, &numTx0Entries);
+ numTx1Entries = 0;
+ ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET1_Q, &numTx1Entries);
+ numTxDoneEntries = 0;
+ ixQMgrQNumEntriesGet( IX_ETH_ACC_TX_FRAME_DONE_ETH_Q, &numTxDoneEntries);
+ numRxEntries = 0;
+ ixEthAccQMgrRxQEntryGet(&numRxEntries);
+ numRxFree0Entries = 0;
+ ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q, &numRxFree0Entries);
+ numRxFree1Entries = 0;
+ ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q, &numRxFree1Entries);
+
+#ifdef __ixp46X
+ numTx2Entries = 0;
+ ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET2_Q, &numTx2Entries);
+ numRxFree2Entries = 0;
+ ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q, &numRxFree2Entries);
+#endif
+
+ for(portId=IX_ETH_PORT_1; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+ {
+ memcpy(&tx[portId],
+ &ixEthAccPortData[portId].ixEthAccTxData.stats,
+ sizeof(tx[portId]));
+ memcpy(&rx[portId],
+ &ixEthAccPortData[portId].ixEthAccRxData.stats,
+ sizeof(rx[portId]));
+ }
+ memcpy(&stats, &ixEthAccDataStats, sizeof(stats));
+
+ ixOsalIrqUnlock(key);
+
+#ifdef NDEBUG
+ printf("Detailed statistics collection not supported in this load\n");
+#endif
+
+ /* print snapshot */
+ for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+ {
+ /* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */
+ if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+ (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+ || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+ {
+ if ((IX_ETH_PORT_1 == portId) &&
+ (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED))
+ {
+ continue ;
+ }
+ if ((IX_ETH_PORT_2 == portId) &&
+ (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED))
+ {
+ continue ;
+ }
+ if ((IX_ETH_PORT_3 == portId) &&
+ (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) ==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED))
+ {
+ continue ;
+ }
+ }
+
+ printf("PORT %u --------------------------------\n",
+ portId);
+#ifndef NDEBUG
+ printf("Tx Done Frames : %u\n",
+ tx[portId].txDoneClientCallback +
+ tx[portId].txDoneSwQDuringDisable +
+ tx[portId].txDoneDuringDisable);
+ printf("Tx Frames : %u\n",
+ tx[portId].txQOK + tx[portId].txQDelayed);
+ printf("Tx H/W Q Added OK : %u\n",
+ tx[portId].txQOK);
+ printf("Tx H/W Q Delayed : %u\n",
+ tx[portId].txQDelayed);
+ printf("Tx From S/W Q Added OK : %u\n",
+ tx[portId].txFromSwQOK);
+ printf("Tx From S/W Q Delayed : %u\n",
+ tx[portId].txFromSwQDelayed);
+ printf("Tx Overflow : %u\n",
+ tx[portId].txOverflow);
+ printf("Tx Mutual Lock : %u\n",
+ tx[portId].txLock);
+ printf("Tx Late Ntf Enabled : %u\n",
+ tx[portId].txLateNotificationEnabled);
+ printf("Tx Low Thresh CB : %u\n",
+ tx[portId].txLowThreshCallback);
+ printf("Tx Done from H/W Q (Disable) : %u\n",
+ tx[portId].txDoneDuringDisable);
+ printf("Tx Done from S/W Q (Disable) : %u\n",
+ tx[portId].txDoneSwQDuringDisable);
+ for (priority = IX_ETH_ACC_TX_PRIORITY_0;
+ priority <= IX_ETH_ACC_TX_PRIORITY_7;
+ priority++)
+ {
+ if (tx[portId].txPriority[priority])
+ {
+ printf("Tx Priority %u : %u\n",
+ priority,
+ tx[portId].txPriority[priority]);
+ }
+ }
+#endif
+ printf("Tx unexpected errors : %u (should be 0)\n",
+ tx[portId].txUnexpectedError);
+
+#ifndef NDEBUG
+ printf("Rx Frames : %u\n",
+ rx[portId].rxFrameClientCallback +
+ rx[portId].rxSwQDuringDisable+
+ rx[portId].rxDuringDisable);
+ printf("Rx Free Replenish : %u\n",
+ rx[portId].rxFreeRepOK + rx[portId].rxFreeRepDelayed);
+ printf("Rx Free H/W Q Added OK : %u\n",
+ rx[portId].rxFreeRepOK);
+ printf("Rx Free H/W Q Delayed : %u\n",
+ rx[portId].rxFreeRepDelayed);
+ printf("Rx Free From S/W Q Added OK : %u\n",
+ rx[portId].rxFreeRepFromSwQOK);
+ printf("Rx Free From S/W Q Delayed : %u\n",
+ rx[portId].rxFreeRepFromSwQDelayed);
+ printf("Rx Free Overflow : %u\n",
+ rx[portId].rxFreeOverflow);
+ printf("Rx Free Mutual Lock : %u\n",
+ rx[portId].rxFreeLock);
+ printf("Rx Free Late Ntf Enabled : %u\n",
+ rx[portId].rxFreeLateNotificationEnabled);
+ printf("Rx Free Low CB : %u\n",
+ rx[portId].rxFreeLowCallback);
+ printf("Rx From H/W Q (Disable) : %u\n",
+ rx[portId].rxDuringDisable);
+ printf("Rx From S/W Q (Disable) : %u\n",
+ rx[portId].rxSwQDuringDisable);
+ printf("Rx unlearned Mac Address : %u\n",
+ rx[portId].rxUnlearnedMacAddress);
+ printf("Rx Filtered (Rx => RxFree) : %u\n",
+ rx[portId].rxFiltered);
+
+ for (priority = IX_ETH_ACC_TX_PRIORITY_0;
+ priority <= IX_ETH_ACC_TX_PRIORITY_7;
+ priority++)
+ {
+ if (rx[portId].rxPriority[priority])
+ {
+ printf("Rx Priority %u : %u\n",
+ priority,
+ rx[portId].rxPriority[priority]);
+ }
+ }
+#endif
+ printf("Rx unexpected errors : %u (should be 0)\n",
+ rx[portId].rxUnexpectedError);
+
+#ifndef NDEBUG
+ numBuffersInTx = tx[portId].txQOK +
+ tx[portId].txQDelayed -
+ tx[portId].txDoneClientCallback -
+ tx[portId].txDoneSwQDuringDisable -
+ tx[portId].txDoneDuringDisable;
+
+ printf("# Tx Buffers currently for transmission : %u\n",
+ numBuffersInTx);
+
+ numBuffersInRx = rx[portId].rxFreeRepOK +
+ rx[portId].rxFreeRepDelayed -
+ rx[portId].rxFrameClientCallback -
+ rx[portId].rxSwQDuringDisable -
+ rx[portId].rxDuringDisable;
+
+ printf("# Rx Buffers currently for reception : %u\n",
+ numBuffersInRx);
+
+ totalBuffers += numBuffersInRx + numBuffersInTx;
+#endif
+ }
+
+ printf("---------------------------------------\n");
+
+#ifndef NDEBUG
+ printf("\n");
+ printf("Mbufs :\n");
+ printf("Tx Unchained mbufs : %u\n",
+ stats.unchainedTxMBufs);
+ printf("Tx Chained bufs : %u\n",
+ stats.chainedTxMBufs);
+ printf("TxDone Unchained mbufs : %u\n",
+ stats.unchainedTxDoneMBufs);
+ printf("TxDone Chained bufs : %u\n",
+ stats.chainedTxDoneMBufs);
+ printf("RxFree Unchained mbufs : %u\n",
+ stats.unchainedRxFreeMBufs);
+ printf("RxFree Chained bufs : %u\n",
+ stats.chainedRxFreeMBufs);
+ printf("Rx Unchained mbufs : %u\n",
+ stats.unchainedRxMBufs);
+ printf("Rx Chained bufs : %u\n",
+ stats.chainedRxMBufs);
+
+ printf("\n");
+ printf("Software queue usage :\n");
+ printf("Buffers added to S/W Q : %u\n",
+ stats.addToSwQ);
+ printf("Buffers removed from S/W Q : %u\n",
+ stats.removeFromSwQ);
+
+ printf("\n");
+ printf("Hardware queues callbacks :\n");
+
+ for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+ {
+ rxFreeCallbackCounter += rx[portId].rxFreeLowCallback;
+ txCallbackCounter += tx[portId].txLowThreshCallback;
+ }
+ printf("Tx Done QM Callback invoked : %u\n",
+ stats.txDoneCallbackCounter);
+ printf("Tx QM Callback invoked : %u\n",
+ txCallbackCounter);
+ printf("Rx QM Callback invoked : %u\n",
+ stats.rxCallbackCounter);
+ printf("Rx QM Callback burst read : %u\n",
+ stats.rxCallbackBurstRead);
+ printf("Rx Free QM Callback invoked : %u\n",
+ rxFreeCallbackCounter);
+#endif
+ printf("Unexpected errors in CB : %u (should be 0)\n",
+ stats.unexpectedError);
+ printf("\n");
+
+ printf("Hardware queues levels :\n");
+ printf("Transmit Port 1 Q : %u \n",numTx0Entries);
+ printf("Transmit Port 2 Q : %u \n",numTx1Entries);
+#ifdef __ixp46X
+ printf("Transmit Port 3 Q : %u \n",numTx2Entries);
+#endif
+ printf("Transmit Done Q : %u \n",numTxDoneEntries);
+ printf("Receive Q : %u \n",numRxEntries);
+ printf("Receive Free Port 1 Q : %u \n",numRxFree0Entries);
+ printf("Receive Free Port 2 Q : %u \n",numRxFree1Entries);
+#ifdef __ixp46X
+ printf("Receive Free Port 3 Q : %u \n",numRxFree2Entries);
+#endif
+
+#ifndef NDEBUG
+ printf("\n");
+ printf("# Total Buffers accounted for : %u\n",
+ totalBuffers);
+
+ numBuffersInSwQ = ixEthAccDataStats.addToSwQ -
+ ixEthAccDataStats.removeFromSwQ;
+
+ printf(" Buffers in S/W Qs : %u\n",
+ numBuffersInSwQ);
+ printf(" Buffers in H/W Qs or NPEs : %u\n",
+ totalBuffers - numBuffersInSwQ);
+#endif
+
+ printf("Rx QoS Discipline : %s\n",
+ (ixEthAccDataInfo.schDiscipline ==
+ FIFO_PRIORITY ) ? "Enabled" : "Disabled");
+
+ for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+ {
+ printf("Tx QoS Discipline port %u : %s\n",
+ portId,
+ (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline ==
+ FIFO_PRIORITY ) ? "Enabled" : "Disabled");
+ }
+ printf("\n");
+}
+
+
+
+
+
diff --git a/cpu/ixp/npe/IxEthAccMac.c b/cpu/ixp/npe/IxEthAccMac.c
new file mode 100644
index 0000000..d57e716
--- /dev/null
+++ b/cpu/ixp/npe/IxEthAccMac.c
@@ -0,0 +1,2641 @@
+/**
+ * @file IxEthAccMac.c
+ *
+ * @author Intel Corporation
+ * @date
+ *
+ * @brief MAC control functions
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxOsal.h"
+#include "IxNpeMh.h"
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+#include "IxEthDB.h"
+#endif
+#include "IxEthDBPortDefs.h"
+#include "IxEthNpe.h"
+#include "IxEthAcc.h"
+#include "IxEthAccDataPlane_p.h"
+#include "IxEthAcc_p.h"
+#include "IxEthAccMac_p.h"
+
+/* Maximum number of retries during ixEthAccPortDisable, which
+ * is approximately 10 seconds
+*/
+#define IX_ETH_ACC_MAX_RETRY 500
+
+/* Maximum number of retries during ixEthAccPortDisable when expecting
+ * timeout
+ */
+#define IX_ETH_ACC_MAX_RETRY_TIMEOUT 5
+
+#define IX_ETH_ACC_VALIDATE_PORT_ID(portId) \
+ do \
+ { \
+ if(!IX_ETH_ACC_IS_PORT_VALID(portId)) \
+ { \
+ return IX_ETH_ACC_INVALID_PORT; \
+ } \
+ } while(0)
+
+PUBLIC IxEthAccMacState ixEthAccMacState[IX_ETH_ACC_NUMBER_OF_PORTS];
+
+PRIVATE UINT32 ixEthAccMacBase[IX_ETH_ACC_NUMBER_OF_PORTS];
+
+/*Forward function declarations*/
+PRIVATE void
+ixEthAccPortDisableRx (IxEthAccPortId portId,
+ IX_OSAL_MBUF * mBufPtr,
+ BOOL useMultiBufferCallback);
+
+PRIVATE void
+ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId,
+ IX_OSAL_MBUF * mBufPtr,
+ BOOL useMultiBufferCallback);
+
+PRIVATE void
+ixEthAccPortDisableTxDone (UINT32 cbTag,
+ IX_OSAL_MBUF *mbuf);
+
+PRIVATE void
+ixEthAccPortDisableTxDoneAndSubmit (UINT32 cbTag,
+ IX_OSAL_MBUF *mbuf);
+
+PRIVATE void
+ixEthAccPortDisableRxCallback (UINT32 cbTag,
+ IX_OSAL_MBUF * mBufPtr,
+ UINT32 learnedPortId);
+
+PRIVATE void
+ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag,
+ IX_OSAL_MBUF **mBufPtr);
+
+PRIVATE IxEthAccStatus
+ixEthAccPortDisableTryTransmit(UINT32 portId);
+
+PRIVATE IxEthAccStatus
+ixEthAccPortDisableTryReplenish(UINT32 portId);
+
+PRIVATE IxEthAccStatus
+ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId,
+ IxEthAccMacAddr *macAddr);
+
+PRIVATE IxEthAccStatus
+ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId,
+ IxEthAccMacAddr *macAddr);
+
+PRIVATE void
+ixEthAccMacNpeStatsMessageCallback (IxNpeMhNpeId npeId,
+ IxNpeMhMessage msg);
+
+PRIVATE void
+ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId,
+ IxNpeMhMessage msg);
+
+PRIVATE void
+ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId,
+ IxNpeMhMessage msg);
+
+PRIVATE void
+ixEthAccMulticastAddressSet(IxEthAccPortId portId);
+
+PRIVATE BOOL
+ixEthAccMacEqual(IxEthAccMacAddr *macAddr1,
+ IxEthAccMacAddr *macAddr2);
+
+PRIVATE void
+ixEthAccMacPrint(IxEthAccMacAddr *m);
+
+PRIVATE void
+ixEthAccMacStateUpdate(IxEthAccPortId portId);
+
+IxEthAccStatus
+ixEthAccMacMemInit(void)
+{
+ ixEthAccMacBase[IX_ETH_PORT_1] =
+ (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE,
+ IX_OSAL_IXP400_ETHA_MAP_SIZE);
+ ixEthAccMacBase[IX_ETH_PORT_2] =
+ (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_1_BASE,
+ IX_OSAL_IXP400_ETHB_MAP_SIZE);
+#ifdef __ixp46X
+ ixEthAccMacBase[IX_ETH_PORT_3] =
+ (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_2_BASE,
+ IX_OSAL_IXP400_ETH_NPEA_MAP_SIZE);
+ if (ixEthAccMacBase[IX_ETH_PORT_3] == 0)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "EthAcc: Could not map MAC I/O memory\n",
+ 0, 0, 0, 0, 0 ,0);
+
+ return IX_ETH_ACC_FAIL;
+ }
+#endif
+
+ if (ixEthAccMacBase[IX_ETH_PORT_1] == 0
+ || ixEthAccMacBase[IX_ETH_PORT_2] == 0)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "EthAcc: Could not map MAC I/O memory\n",
+ 0, 0, 0, 0, 0 ,0);
+
+ return IX_ETH_ACC_FAIL;
+ }
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+void
+ixEthAccMacUnload(void)
+{
+ IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_1]);
+ IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_2]);
+#ifdef __ixp46X
+ IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_3]);
+ ixEthAccMacBase[IX_ETH_PORT_3] = 0;
+#endif
+ ixEthAccMacBase[IX_ETH_PORT_2] = 0;
+ ixEthAccMacBase[IX_ETH_PORT_1] = 0;
+}
+
+IxEthAccStatus
+ixEthAccPortEnablePriv(IxEthAccPortId portId)
+{
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ printf("EthAcc: (Mac) cannot enable port %d, port not initialized\n", portId);
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ if (ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn == NULL)
+ {
+ /* TxDone callback not registered */
+ printf("EthAcc: (Mac) cannot enable port %d, TxDone callback not registered\n", portId);
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ if ((ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn == NULL)
+ && (ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn == NULL))
+ {
+ /* Receive callback not registered */
+ printf("EthAcc: (Mac) cannot enable port %d, Rx callback not registered\n", portId);
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ if(!ixEthAccMacState[portId].initDone)
+ {
+ printf("EthAcc: (Mac) cannot enable port %d, MAC address not set\n", portId);
+ return (IX_ETH_ACC_MAC_UNINITIALIZED);
+ }
+
+ /* if the state is being set to what it is already at, do nothing*/
+ if (ixEthAccMacState[portId].enabled)
+ {
+ return IX_ETH_ACC_SUCCESS;
+ }
+
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+ /* enable ethernet database for this port */
+ if (ixEthDBPortEnable(portId) != IX_ETH_DB_SUCCESS)
+ {
+ printf("EthAcc: (Mac) cannot enable port %d, EthDB failure\n", portId);
+ return IX_ETH_ACC_FAIL;
+ }
+#endif
+
+ /* set the MAC core registers */
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL2,
+ IX_ETH_ACC_TX_CNTRL2_RETRIES_MASK);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RANDOM_SEED,
+ IX_ETH_ACC_RANDOM_SEED_DEFAULT);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_THRESH_P_EMPTY,
+ IX_ETH_ACC_MAC_THRESH_P_EMPTY_DEFAULT);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_THRESH_P_FULL,
+ IX_ETH_ACC_MAC_THRESH_P_FULL_DEFAULT);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_DEFER,
+ IX_ETH_ACC_MAC_TX_DEFER_DEFAULT);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_TWO_DEFER_1,
+ IX_ETH_ACC_MAC_TX_TWO_DEFER_1_DEFAULT);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_TWO_DEFER_2,
+ IX_ETH_ACC_MAC_TX_TWO_DEFER_2_DEFAULT);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_SLOT_TIME,
+ IX_ETH_ACC_MAC_SLOT_TIME_DEFAULT);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_INT_CLK_THRESH,
+ IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_BUF_SIZE_TX,
+ IX_ETH_ACC_MAC_BUF_SIZE_TX_DEFAULT);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ IX_ETH_ACC_TX_CNTRL1_DEFAULT);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ IX_ETH_ACC_RX_CNTRL1_DEFAULT);
+
+ /* set the global state */
+ ixEthAccMacState[portId].portDisableState = ACTIVE;
+ ixEthAccMacState[portId].enabled = TRUE;
+
+ /* rewrite the setup (including mac filtering) depending
+ * on current options
+ */
+ ixEthAccMacStateUpdate(portId);
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+/*
+ * PortDisable local variables. They contain the intermediate steps
+ * while the port is being disabled and the buffers being drained out
+ * of the NPE.
+ */
+typedef void (*IxEthAccPortDisableRx)(IxEthAccPortId portId,
+ IX_OSAL_MBUF * mBufPtr,
+ BOOL useMultiBufferCallback);
+static IxEthAccPortRxCallback
+ixEthAccPortDisableFn[IX_ETH_ACC_NUMBER_OF_PORTS];
+static IxEthAccPortMultiBufferRxCallback
+ixEthAccPortDisableMultiBufferFn[IX_ETH_ACC_NUMBER_OF_PORTS];
+static IxEthAccPortDisableRx
+ixEthAccPortDisableRxTable[IX_ETH_ACC_NUMBER_OF_PORTS];
+static UINT32
+ixEthAccPortDisableCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];
+static UINT32
+ixEthAccPortDisableMultiBufferCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];
+
+static IxEthAccPortTxDoneCallback
+ixEthAccPortDisableTxDoneFn[IX_ETH_ACC_NUMBER_OF_PORTS];
+static UINT32
+ixEthAccPortDisableTxDoneCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];
+
+static UINT32
+ixEthAccPortDisableUserBufferCount[IX_ETH_ACC_NUMBER_OF_PORTS];
+
+/*
+ * PortDisable private callbacks functions. They handle the user
+ * traffic, and the special buffers (one for tx, one for rx) used
+ * in portDisable.
+ */
+PRIVATE void
+ixEthAccPortDisableTxDone(UINT32 cbTag,
+ IX_OSAL_MBUF *mbuf)
+{
+ IxEthAccPortId portId = (IxEthAccPortId)cbTag;
+ volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState;
+
+ /* check for the special mbuf used in portDisable */
+ if (mbuf == ixEthAccMacState[portId].portDisableTxMbufPtr)
+ {
+ *txState = TRANSMIT_DONE;
+ }
+ else
+ {
+ /* increment the count of user traffic during portDisable */
+ ixEthAccPortDisableUserBufferCount[portId]++;
+
+ /* call client TxDone function */
+ ixEthAccPortDisableTxDoneFn[portId](ixEthAccPortDisableTxDoneCbTag[portId], mbuf);
+ }
+}
+
+PRIVATE IxEthAccStatus
+ixEthAccPortDisableTryTransmit(UINT32 portId)
+{
+ int key;
+ IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
+ volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState;
+ /* transmit the special buffer again if it is transmitted
+ * and update the txState
+ * This section is protected because the portDisable context
+ * run an identical code, so the system keeps transmitting at the
+ * maximum rate.
+ */
+ key = ixOsalIrqLock();
+ if (*txState == TRANSMIT_DONE)
+ {
+ IX_OSAL_MBUF *mbufTxPtr = ixEthAccMacState[portId].portDisableTxMbufPtr;
+ *txState = TRANSMIT;
+ status = ixEthAccPortTxFrameSubmit(portId,
+ mbufTxPtr,
+ IX_ETH_ACC_TX_DEFAULT_PRIORITY);
+ }
+ ixOsalIrqUnlock(key);
+
+ return status;
+}
+
+PRIVATE void
+ixEthAccPortDisableTxDoneAndSubmit(UINT32 cbTag,
+ IX_OSAL_MBUF *mbuf)
+{
+ IxEthAccPortId portId = (IxEthAccPortId)cbTag;
+
+ /* call the callback which forwards the traffic to the client */
+ ixEthAccPortDisableTxDone(cbTag, mbuf);
+
+ /* try to transmit the buffer used in portDisable
+ * if seen in TxDone
+ */
+ ixEthAccPortDisableTryTransmit(portId);
+}
+
+PRIVATE void
+ixEthAccPortDisableRx (IxEthAccPortId portId,
+ IX_OSAL_MBUF * mBufPtr,
+ BOOL useMultiBufferCallback)
+{
+ volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState;
+ IX_OSAL_MBUF *mNextPtr;
+
+ while (mBufPtr)
+ {
+ mNextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr);
+ IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr) = NULL;
+
+ /* check for the special mbuf used in portDisable */
+ if (mBufPtr == ixEthAccMacState[portId].portDisableRxMbufPtr)
+ {
+ *rxState = RECEIVE;
+ }
+ else
+ {
+ /* increment the count of user traffic during portDisable */
+ ixEthAccPortDisableUserBufferCount[portId]++;
+
+ /* reset the received payload length during portDisable */
+ IX_OSAL_MBUF_MLEN(mBufPtr) = 0;
+ IX_OSAL_MBUF_PKT_LEN(mBufPtr) = 0;
+
+ if (useMultiBufferCallback)
+ {
+ /* call the user callback with one unchained
+ * buffer, without payload. A small array is built
+ * to be used as a parameter (the user callback expects
+ * to receive an array ended by a NULL pointer.
+ */
+ IX_OSAL_MBUF *mBufPtrArray[2];
+
+ mBufPtrArray[0] = mBufPtr;
+ mBufPtrArray[1] = NULL;
+ ixEthAccPortDisableMultiBufferFn[portId](
+ ixEthAccPortDisableMultiBufferCbTag[portId],
+ mBufPtrArray);
+ }
+ else
+ {
+ /* call the user callback with a unchained
+ * buffer, without payload and the destination port is
+ * unknown.
+ */
+ ixEthAccPortDisableFn[portId](
+ ixEthAccPortDisableCbTag[portId],
+ mBufPtr,
+ IX_ETH_DB_UNKNOWN_PORT /* port not found */);
+ }
+ }
+
+ mBufPtr = mNextPtr;
+ }
+}
+
+PRIVATE IxEthAccStatus
+ixEthAccPortDisableTryReplenish(UINT32 portId)
+{
+ int key;
+ IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
+ volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState;
+ /* replenish with the special buffer again if it is received
+ * and update the rxState
+ * This section is protected because the portDisable context
+ * run an identical code, so the system keeps replenishing at the
+ * maximum rate.
+ */
+ key = ixOsalIrqLock();
+ if (*rxState == RECEIVE)
+ {
+ IX_OSAL_MBUF *mbufRxPtr = ixEthAccMacState[portId].portDisableRxMbufPtr;
+ *rxState = REPLENISH;
+ IX_OSAL_MBUF_MLEN(mbufRxPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE;
+ status = ixEthAccPortRxFreeReplenish(portId, mbufRxPtr);
+ }
+ ixOsalIrqUnlock(key);
+
+ return status;
+}
+
+PRIVATE void
+ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId,
+ IX_OSAL_MBUF * mBufPtr,
+ BOOL useMultiBufferCallback)
+{
+ /* call the callback which forwards the traffic to the client */
+ ixEthAccPortDisableRx(portId, mBufPtr, useMultiBufferCallback);
+
+ /* try to replenish with the buffer used in portDisable
+ * if seen in Rx
+ */
+ ixEthAccPortDisableTryReplenish(portId);
+}
+
+PRIVATE void
+ixEthAccPortDisableRxCallback (UINT32 cbTag,
+ IX_OSAL_MBUF * mBufPtr,
+ UINT32 learnedPortId)
+{
+ IxEthAccPortId portId = (IxEthAccPortId)cbTag;
+
+ /* call the portDisable receive callback */
+ (ixEthAccPortDisableRxTable[portId])(portId, mBufPtr, FALSE);
+}
+
+PRIVATE void
+ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag,
+ IX_OSAL_MBUF **mBufPtr)
+{
+ IxEthAccPortId portId = (IxEthAccPortId)cbTag;
+
+ while (*mBufPtr)
+ {
+ /* call the portDisable receive callback with one buffer at a time */
+ (ixEthAccPortDisableRxTable[portId])(portId, *mBufPtr++, TRUE);
+ }
+}
+
+IxEthAccStatus
+ixEthAccPortDisablePriv(IxEthAccPortId portId)
+{
+ IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
+ int key;
+ int retry, retryTimeout;
+ volatile IxEthAccPortDisableState *state = &ixEthAccMacState[portId].portDisableState;
+ volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState;
+ volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState;
+
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable port.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ /* if the state is being set to what it is already at, do nothing */
+ if (!ixEthAccMacState[portId].enabled)
+ {
+ return IX_ETH_ACC_SUCCESS;
+ }
+
+ *state = DISABLED;
+
+ /* disable MAC receive first */
+ ixEthAccPortRxDisablePriv(portId);
+
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+ /* disable ethernet database for this port - It is done now to avoid
+ * issuing ELT maintenance after requesting 'port disable' in an NPE
+ */
+ if (ixEthDBPortDisable(portId) != IX_ETH_DB_SUCCESS)
+ {
+ status = IX_ETH_ACC_FAIL;
+ IX_ETH_ACC_FATAL_LOG("ixEthAccPortDisable: failed to disable EthDB for this port\n", 0, 0, 0, 0, 0, 0);
+ }
+#endif
+
+ /* enter the critical section */
+ key = ixOsalIrqLock();
+
+ /* swap the Rx and TxDone callbacks */
+ ixEthAccPortDisableFn[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn;
+ ixEthAccPortDisableMultiBufferFn[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn;
+ ixEthAccPortDisableCbTag[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag;
+ ixEthAccPortDisableMultiBufferCbTag[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag;
+ ixEthAccPortDisableTxDoneFn[portId] = ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn;
+ ixEthAccPortDisableTxDoneCbTag[portId] = ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag;
+ ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRx;
+
+ /* register temporary callbacks */
+ ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = ixEthAccPortDisableRxCallback;
+ ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = portId;
+
+ ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferRxCallback;
+ ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = portId;
+
+ ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = ixEthAccPortDisableTxDone;
+ ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = portId;
+
+ /* initialise the Rx state and Tx states */
+ *txState = TRANSMIT_DONE;
+ *rxState = RECEIVE;
+
+ /* exit the critical section */
+ ixOsalIrqUnlock(key);
+
+ /* enable a NPE loopback */
+ if (ixEthAccNpeLoopbackEnablePriv(portId) != IX_ETH_ACC_SUCCESS)
+ {
+ status = IX_ETH_ACC_FAIL;
+ }
+
+ if (status == IX_ETH_ACC_SUCCESS)
+ {
+ retry = 0;
+
+ /* Step 1 : Drain Tx traffic and TxDone queues :
+ *
+ * Transmit and replenish at least once with the
+ * special buffers until both of them are seen
+ * in the callback hook
+ *
+ * (the receive callback keeps replenishing, so once we see
+ * the special Tx buffer, we can be sure that Tx drain is complete)
+ */
+ ixEthAccPortDisableRxTable[portId]
+ = ixEthAccPortDisableRxAndReplenish;
+ ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn
+ = ixEthAccPortDisableTxDone;
+
+ do
+ {
+ /* keep replenishing */
+ status = ixEthAccPortDisableTryReplenish(portId);
+ if (status == IX_ETH_ACC_SUCCESS)
+ {
+ /* keep transmitting */
+ status = ixEthAccPortDisableTryTransmit(portId);
+ }
+ if (status == IX_ETH_ACC_SUCCESS)
+ {
+ /* wait for some traffic being processed */
+ ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
+ }
+ }
+ while ((status == IX_ETH_ACC_SUCCESS)
+ && (retry++ < IX_ETH_ACC_MAX_RETRY)
+ && (*txState == TRANSMIT));
+
+ /* Step 2 : Drain Rx traffic, RxFree and Rx queues :
+ *
+ * Transmit and replenish at least once with the
+ * special buffers until both of them are seen
+ * in the callback hook
+ * (the transmit callback keeps transmitting, and when we see
+ * the special Rx buffer, we can be sure that rxFree drain
+ * is complete)
+ *
+ * The nested loop helps to retry if the user was keeping
+ * replenishing or transmitting during portDisable.
+ *
+ * The 2 nested loops ensure more retries if user traffic is
+ * seen during portDisable : the user should not replenish
+ * or transmit while portDisable is running. However, because of
+ * the queueing possibilities in ethAcc dataplane, it is possible
+ * that a lot of traffic is left in the queues (e.g. when
+ * transmitting over a low speed link) and therefore, more
+ * retries are allowed to help flushing the buffers out.
+ */
+ ixEthAccPortDisableRxTable[portId]
+ = ixEthAccPortDisableRx;
+ ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn
+ = ixEthAccPortDisableTxDoneAndSubmit;
+
+ do
+ {
+ do
+ {
+ ixEthAccPortDisableUserBufferCount[portId] = 0;
+
+ /* keep replenishing */
+ status = ixEthAccPortDisableTryReplenish(portId);
+ if (status == IX_ETH_ACC_SUCCESS)
+ {
+ /* keep transmitting */
+ status = ixEthAccPortDisableTryTransmit(portId);
+ }
+ if (status == IX_ETH_ACC_SUCCESS)
+ {
+ /* wait for some traffic being processed */
+ ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
+ }
+ }
+ while ((status == IX_ETH_ACC_SUCCESS)
+ && (retry++ < IX_ETH_ACC_MAX_RETRY)
+ && ((ixEthAccPortDisableUserBufferCount[portId] != 0)
+ || (*rxState == REPLENISH)));
+
+ /* After the first iteration, change the receive callbacks,
+ * to process only 1 buffer at a time
+ */
+ ixEthAccPortDisableRxTable[portId]
+ = ixEthAccPortDisableRx;
+ ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn
+ = ixEthAccPortDisableTxDone;
+
+ /* repeat the whole process while user traffic is seen in TxDone
+ *
+ * The conditions to stop the loop are
+ * - Xscale has both Rx and Tx special buffers
+ * (txState = transmit, rxState = receive)
+ * - any error in txSubmit or rxReplenish
+ * - no user traffic seen
+ * - an excessive amount of retries
+ */
+ }
+ while ((status == IX_ETH_ACC_SUCCESS)
+ && (retry < IX_ETH_ACC_MAX_RETRY)
+ && (*txState == TRANSMIT));
+
+ /* check the loop exit conditions. The NPE should not hold
+ * the special buffers.
+ */
+ if ((*rxState == REPLENISH) || (*txState == TRANSMIT))
+ {
+ status = IX_ETH_ACC_FAIL;
+ }
+
+ if (status == IX_ETH_ACC_SUCCESS)
+ {
+ /* Step 3 : Replenish without transmitting until a timeout
+ * occurs, in order to drain the internal NPE fifos
+ *
+ * we can expect a few frames srill held
+ * in the NPE.
+ *
+ * The 2 nested loops take care about the NPE dropping traffic
+ * (including loopback traffic) when the Rx queue is full.
+ *
+ * The timeout value is very conservative
+ * since the loopback used keeps replenishhing.
+ *
+ */
+ do
+ {
+ ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRxAndReplenish;
+ ixEthAccPortDisableUserBufferCount[portId] = 0;
+ retryTimeout = 0;
+ do
+ {
+ /* keep replenishing */
+ status = ixEthAccPortDisableTryReplenish(portId);
+ if (status == IX_ETH_ACC_SUCCESS)
+ {
+ /* wait for some traffic being processed */
+ ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
+ }
+ }
+ while ((status == IX_ETH_ACC_SUCCESS)
+ && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT));
+
+ /* Step 4 : Transmit once. Stop replenish
+ *
+ * After the Rx timeout, we are sure that the NPE does not
+ * hold any frame in its internal NPE fifos.
+ *
+ * At this point, the NPE still holds the last rxFree buffer.
+ * By transmitting a single frame, this should unblock the
+ * last rxFree buffer. This code just transmit once and
+ * wait for both frames seen in TxDone and in rxFree.
+ *
+ */
+ ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRx;
+ status = ixEthAccPortDisableTryTransmit(portId);
+
+ /* the NPE should immediatelyt release
+ * the last Rx buffer and the last transmitted buffer
+ * unless the last Tx frame was dropped (rx queue full)
+ */
+ if (status == IX_ETH_ACC_SUCCESS)
+ {
+ retryTimeout = 0;
+ do
+ {
+ ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
+ }
+ while ((*rxState == REPLENISH)
+ && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT));
+ }
+
+ /* the NPE may have dropped the traffic because of Rx
+ * queue being full. This code ensures that the last
+ * Tx and Rx frames are both received.
+ */
+ }
+ while ((status == IX_ETH_ACC_SUCCESS)
+ && (retry++ < IX_ETH_ACC_MAX_RETRY)
+ && ((*txState == TRANSMIT)
+ || (*rxState == REPLENISH)
+ || (ixEthAccPortDisableUserBufferCount[portId] != 0)));
+
+ /* Step 5 : check the final states : the NPE has
+ * no buffer left, nor in Tx , nor in Rx directions.
+ */
+ if ((*rxState == REPLENISH) || (*txState == TRANSMIT))
+ {
+ status = IX_ETH_ACC_FAIL;
+ }
+ }
+
+ /* now all the buffers are drained, disable NPE loopback
+ * This is done regardless of the logic to drain the queues and
+ * the internal buffers held by the NPE.
+ */
+ if (ixEthAccNpeLoopbackDisablePriv(portId) != IX_ETH_ACC_SUCCESS)
+ {
+ status = IX_ETH_ACC_FAIL;
+ }
+ }
+
+ /* disable MAC Tx and Rx services */
+ ixEthAccMacState[portId].enabled = FALSE;
+ ixEthAccMacStateUpdate(portId);
+
+ /* restore the Rx and TxDone callbacks (within a critical section) */
+ key = ixOsalIrqLock();
+
+ ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = ixEthAccPortDisableFn[portId];
+ ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = ixEthAccPortDisableCbTag[portId];
+ ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferFn[portId];
+ ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = ixEthAccPortDisableMultiBufferCbTag[portId];
+ ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = ixEthAccPortDisableTxDoneFn[portId];
+ ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = ixEthAccPortDisableTxDoneCbTag[portId];
+
+ ixOsalIrqUnlock(key);
+
+ /* the MAC core rx/tx disable may left the MAC hardware in an
+ * unpredictable state. A hw reset is executed before resetting
+ * all the MAC parameters to a known value.
+ */
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_CORE_CNTRL,
+ IX_ETH_ACC_CORE_RESET);
+
+ ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY);
+
+ /* rewrite all parameters to their current value */
+ ixEthAccMacStateUpdate(portId);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_INT_CLK_THRESH,
+ IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_CORE_CNTRL,
+ IX_ETH_ACC_CORE_MDC_EN);
+
+ return status;
+}
+
+IxEthAccStatus
+ixEthAccPortEnabledQueryPriv(IxEthAccPortId portId, BOOL *enabled)
+{
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0);
+
+ /* Since Eth NPE is not available, port must be disabled */
+ *enabled = FALSE ;
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ /* Since Eth NPE is not available, port must be disabled */
+ *enabled = FALSE ;
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ *enabled = ixEthAccMacState[portId].enabled;
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortMacResetPriv(IxEthAccPortId portId)
+{
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot reset Ethernet coprocessor.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_CORE_CNTRL,
+ IX_ETH_ACC_CORE_RESET);
+
+ ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY);
+
+ /* rewrite all parameters to their current value */
+ ixEthAccMacStateUpdate(portId);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_INT_CLK_THRESH,
+ IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_CORE_CNTRL,
+ IX_ETH_ACC_CORE_MDC_EN);
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortLoopbackEnable(IxEthAccPortId portId)
+{
+ UINT32 regval;
+
+ /* Turn off promiscuous mode */
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable loopback.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ /* read register */
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval);
+
+ /* update register */
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval | IX_ETH_ACC_RX_CNTRL1_LOOP_EN);
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+PRIVATE void
+ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId,
+ IxNpeMhMessage msg)
+{
+ IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
+
+#ifndef NDEBUG
+ /* Prudent to at least check the port is within range */
+ if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
+ {
+ IX_ETH_ACC_FATAL_LOG("IXETHACC:ixEthAccPortDisableMessageCallback: Illegal port: %u\n",
+ (UINT32) portId, 0, 0, 0, 0, 0);
+
+ return;
+ }
+#endif
+
+ /* unlock message reception mutex */
+ ixOsalMutexUnlock(&ixEthAccMacState[portId].npeLoopbackMessageLock);
+}
+
+IxEthAccStatus
+ixEthAccNpeLoopbackEnablePriv(IxEthAccPortId portId)
+{
+ IX_STATUS npeMhStatus;
+ IxNpeMhMessage message;
+ IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
+
+ /* Turn off promiscuous mode */
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ /* enable NPE loopback (lsb of the message contains the value 1) */
+ message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL)
+ | 0x01;
+ message.data[1] = 0;
+
+ npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
+ message,
+ IX_ETHNPE_SETLOOPBACK_MODE_ACK,
+ ixEthAccNpeLoopbackMessageCallback,
+ IX_NPEMH_SEND_RETRIES_DEFAULT);
+
+ if (npeMhStatus != IX_SUCCESS)
+ {
+ status = IX_ETH_ACC_FAIL;
+ }
+ else
+ {
+ /* wait for NPE loopbackEnable response */
+ if (ixOsalMutexLock(&ixEthAccMacState[portId]. npeLoopbackMessageLock,
+ IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS)
+ != IX_SUCCESS)
+ {
+ status = IX_ETH_ACC_FAIL;
+ }
+ }
+
+ return status;
+}
+
+IxEthAccStatus
+ixEthAccPortTxEnablePriv(IxEthAccPortId portId)
+{
+ UINT32 regval;
+
+ /* Turn off promiscuous mode */
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable TX.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ /* read register */
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ regval);
+
+ /* update register */
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ regval | IX_ETH_ACC_TX_CNTRL1_TX_EN);
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortRxEnablePriv(IxEthAccPortId portId)
+{
+ UINT32 regval;
+
+ /* Turn off promiscuous mode */
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable RX.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ /* read register */
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval);
+
+ /* update register */
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval | IX_ETH_ACC_RX_CNTRL1_RX_EN);
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortLoopbackDisable(IxEthAccPortId portId)
+{
+ UINT32 regval;
+
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable loopback.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ /*disable MAC loopabck */
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ (regval & ~IX_ETH_ACC_RX_CNTRL1_LOOP_EN));
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccNpeLoopbackDisablePriv(IxEthAccPortId portId)
+{
+ IX_STATUS npeMhStatus;
+ IxNpeMhMessage message;
+ IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
+
+ /* Turn off promiscuous mode */
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ /* disable NPE loopback (lsb of the message contains the value 0) */
+ message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL);
+ message.data[1] = 0;
+
+ npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
+ message,
+ IX_ETHNPE_SETLOOPBACK_MODE_ACK,
+ ixEthAccNpeLoopbackMessageCallback,
+ IX_NPEMH_SEND_RETRIES_DEFAULT);
+
+ if (npeMhStatus != IX_SUCCESS)
+ {
+ status = IX_ETH_ACC_FAIL;
+ }
+ else
+ {
+ /* wait for NPE loopbackEnable response */
+ if (ixOsalMutexLock(&ixEthAccMacState[portId].npeLoopbackMessageLock,
+ IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS)
+ != IX_SUCCESS)
+ {
+ status = IX_ETH_ACC_FAIL;
+ }
+ }
+
+ return status;
+}
+
+IxEthAccStatus
+ixEthAccPortTxDisablePriv(IxEthAccPortId portId)
+{
+ UINT32 regval;
+
+ /* Turn off promiscuous mode */
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable TX.\n", (INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ /* read register */
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ regval);
+
+ /* update register */
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ (regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN));
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortRxDisablePriv(IxEthAccPortId portId)
+{
+ UINT32 regval;
+
+ /* Turn off promiscuous mode */
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable RX.\n", (INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ /* read register */
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval);
+
+ /* update register */
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ (regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN));
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortPromiscuousModeClearPriv(IxEthAccPortId portId)
+{
+ UINT32 regval;
+
+ /* Turn off promiscuous mode */
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear promiscuous mode.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ /*set bit 5 of Rx control 1 - enable address filtering*/
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN);
+
+ ixEthAccMacState[portId].promiscuous = FALSE;
+
+ ixEthAccMulticastAddressSet(portId);
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortPromiscuousModeSetPriv(IxEthAccPortId portId)
+{
+ UINT32 regval;
+
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set promiscuous mode.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ /*
+ * Set bit 5 of Rx control 1 - We enable address filtering even in
+ * promiscuous mode because we want the MAC to set the appropriate
+ * bits in m_flags which doesn't happen if we turn off filtering.
+ */
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN);
+
+ ixEthAccMacState[portId].promiscuous = TRUE;
+
+ ixEthAccMulticastAddressSet(portId);
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortUnicastMacAddressSetPriv (IxEthAccPortId portId,
+ IxEthAccMacAddr *macAddr)
+{
+ UINT32 i;
+
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set Unicast Mac Address.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+
+ if (macAddr == NULL)
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+
+ if ( macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT )
+ {
+ /* This is a multicast/broadcast address cant set it ! */
+ return IX_ETH_ACC_FAIL;
+ }
+
+ if ( macAddr->macAddress[0] == 0 &&
+ macAddr->macAddress[1] == 0 &&
+ macAddr->macAddress[2] == 0 &&
+ macAddr->macAddress[3] == 0 &&
+ macAddr->macAddress[4] == 0 &&
+ macAddr->macAddress[5] == 0 )
+ {
+ /* This is an invalid mac address cant set it ! */
+ return IX_ETH_ACC_FAIL;
+ }
+
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+ /* update the MAC address in the ethernet database */
+ if (ixEthDBPortAddressSet(portId, (IxEthDBMacAddr *) macAddr) != IX_ETH_DB_SUCCESS)
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+#endif
+
+ /*Set the Unicast MAC to the specified value*/
+ for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
+ {
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_UNI_ADDR_1 + i*sizeof(UINT32),
+ macAddr->macAddress[i]);
+ }
+ ixEthAccMacState[portId].initDone = TRUE;
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortUnicastMacAddressGetPriv (IxEthAccPortId portId,
+ IxEthAccMacAddr *macAddr)
+{
+ /*Return the current value of the Unicast MAC from h/w
+ for the specified port*/
+ UINT32 i;
+
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get Unicast Mac Address.\n",(INT32)portId,0,0,0,0,0);
+ /* Since Eth Npe is unavailable, return invalid MAC Address = 00:00:00:00:00:00 */
+ for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
+ {
+ macAddr->macAddress[i] = 0;
+ }
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if(!ixEthAccMacState[portId].initDone)
+ {
+ return (IX_ETH_ACC_MAC_UNINITIALIZED);
+ }
+
+ if (macAddr == NULL)
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+
+
+ for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
+ {
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_UNI_ADDR_1 + i*sizeof(UINT32),
+ macAddr->macAddress[i]);
+ }
+ return IX_ETH_ACC_SUCCESS;
+}
+
+PRIVATE IxEthAccStatus
+ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId,
+ IxEthAccMacAddr *macAddr)
+{
+ /*Return the current value of the Multicast MAC from h/w
+ for the specified port*/
+ UINT32 i;
+
+ for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
+ {
+
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_ADDR_1 + i*sizeof(UINT32),
+ macAddr->macAddress[i]);
+ }
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+PRIVATE IxEthAccStatus
+ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId,
+ IxEthAccMacAddr *macAddr)
+{
+ /*Return the current value of the Multicast MAC from h/w
+ for the specified port*/
+ UINT32 i;
+
+ for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
+ {
+
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_ADDR_MASK_1 + i*sizeof(UINT32),
+ macAddr->macAddress[i]);
+ }
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortMulticastAddressJoinPriv (IxEthAccPortId portId,
+ IxEthAccMacAddr *macAddr)
+{
+ UINT32 i;
+ IxEthAccMacAddr broadcastAddr = {{0xff,0xff,0xff,0xff,0xff,0xff}};
+
+ /*Check that the port parameter is valid*/
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join Multicast Mac Address.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ /*Check that the mac address is valid*/
+ if(macAddr == NULL)
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+
+ /* Check that this is a multicast address */
+ if (!(macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT))
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+
+ /* We don't add the Broadcast address */
+ if(ixEthAccMacEqual(&broadcastAddr, macAddr))
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+
+ for (i = 0;
+ i<ixEthAccMacState[portId].mcastAddrIndex;
+ i++)
+ {
+ /*Check if the current entry already match an existing matches*/
+ if(ixEthAccMacEqual(&ixEthAccMacState[portId].mcastAddrsTable[i], macAddr))
+ {
+ /* Address found in the list and already configured,
+ * return a success status
+ */
+ return IX_ETH_ACC_SUCCESS;
+ }
+ }
+
+ /* check for availability at the end of the current table */
+ if(ixEthAccMacState[portId].mcastAddrIndex >= IX_ETH_ACC_MAX_MULTICAST_ADDRESSES)
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+
+ /*First add the address to the multicast table for the
+ specified port*/
+ i=ixEthAccMacState[portId].mcastAddrIndex;
+
+ memcpy(&ixEthAccMacState[portId].mcastAddrsTable[i],
+ &macAddr->macAddress,
+ IX_IEEE803_MAC_ADDRESS_SIZE);
+
+ /*Increment the index into the table, this must be done here
+ as MulticastAddressSet below needs to know about the latest
+ entry.
+ */
+ ixEthAccMacState[portId].mcastAddrIndex++;
+
+ /*Then calculate the new value to be written to the address and
+ address mask registers*/
+ ixEthAccMulticastAddressSet(portId);
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+
+IxEthAccStatus
+ixEthAccPortMulticastAddressJoinAllPriv (IxEthAccPortId portId)
+{
+ IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}};
+
+ /*Check that the port parameter is valid*/
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join all Multicast Address.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ /* remove all entries from the database and
+ * insert a multicast entry
+ */
+ memcpy(&ixEthAccMacState[portId].mcastAddrsTable[0],
+ &mcastMacAddr.macAddress,
+ IX_IEEE803_MAC_ADDRESS_SIZE);
+
+ ixEthAccMacState[portId].mcastAddrIndex = 1;
+ ixEthAccMacState[portId].joinAll = TRUE;
+
+ ixEthAccMulticastAddressSet(portId);
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortMulticastAddressLeavePriv (IxEthAccPortId portId,
+ IxEthAccMacAddr *macAddr)
+{
+ UINT32 i;
+ IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}};
+
+ /*Check that the port parameter is valid*/
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot leave Multicast Address.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ /*Check that the mac address is valid*/
+ if(macAddr == NULL)
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+ /* Remove this mac address from the mask for the specified port
+ * we copy down all entries above the blanked entry, and
+ * decrement the index
+ */
+ i=0;
+
+ while(i<ixEthAccMacState[portId].mcastAddrIndex)
+ {
+ /*Check if the current entry matches*/
+ if(ixEthAccMacEqual(&ixEthAccMacState[portId].mcastAddrsTable[i],
+ macAddr))
+ {
+ if(ixEthAccMacEqual(macAddr, &mcastMacAddr))
+ {
+ ixEthAccMacState[portId].joinAll = FALSE;
+ }
+ /*Decrement the index into the multicast address table
+ for the current port*/
+ ixEthAccMacState[portId].mcastAddrIndex--;
+
+ /*Copy down all entries above the current entry*/
+ while(i<ixEthAccMacState[portId].mcastAddrIndex)
+ {
+ memcpy(&ixEthAccMacState[portId].mcastAddrsTable[i],
+ &ixEthAccMacState[portId].mcastAddrsTable[i+1],
+ IX_IEEE803_MAC_ADDRESS_SIZE);
+ i++;
+ }
+ /*recalculate the mask and write it to the MAC*/
+ ixEthAccMulticastAddressSet(portId);
+
+ return IX_ETH_ACC_SUCCESS;
+ }
+ /* search the next entry */
+ i++;
+ }
+ /* no matching entry found */
+ return IX_ETH_ACC_NO_SUCH_ADDR;
+}
+
+IxEthAccStatus
+ixEthAccPortMulticastAddressLeaveAllPriv (IxEthAccPortId portId)
+{
+ /*Check that the port parameter is valid*/
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot leave all Multicast Address.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ ixEthAccMacState[portId].mcastAddrIndex = 0;
+ ixEthAccMacState[portId].joinAll = FALSE;
+
+ ixEthAccMulticastAddressSet(portId);
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+
+IxEthAccStatus
+ixEthAccPortUnicastAddressShowPriv (IxEthAccPortId portId)
+{
+ IxEthAccMacAddr macAddr;
+
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot show Unicast Address.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ /*Get the MAC (UINICAST) address from hardware*/
+ if(ixEthAccPortUnicastMacAddressGetPriv(portId, &macAddr) != IX_ETH_ACC_SUCCESS)
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: MAC address uninitialised port %u\n",
+ (INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_MAC_UNINITIALIZED;
+ }
+
+ /*print it out*/
+ ixEthAccMacPrint(&macAddr);
+ printf("\n");
+ return IX_ETH_ACC_SUCCESS;
+}
+
+
+
+void
+ixEthAccPortMulticastAddressShowPriv(IxEthAccPortId portId)
+{
+ IxEthAccMacAddr macAddr;
+ UINT32 i;
+
+ if(!IX_ETH_ACC_IS_PORT_VALID(portId))
+ {
+ return;
+ }
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot show Multicast Address.\n",(INT32)portId,0,0,0,0,0);
+ return ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return;
+ }
+
+ printf("Multicast MAC: ");
+ /*Get the MAC (MULTICAST) address from hardware*/
+ ixEthAccPortMulticastMacAddressGet(portId, &macAddr);
+ /*print it out*/
+ ixEthAccMacPrint(&macAddr);
+ /*Get the MAC (MULTICAST) filter from hardware*/
+ ixEthAccPortMulticastMacFilterGet(portId, &macAddr);
+ /*print it out*/
+ printf(" ( ");
+ ixEthAccMacPrint(&macAddr);
+ printf(" )\n");
+ printf("Constituent Addresses:\n");
+ for(i=0;i<ixEthAccMacState[portId].mcastAddrIndex;i++)
+ {
+ ixEthAccMacPrint(&ixEthAccMacState[portId].mcastAddrsTable[i]);
+ printf("\n");
+ }
+ return;
+}
+
+/*Set the duplex mode*/
+IxEthAccStatus
+ixEthAccPortDuplexModeSetPriv (IxEthAccPortId portId,
+ IxEthAccDuplexMode mode)
+{
+ UINT32 txregval;
+ UINT32 rxregval;
+
+ /*This is bit 1 of the transmit control reg, set to 1 for half
+ duplex, 0 for full duplex*/
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set Duplex Mode.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ txregval);
+
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ rxregval);
+
+ if (mode == IX_ETH_ACC_FULL_DUPLEX)
+ {
+ /*Clear half duplex bit in TX*/
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ txregval & ~IX_ETH_ACC_TX_CNTRL1_DUPLEX);
+
+ /*We must set the pause enable in the receive logic when in
+ full duplex mode*/
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ rxregval | IX_ETH_ACC_RX_CNTRL1_PAUSE_EN);
+ ixEthAccMacState[portId].fullDuplex = TRUE;
+
+ }
+ else if (mode == IX_ETH_ACC_HALF_DUPLEX)
+ {
+ /*Set half duplex bit in TX*/
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ txregval | IX_ETH_ACC_TX_CNTRL1_DUPLEX);
+
+ /*We must clear pause enable in the receive logic when in
+ half duplex mode*/
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ rxregval & ~IX_ETH_ACC_RX_CNTRL1_PAUSE_EN);
+
+ ixEthAccMacState[portId].fullDuplex = FALSE;
+ }
+ else
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+
+
+ return IX_ETH_ACC_SUCCESS;
+
+}
+
+
+
+IxEthAccStatus
+ixEthAccPortDuplexModeGetPriv (IxEthAccPortId portId,
+ IxEthAccDuplexMode *mode)
+{
+ /*Return the duplex mode for the specified port*/
+ UINT32 regval;
+
+ /*This is bit 1 of the transmit control reg, set to 1 for half
+ duplex, 0 for full duplex*/
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get Duplex Mode.\n",(INT32)portId,0,0,0,0,0);
+ /* return hald duplex */
+ *mode = IX_ETH_ACC_HALF_DUPLEX ;
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ if (mode == NULL)
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ regval);
+
+ if( regval & IX_ETH_ACC_TX_CNTRL1_DUPLEX)
+ {
+ *mode = IX_ETH_ACC_HALF_DUPLEX;
+ }
+ else
+ {
+ *mode = IX_ETH_ACC_FULL_DUPLEX;
+ }
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+
+
+IxEthAccStatus
+ixEthAccPortTxFrameAppendPaddingEnablePriv (IxEthAccPortId portId)
+{
+ UINT32 regval;
+ /*Enable FCS computation by the MAC and appending to the
+ frame*/
+
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable Tx Frame Append Padding.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ regval);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ regval |
+ IX_ETH_ACC_TX_CNTRL1_PAD_EN);
+
+ ixEthAccMacState[portId].txPADAppend = TRUE;
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortTxFrameAppendPaddingDisablePriv (IxEthAccPortId portId)
+{
+ UINT32 regval;
+
+ /*disable FCS computation and appending*/
+ /*Set bit 4 of Tx control register one to zero*/
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disble Tx Frame Append Padding.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ regval);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ regval & ~IX_ETH_ACC_TX_CNTRL1_PAD_EN);
+
+ ixEthAccMacState[portId].txPADAppend = FALSE;
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortTxFrameAppendFCSEnablePriv (IxEthAccPortId portId)
+{
+ UINT32 regval;
+
+ /*Enable FCS computation by the MAC and appending to the
+ frame*/
+
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable Tx Frame Append FCS.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ regval);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ regval | IX_ETH_ACC_TX_CNTRL1_FCS_EN);
+
+ ixEthAccMacState[portId].txFCSAppend = TRUE;
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortTxFrameAppendFCSDisablePriv (IxEthAccPortId portId)
+{
+ UINT32 regval;
+
+ /*disable FCS computation and appending*/
+ /*Set bit 4 of Tx control register one to zero*/
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable Tx Frame Append FCS.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ regval);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ regval & ~IX_ETH_ACC_TX_CNTRL1_FCS_EN);
+
+ ixEthAccMacState[portId].txFCSAppend = FALSE;
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortRxFrameAppendFCSEnablePriv (IxEthAccPortId portId)
+{
+ /*Set bit 2 of Rx control 1*/
+ UINT32 regval;
+
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable Rx Frame Append FCS.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval | IX_ETH_ACC_RX_CNTRL1_CRC_EN);
+
+ ixEthAccMacState[portId].rxFCSAppend = TRUE;
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortRxFrameAppendFCSDisablePriv (IxEthAccPortId portId)
+{
+ UINT32 regval;
+
+ /*Clear bit 2 of Rx control 1*/
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable Rx Frame Append FCS.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval & ~IX_ETH_ACC_RX_CNTRL1_CRC_EN);
+
+ ixEthAccMacState[portId].rxFCSAppend = FALSE;
+ return IX_ETH_ACC_SUCCESS;
+}
+
+
+
+PRIVATE void
+ixEthAccMacNpeStatsMessageCallback (IxNpeMhNpeId npeId,
+ IxNpeMhMessage msg)
+{
+ IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
+
+#ifndef NDEBUG
+ /* Prudent to at least check the port is within range */
+ if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
+ {
+ IX_ETH_ACC_FATAL_LOG(
+ "IXETHACC:ixEthAccMacNpeStatsMessageCallback: Illegal port: %u\n",
+ (UINT32)portId, 0, 0, 0, 0, 0);
+ return;
+ }
+#endif
+
+ /*Unblock Stats Get call*/
+ ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsLock);
+
+}
+
+PRIVATE void
+ixEthAccMibIIStatsEndianConvert (IxEthEthObjStats *retStats)
+{
+ /* endianness conversion */
+
+ /* Rx stats */
+ retStats->dot3StatsAlignmentErrors =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsAlignmentErrors);
+ retStats->dot3StatsFCSErrors =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsFCSErrors);
+ retStats->dot3StatsInternalMacReceiveErrors =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacReceiveErrors);
+ retStats->RxOverrunDiscards =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxOverrunDiscards);
+ retStats->RxLearnedEntryDiscards =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLearnedEntryDiscards);
+ retStats->RxLargeFramesDiscards =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLargeFramesDiscards);
+ retStats->RxSTPBlockedDiscards =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxSTPBlockedDiscards);
+ retStats->RxVLANTypeFilterDiscards =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANTypeFilterDiscards);
+ retStats->RxVLANIdFilterDiscards =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANIdFilterDiscards);
+ retStats->RxInvalidSourceDiscards =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxInvalidSourceDiscards);
+ retStats->RxBlackListDiscards =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxBlackListDiscards);
+ retStats->RxWhiteListDiscards =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxWhiteListDiscards);
+ retStats->RxUnderflowEntryDiscards =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxUnderflowEntryDiscards);
+
+ /* Tx stats */
+ retStats->dot3StatsSingleCollisionFrames =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsSingleCollisionFrames);
+ retStats->dot3StatsMultipleCollisionFrames =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsMultipleCollisionFrames);
+ retStats->dot3StatsDeferredTransmissions =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsDeferredTransmissions);
+ retStats->dot3StatsLateCollisions =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsLateCollisions);
+ retStats->dot3StatsExcessiveCollsions =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsExcessiveCollsions);
+ retStats->dot3StatsInternalMacTransmitErrors =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacTransmitErrors);
+ retStats->dot3StatsCarrierSenseErrors =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsCarrierSenseErrors);
+ retStats->TxLargeFrameDiscards =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxLargeFrameDiscards);
+ retStats->TxVLANIdFilterDiscards =
+ IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxVLANIdFilterDiscards);
+}
+
+IxEthAccStatus
+ixEthAccMibIIStatsGet (IxEthAccPortId portId,
+ IxEthEthObjStats *retStats )
+{
+ IxNpeMhMessage message;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ printf("EthAcc: ixEthAccMibIIStatsGet (Mac) EthAcc service is not initialized\n");
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (retStats == NULL)
+ {
+ printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NULL argument\n");
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NPE for port %d is not available\n", portId);
+
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get MIB II Stats.\n",(INT32)portId,0,0,0,0,0);
+
+ /* Return all zero stats */
+ IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats));
+
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ printf("EthAcc: ixEthAccMibIIStatsGet (Mac) port %d is not initialized\n", portId);
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats));
+
+ message.data[0] = IX_ETHNPE_GETSTATS << IX_ETH_ACC_MAC_MSGID_SHL;
+ message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats);
+
+ /* Permit only one task to request MIB statistics Get operation
+ at a time */
+ ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetAccessLock, IX_OSAL_WAIT_FOREVER);
+
+ if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
+ message,
+ IX_ETHNPE_GETSTATS,
+ ixEthAccMacNpeStatsMessageCallback,
+ IX_NPEMH_SEND_RETRIES_DEFAULT)
+ != IX_SUCCESS)
+ {
+ ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock);
+
+ printf("EthAcc: (Mac) StatsGet failed to send NPE message\n");
+
+ return IX_ETH_ACC_FAIL;
+ }
+
+ /* Wait for callback invocation indicating response to
+ this request - we need this mutex in order to ensure
+ that the return from this function is synchronous */
+ ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS);
+
+ /* Permit other tasks to perform MIB statistics Get operation */
+ ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock);
+
+ ixEthAccMibIIStatsEndianConvert (retStats);
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+
+PRIVATE void
+ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId,
+ IxNpeMhMessage msg)
+{
+ IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
+
+#ifndef NDEBUG
+ /* Prudent to at least check the port is within range */
+ if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
+ {
+ IX_ETH_ACC_FATAL_LOG(
+ "IXETHACC:ixEthAccMacNpeStatsResetMessageCallback: Illegal port: %u\n",
+ (UINT32)portId, 0, 0, 0, 0, 0);
+ return;
+ }
+#endif
+
+ /*Unblock Stats Get & reset call*/
+ ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsResetLock);
+
+}
+
+
+
+IxEthAccStatus
+ixEthAccMibIIStatsGetClear (IxEthAccPortId portId,
+ IxEthEthObjStats *retStats)
+{
+ IxNpeMhMessage message;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) EthAcc service is not initialized\n");
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (retStats == NULL)
+ {
+ printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NULL argument\n");
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NPE for port %d is not available\n", portId);
+
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get and clear MIB II Stats.\n", (INT32)portId, 0, 0, 0, 0, 0);
+
+ /* Return all zero stats */
+ IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats));
+
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+ {
+ printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) port %d is not initialized\n", portId);
+ return (IX_ETH_ACC_PORT_UNINITIALIZED);
+ }
+
+ IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats));
+
+ message.data[0] = IX_ETHNPE_RESETSTATS << IX_ETH_ACC_MAC_MSGID_SHL;
+ message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats);
+
+ /* Permit only one task to request MIB statistics Get-Reset operation at a time */
+ ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock, IX_OSAL_WAIT_FOREVER);
+
+ if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
+ message,
+ IX_ETHNPE_RESETSTATS,
+ ixEthAccMacNpeStatsResetMessageCallback,
+ IX_NPEMH_SEND_RETRIES_DEFAULT)
+ != IX_SUCCESS)
+ {
+ ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock);
+
+ printf("EthAcc: (Mac) ixEthAccMibIIStatsGetClear failed to send NPE message\n");
+
+ return IX_ETH_ACC_FAIL;
+ }
+
+ /* Wait for callback invocation indicating response to this request */
+ ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS);
+
+ /* permit other tasks to get and reset MIB stats*/
+ ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock);
+
+ ixEthAccMibIIStatsEndianConvert(retStats);
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccMibIIStatsClear (IxEthAccPortId portId)
+{
+ static IxEthEthObjStats retStats;
+ IxEthAccStatus status;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear MIB II Stats.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ /* there is no reset operation without a corresponding Get */
+ status = ixEthAccMibIIStatsGetClear(portId, &retStats);
+
+ return status;
+}
+
+/* Initialize the ethernet MAC settings */
+IxEthAccStatus
+ixEthAccMacInit(IxEthAccPortId portId)
+{
+ IX_OSAL_MBUF_POOL* portDisablePool;
+ UINT8 *data;
+
+ IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+ if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ {
+ IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot initialize Mac.\n",(INT32)portId,0,0,0,0,0);
+ return IX_ETH_ACC_SUCCESS ;
+ }
+
+ if(ixEthAccMacState[portId].macInitialised == FALSE)
+ {
+ ixEthAccMacState[portId].fullDuplex = TRUE;
+ ixEthAccMacState[portId].rxFCSAppend = TRUE;
+ ixEthAccMacState[portId].txFCSAppend = TRUE;
+ ixEthAccMacState[portId].txPADAppend = TRUE;
+ ixEthAccMacState[portId].enabled = FALSE;
+ ixEthAccMacState[portId].promiscuous = TRUE;
+ ixEthAccMacState[portId].joinAll = FALSE;
+ ixEthAccMacState[portId].initDone = FALSE;
+ ixEthAccMacState[portId].macInitialised = TRUE;
+
+ /* initialize MIB stats mutexes */
+ ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsLock);
+ ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_OSAL_WAIT_FOREVER);
+
+ ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsResetLock);
+ ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_OSAL_WAIT_FOREVER);
+
+ ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetAccessLock);
+
+ ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock);
+
+ ixOsalMutexInit(&ixEthAccMacState[portId].npeLoopbackMessageLock);
+
+ ixEthAccMacState[portId].portDisableRxMbufPtr = NULL;
+ ixEthAccMacState[portId].portDisableTxMbufPtr = NULL;
+
+ portDisablePool = IX_OSAL_MBUF_POOL_INIT(2,
+ IX_ETHACC_RX_MBUF_MIN_SIZE,
+ "portDisable Pool");
+
+ IX_OSAL_ENSURE(portDisablePool != NULL, "Failed to initialize PortDisable pool");
+
+ ixEthAccMacState[portId].portDisableRxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool);
+ ixEthAccMacState[portId].portDisableTxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool);
+
+ IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableRxMbufPtr != NULL,
+ "Pool allocation failed");
+ IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableTxMbufPtr != NULL,
+ "Pool allocation failed");
+ /* fill the payload of the Rx mbuf used in portDisable */
+ IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableRxMbufPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE;
+
+ memset(IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableRxMbufPtr),
+ 0xAA,
+ IX_ETHACC_RX_MBUF_MIN_SIZE);
+
+ /* fill the payload of the Tx mbuf used in portDisable (64 bytes) */
+ IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64;
+ IX_OSAL_MBUF_PKT_LEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64;
+
+ data = (UINT8 *) IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableTxMbufPtr);
+ memset(data, 0xBB, 64);
+ data[0] = 0x00; /* unicast destination MAC address */
+ data[6] = 0x00; /* unicast source MAC address */
+ data[12] = 0x08; /* typelength : IP frame */
+ data[13] = 0x00; /* typelength : IP frame */
+
+ IX_OSAL_CACHE_FLUSH(data, 64);
+ }
+
+ IX_OSAL_ASSERT (ixEthAccMacBase[portId] != 0);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_CORE_CNTRL,
+ IX_ETH_ACC_CORE_RESET);
+
+ ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_CORE_CNTRL,
+ IX_ETH_ACC_CORE_MDC_EN);
+
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_INT_CLK_THRESH,
+ IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);
+
+ ixEthAccMacStateUpdate(portId);
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+/* PRIVATE Functions*/
+
+PRIVATE void
+ixEthAccMacStateUpdate(IxEthAccPortId portId)
+{
+ UINT32 regval;
+
+ if ( ixEthAccMacState[portId].enabled == FALSE )
+ {
+ /* Just disable both the transmitter and reciver in the MAC. */
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval);
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN);
+
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ regval);
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN);
+ }
+
+ if(ixEthAccMacState[portId].fullDuplex)
+ {
+ ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_FULL_DUPLEX);
+ }
+ else
+ {
+ ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_HALF_DUPLEX);
+ }
+
+ if(ixEthAccMacState[portId].rxFCSAppend)
+ {
+ ixEthAccPortRxFrameAppendFCSEnablePriv (portId);
+ }
+ else
+ {
+ ixEthAccPortRxFrameAppendFCSDisablePriv (portId);
+ }
+
+ if(ixEthAccMacState[portId].txFCSAppend)
+ {
+ ixEthAccPortTxFrameAppendFCSEnablePriv (portId);
+ }
+ else
+ {
+ ixEthAccPortTxFrameAppendFCSDisablePriv (portId);
+ }
+
+ if(ixEthAccMacState[portId].txPADAppend)
+ {
+ ixEthAccPortTxFrameAppendPaddingEnablePriv (portId);
+ }
+ else
+ {
+ ixEthAccPortTxFrameAppendPaddingDisablePriv (portId);
+ }
+
+ if(ixEthAccMacState[portId].promiscuous)
+ {
+ ixEthAccPortPromiscuousModeSetPriv(portId);
+ }
+ else
+ {
+ ixEthAccPortPromiscuousModeClearPriv(portId);
+ }
+
+ if ( ixEthAccMacState[portId].enabled == TRUE )
+ {
+ /* Enable both the transmitter and reciver in the MAC. */
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval);
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_RX_CNTRL1,
+ regval | IX_ETH_ACC_RX_CNTRL1_RX_EN);
+
+ REG_READ(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ regval);
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_TX_CNTRL1,
+ regval | IX_ETH_ACC_TX_CNTRL1_TX_EN);
+ }
+}
+
+
+PRIVATE BOOL
+ixEthAccMacEqual(IxEthAccMacAddr *macAddr1,
+ IxEthAccMacAddr *macAddr2)
+{
+ UINT32 i;
+ for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE; i++)
+ {
+ if(macAddr1->macAddress[i] != macAddr2->macAddress[i])
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+PRIVATE void
+ixEthAccMacPrint(IxEthAccMacAddr *m)
+{
+ printf("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
+ m->macAddress[0], m->macAddress[1],
+ m->macAddress[2], m->macAddress[3],
+ m->macAddress[4], m->macAddress[5]);
+}
+
+/* Set the multicast address and address mask registers
+ *
+ * A bit in the address mask register must be set if
+ * all multicast addresses always have that bit set, or if
+ * all multicast addresses always have that bit cleared.
+ *
+ * A bit in the address register must be set if all multicast
+ * addresses have that bit set, otherwise, it should be cleared
+ */
+
+PRIVATE void
+ixEthAccMulticastAddressSet(IxEthAccPortId portId)
+{
+ UINT32 i;
+ UINT32 j;
+ IxEthAccMacAddr addressMask;
+ IxEthAccMacAddr address;
+ IxEthAccMacAddr alwaysClearBits;
+ IxEthAccMacAddr alwaysSetBits;
+
+ /* calculate alwaysClearBits and alwaysSetBits:
+ * alwaysClearBits is calculated by ORing all
+ * multicast addresses, those bits that are always
+ * clear are clear in the result
+ *
+ * alwaysSetBits is calculated by ANDing all
+ * multicast addresses, those bits that are always set
+ * are set in the result
+ */
+
+ if (ixEthAccMacState[portId].promiscuous == TRUE)
+ {
+ /* Promiscuous Mode is set, and filtering
+ * allow all packets, and enable the mcast and
+ * bcast detection.
+ */
+ memset(&addressMask.macAddress,
+ 0,
+ IX_IEEE803_MAC_ADDRESS_SIZE);
+ memset(&address.macAddress,
+ 0,
+ IX_IEEE803_MAC_ADDRESS_SIZE);
+ }
+ else
+ {
+ if(ixEthAccMacState[portId].joinAll == TRUE)
+ {
+ /* Join all is set. The mask and address are
+ * the multicast settings.
+ */
+ IxEthAccMacAddr macAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}};
+
+ memcpy(addressMask.macAddress,
+ macAddr.macAddress,
+ IX_IEEE803_MAC_ADDRESS_SIZE);
+ memcpy(address.macAddress,
+ macAddr.macAddress,
+ IX_IEEE803_MAC_ADDRESS_SIZE);
+ }
+ else if(ixEthAccMacState[portId].mcastAddrIndex == 0)
+ {
+ /* No entry in the filtering database,
+ * Promiscuous Mode is cleared, Broadcast filtering
+ * is configured.
+ */
+ memset(addressMask.macAddress,
+ IX_ETH_ACC_MAC_ALL_BITS_SET,
+ IX_IEEE803_MAC_ADDRESS_SIZE);
+ memset(address.macAddress,
+ IX_ETH_ACC_MAC_ALL_BITS_SET,
+ IX_IEEE803_MAC_ADDRESS_SIZE);
+ }
+ else
+ {
+ /* build a mask and an address which mix all entreis
+ * from the list of multicast addresses
+ */
+ memset(alwaysClearBits.macAddress,
+ 0,
+ IX_IEEE803_MAC_ADDRESS_SIZE);
+ memset(alwaysSetBits.macAddress,
+ IX_ETH_ACC_MAC_ALL_BITS_SET,
+ IX_IEEE803_MAC_ADDRESS_SIZE);
+
+ for(i=0;i<ixEthAccMacState[portId].mcastAddrIndex;i++)
+ {
+ for(j=0;j<IX_IEEE803_MAC_ADDRESS_SIZE;j++)
+ {
+ alwaysClearBits.macAddress[j] |=
+ ixEthAccMacState[portId].mcastAddrsTable[i].macAddress[j];
+ alwaysSetBits.macAddress[j] &=
+ ixEthAccMacState[portId].mcastAddrsTable[i].macAddress[j];
+ }
+ }
+
+ for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
+ {
+ addressMask.macAddress[i] = alwaysSetBits.macAddress[i]
+ | ~alwaysClearBits.macAddress[i];
+ address.macAddress[i] = alwaysSetBits.macAddress[i];
+ }
+ }
+ }
+
+ /*write the new addr filtering to h/w*/
+ for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
+ {
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_ADDR_MASK_1+i*sizeof(UINT32),
+ addressMask.macAddress[i]);
+ REG_WRITE(ixEthAccMacBase[portId],
+ IX_ETH_ACC_MAC_ADDR_1+i*sizeof(UINT32),
+ address.macAddress[i]);
+ }
+}
diff --git a/cpu/ixp/npe/IxEthAccMii.c b/cpu/ixp/npe/IxEthAccMii.c
new file mode 100644
index 0000000..86368a4
--- /dev/null
+++ b/cpu/ixp/npe/IxEthAccMii.c
@@ -0,0 +1,410 @@
+/**
+ * @file IxEthAccMii.c
+ *
+ * @author Intel Corporation
+ * @date
+ *
+ * @brief MII control functions
+ *
+ * Design Notes:
+ *
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxOsal.h"
+#include "IxEthAcc.h"
+#include "IxEthAcc_p.h"
+#include "IxEthAccMac_p.h"
+#include "IxEthAccMii_p.h"
+
+
+PRIVATE UINT32 miiBaseAddressVirt;
+PRIVATE IxOsalMutex miiAccessLock;
+
+PUBLIC UINT32 ixEthAccMiiRetryCount = IX_ETH_ACC_MII_TIMEOUT_10TH_SECS;
+PUBLIC UINT32 ixEthAccMiiAccessTimeout = IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS;
+
+/* -----------------------------------
+ * private function prototypes
+ */
+PRIVATE void
+ixEthAccMdioCmdWrite(UINT32 mdioCommand);
+
+PRIVATE void
+ixEthAccMdioCmdRead(UINT32 *data);
+
+PRIVATE void
+ixEthAccMdioStatusRead(UINT32 *data);
+
+
+PRIVATE void
+ixEthAccMdioCmdWrite(UINT32 mdioCommand)
+{
+ REG_WRITE(miiBaseAddressVirt,
+ IX_ETH_ACC_MAC_MDIO_CMD_1,
+ mdioCommand & 0xff);
+
+ REG_WRITE(miiBaseAddressVirt,
+ IX_ETH_ACC_MAC_MDIO_CMD_2,
+ (mdioCommand >> 8) & 0xff);
+
+ REG_WRITE(miiBaseAddressVirt,
+ IX_ETH_ACC_MAC_MDIO_CMD_3,
+ (mdioCommand >> 16) & 0xff);
+
+ REG_WRITE(miiBaseAddressVirt,
+ IX_ETH_ACC_MAC_MDIO_CMD_4,
+ (mdioCommand >> 24) & 0xff);
+}
+
+PRIVATE void
+ixEthAccMdioCmdRead(UINT32 *data)
+{
+ UINT32 regval;
+
+ REG_READ(miiBaseAddressVirt,
+ IX_ETH_ACC_MAC_MDIO_CMD_1,
+ regval);
+
+ *data = regval & 0xff;
+
+ REG_READ(miiBaseAddressVirt,
+ IX_ETH_ACC_MAC_MDIO_CMD_2,
+ regval);
+
+ *data |= (regval & 0xff) << 8;
+
+ REG_READ(miiBaseAddressVirt,
+ IX_ETH_ACC_MAC_MDIO_CMD_3,
+ regval);
+
+ *data |= (regval & 0xff) << 16;
+
+ REG_READ(miiBaseAddressVirt,
+ IX_ETH_ACC_MAC_MDIO_CMD_4,
+ regval);
+
+ *data |= (regval & 0xff) << 24;
+
+}
+
+PRIVATE void
+ixEthAccMdioStatusRead(UINT32 *data)
+{
+ UINT32 regval;
+
+ REG_READ(miiBaseAddressVirt,
+ IX_ETH_ACC_MAC_MDIO_STS_1,
+ regval);
+
+ *data = regval & 0xff;
+
+ REG_READ(miiBaseAddressVirt,
+ IX_ETH_ACC_MAC_MDIO_STS_2,
+ regval);
+
+ *data |= (regval & 0xff) << 8;
+
+ REG_READ(miiBaseAddressVirt,
+ IX_ETH_ACC_MAC_MDIO_STS_3,
+ regval);
+
+ *data |= (regval & 0xff) << 16;
+
+ REG_READ(miiBaseAddressVirt,
+ IX_ETH_ACC_MAC_MDIO_STS_4,
+ regval);
+
+ *data |= (regval & 0xff) << 24;
+
+}
+
+
+/********************************************************************
+ * ixEthAccMiiInit
+ */
+IxEthAccStatus
+ixEthAccMiiInit()
+{
+ if(ixOsalMutexInit(&miiAccessLock)!= IX_SUCCESS)
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+
+ miiBaseAddressVirt = (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE, IX_OSAL_IXP400_ETHA_MAP_SIZE);
+
+ if (miiBaseAddressVirt == 0)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "EthAcc: Could not map MII I/O mapped memory\n",
+ 0, 0, 0, 0, 0, 0);
+
+ return IX_ETH_ACC_FAIL;
+ }
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+void
+ixEthAccMiiUnload(void)
+{
+ IX_OSAL_MEM_UNMAP(miiBaseAddressVirt);
+
+ miiBaseAddressVirt = 0;
+}
+
+PUBLIC IxEthAccStatus
+ixEthAccMiiAccessTimeoutSet(UINT32 timeout, UINT32 retryCount)
+{
+ if (retryCount < 1) return IX_ETH_ACC_FAIL;
+
+ ixEthAccMiiRetryCount = retryCount;
+ ixEthAccMiiAccessTimeout = timeout;
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+/*********************************************************************
+ * ixEthAccMiiReadRtn - read a 16 bit value from a PHY
+ */
+IxEthAccStatus
+ixEthAccMiiReadRtn (UINT8 phyAddr,
+ UINT8 phyReg,
+ UINT16 *value)
+{
+ UINT32 mdioCommand;
+ UINT32 regval;
+ UINT32 miiTimeout;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR)
+ || (phyReg >= IXP425_ETH_ACC_MII_MAX_REG))
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ if (value == NULL)
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
+ mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL
+ | phyAddr << IX_ETH_ACC_MII_ADDR_SHL;
+ mdioCommand |= IX_ETH_ACC_MII_GO;
+
+ ixEthAccMdioCmdWrite(mdioCommand);
+
+ miiTimeout = ixEthAccMiiRetryCount;
+
+ while(miiTimeout)
+ {
+
+ ixEthAccMdioCmdRead(&regval);
+
+ if((regval & IX_ETH_ACC_MII_GO) == 0x0)
+ {
+ break;
+ }
+ /* Sleep for a while */
+ ixOsalSleep(ixEthAccMiiAccessTimeout);
+ miiTimeout--;
+ }
+
+
+
+ if(miiTimeout == 0)
+ {
+ ixOsalMutexUnlock(&miiAccessLock);
+ *value = 0xffff;
+ return IX_ETH_ACC_FAIL;
+ }
+
+
+ ixEthAccMdioStatusRead(&regval);
+ if(regval & IX_ETH_ACC_MII_READ_FAIL)
+ {
+ ixOsalMutexUnlock(&miiAccessLock);
+ *value = 0xffff;
+ return IX_ETH_ACC_FAIL;
+ }
+
+ *value = regval & 0xffff;
+ ixOsalMutexUnlock(&miiAccessLock);
+ return IX_ETH_ACC_SUCCESS;
+
+}
+
+
+/*********************************************************************
+ * ixEthAccMiiWriteRtn - write a 16 bit value to a PHY
+ */
+IxEthAccStatus
+ixEthAccMiiWriteRtn (UINT8 phyAddr,
+ UINT8 phyReg,
+ UINT16 value)
+{
+ UINT32 mdioCommand;
+ UINT32 regval;
+ UINT16 readVal;
+ UINT32 miiTimeout;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR)
+ || (phyReg >= IXP425_ETH_ACC_MII_MAX_REG))
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ /* ensure that a PHY is present at this address */
+ if(ixEthAccMiiReadRtn(phyAddr,
+ IX_ETH_ACC_MII_CTRL_REG,
+ &readVal) != IX_ETH_ACC_SUCCESS)
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
+ mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL
+ | phyAddr << IX_ETH_ACC_MII_ADDR_SHL ;
+ mdioCommand |= IX_ETH_ACC_MII_GO | IX_ETH_ACC_MII_WRITE | value;
+
+ ixEthAccMdioCmdWrite(mdioCommand);
+
+ miiTimeout = ixEthAccMiiRetryCount;
+
+ while(miiTimeout)
+ {
+
+ ixEthAccMdioCmdRead(&regval);
+
+ /*The "GO" bit is reset to 0 when the write completes*/
+ if((regval & IX_ETH_ACC_MII_GO) == 0x0)
+ {
+ break;
+ }
+ /* Sleep for a while */
+ ixOsalSleep(ixEthAccMiiAccessTimeout);
+ miiTimeout--;
+ }
+
+ ixOsalMutexUnlock(&miiAccessLock);
+ if(miiTimeout == 0)
+ {
+ return IX_ETH_ACC_FAIL;
+ }
+ return IX_ETH_ACC_SUCCESS;
+}
+
+
+/*****************************************************************
+ *
+ * Phy query functions
+ *
+ */
+IxEthAccStatus
+ixEthAccMiiStatsShow (UINT32 phyAddr)
+{
+ UINT16 regval;
+ printf("Regisers on PHY at address 0x%x\n", phyAddr);
+ ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_CTRL_REG, &regval);
+ printf(" Control Register : 0x%4.4x\n", regval);
+ ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_STAT_REG, &regval);
+ printf(" Status Register : 0x%4.4x\n", regval);
+ ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID1_REG, &regval);
+ printf(" PHY ID1 Register : 0x%4.4x\n", regval);
+ ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID2_REG, &regval);
+ printf(" PHY ID2 Register : 0x%4.4x\n", regval);
+ ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_ADS_REG, &regval);
+ printf(" Auto Neg ADS Register : 0x%4.4x\n", regval);
+ ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_PRTN_REG, &regval);
+ printf(" Auto Neg Partner Ability Register : 0x%4.4x\n", regval);
+ ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_EXP_REG, &regval);
+ printf(" Auto Neg Expansion Register : 0x%4.4x\n", regval);
+ ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_NEXT_REG, &regval);
+ printf(" Auto Neg Next Register : 0x%4.4x\n", regval);
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
+
+/*****************************************************************
+ *
+ * Interface query functions
+ *
+ */
+IxEthAccStatus
+ixEthAccMdioShow (void)
+{
+ UINT32 regval;
+
+ if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+ {
+ return (IX_ETH_ACC_FAIL);
+ }
+
+ ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
+ ixEthAccMdioCmdRead(&regval);
+ ixOsalMutexUnlock(&miiAccessLock);
+
+ printf("MDIO command register\n");
+ printf(" Go bit : 0x%x\n", (regval & BIT(31)) >> 31);
+ printf(" MDIO Write : 0x%x\n", (regval & BIT(26)) >> 26);
+ printf(" PHY address : 0x%x\n", (regval >> 21) & 0x1f);
+ printf(" Reg address : 0x%x\n", (regval >> 16) & 0x1f);
+
+ ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
+ ixEthAccMdioStatusRead(&regval);
+ ixOsalMutexUnlock(&miiAccessLock);
+
+ printf("MDIO status register\n");
+ printf(" Read OK : 0x%x\n", (regval & BIT(31)) >> 31);
+ printf(" Read Data : 0x%x\n", (regval >> 16) & 0xff);
+
+ return IX_ETH_ACC_SUCCESS;
+}
+
diff --git a/cpu/ixp/npe/IxEthDBAPI.c b/cpu/ixp/npe/IxEthDBAPI.c
new file mode 100644
index 0000000..b2bfb72
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBAPI.c
@@ -0,0 +1,448 @@
+/**
+ * @file IxEthDBAPI.c
+ *
+ * @brief Implementation of the public API
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB_p.h"
+#include "IxFeatureCtrl.h"
+
+extern HashTable dbHashtable;
+extern IxEthDBPortMap overflowUpdatePortList;
+extern BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
+
+ return ixEthDBTriggerAddPortUpdate(macAddr, portID, TRUE);
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
+
+ return ixEthDBTriggerAddPortUpdate(macAddr, portID, FALSE);
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr)
+{
+ HashNode *searchResult;
+
+ IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+ searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
+
+ if (searchResult == NULL)
+ {
+ return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
+ }
+
+ ixEthDBReleaseHashNode(searchResult);
+
+ /* build a remove event and place it on the event queue */
+ return ixEthDBTriggerRemovePortUpdate(macAddr, ((MacDescriptor *) searchResult->data)->portID);
+}
+
+IX_ETH_DB_PUBLIC
+void ixEthDBDatabaseMaintenance()
+{
+ HashIterator iterator;
+ UINT32 portIndex;
+ BOOL agingRequired = FALSE;
+
+ /* ports who will have deleted records and therefore will need updating */
+ IxEthDBPortMap triggerPorts;
+
+ if (IX_FEATURE_CTRL_SWCONFIG_ENABLED !=
+ ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
+ {
+ return;
+ }
+
+ SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
+
+ /* check if there's at least a port that needs aging */
+ for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+ {
+ if (ixEthDBPortInfo[portIndex].agingEnabled && ixEthDBPortInfo[portIndex].enabled)
+ {
+ agingRequired = TRUE;
+ }
+ }
+
+ if (agingRequired)
+ {
+ /* ask each NPE port to write back the database for aging inspection */
+ for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+ {
+ if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE
+ && ixEthDBPortInfo[portIndex].agingEnabled
+ && ixEthDBPortInfo[portIndex].enabled)
+ {
+ IxNpeMhMessage message;
+ IX_STATUS result;
+
+ /* send EDB_GetMACAddressDatabase message */
+ FILL_GETMACADDRESSDATABASE(message,
+ 0 /* unused */,
+ IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone));
+
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), message, result);
+
+ if (result == IX_SUCCESS)
+ {
+ /* analyze NPE copy */
+ ixEthDBNPESyncScan(portIndex, ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone, FULL_ELT_BYTE_SIZE);
+
+ IX_ETH_DB_SUPPORT_TRACE("DB: (API) Finished scanning NPE tree on port %d\n", portIndex);
+ }
+ else
+ {
+ ixEthDBPortInfo[portIndex].agingEnabled = FALSE;
+ ixEthDBPortInfo[portIndex].updateMethod.updateEnabled = FALSE;
+ ixEthDBPortInfo[portIndex].updateMethod.userControlled = TRUE;
+
+ ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "EthDB: (Maintenance) warning, disabling aging and updates for port %d (assumed dead)\n",
+ portIndex, 0, 0, 0, 0, 0);
+
+ ixEthDBDatabaseClear(portIndex, IX_ETH_DB_ALL_RECORD_TYPES);
+ }
+ }
+ }
+
+ /* browse database and age entries */
+ BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
+
+ while (IS_ITERATOR_VALID(&iterator))
+ {
+ MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
+ UINT32 *age = NULL;
+ BOOL staticEntry = TRUE;
+
+ if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
+ {
+ age = &descriptor->recordData.filteringData.age;
+ staticEntry = descriptor->recordData.filteringData.staticEntry;
+ }
+ else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
+ {
+ age = &descriptor->recordData.filteringVlanData.age;
+ staticEntry = descriptor->recordData.filteringVlanData.staticEntry;
+ }
+ else
+ {
+ staticEntry = TRUE;
+ }
+
+ if (ixEthDBPortInfo[descriptor->portID].agingEnabled && (staticEntry == FALSE))
+ {
+ /* manually increment the age if the port has no such capability */
+ if ((ixEthDBPortDefinitions[descriptor->portID].capabilities & IX_ETH_ENTRY_AGING) == 0)
+ {
+ *age += (IX_ETH_DB_MAINTENANCE_TIME / 60);
+ }
+
+ /* age entry if it exceeded the maximum time to live */
+ if (*age >= (IX_ETH_DB_LEARNING_ENTRY_AGE_TIME / 60))
+ {
+ /* add port to the set of update trigger ports */
+ JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
+
+ /* delete entry */
+ BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
+ }
+ else
+ {
+ /* move to the next record */
+ BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
+ }
+ }
+ else
+ {
+ /* move to the next record */
+ BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
+ }
+ }
+
+ /* update ports which lost records */
+ ixEthDBUpdatePortLearningTrees(triggerPorts);
+ }
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType)
+{
+ IxEthDBPortMap triggerPorts;
+ HashIterator iterator;
+
+ if (portID >= IX_ETH_DB_NUMBER_OF_PORTS && portID != IX_ETH_DB_ALL_PORTS)
+ {
+ return IX_ETH_DB_INVALID_PORT;
+ }
+
+ /* check if the user passes some extra bits */
+ if ((recordType | IX_ETH_DB_ALL_RECORD_TYPES) != IX_ETH_DB_ALL_RECORD_TYPES)
+ {
+ return IX_ETH_DB_INVALID_ARG;
+ }
+
+ SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
+
+ /* browse database and age entries */
+ BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
+
+ while (IS_ITERATOR_VALID(&iterator))
+ {
+ MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
+
+ if (((descriptor->portID == portID) || (portID == IX_ETH_DB_ALL_PORTS))
+ && ((descriptor->type & recordType) != 0))
+ {
+ /* add to trigger if automatic updates are required */
+ if (ixEthDBPortUpdateRequired[descriptor->type])
+ {
+ /* add port to the set of update trigger ports */
+ JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
+ }
+
+ /* delete entry */
+ BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
+ }
+ else
+ {
+ /* move to the next record */
+ BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
+ }
+ }
+
+ /* update ports which lost records */
+ ixEthDBUpdatePortLearningTrees(triggerPorts);
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+{
+ HashNode *searchResult;
+ IxEthDBStatus result = IX_ETH_DB_NO_SUCH_ADDR;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
+
+ searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
+
+ if (searchResult == NULL)
+ {
+ return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
+ }
+
+ if (((MacDescriptor *) (searchResult->data))->portID == portID)
+ {
+ result = IX_ETH_DB_SUCCESS; /* address and port match */
+ }
+
+ ixEthDBReleaseHashNode(searchResult);
+
+ return result;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
+{
+ HashNode *searchResult;
+
+ IX_ETH_DB_CHECK_REFERENCE(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+ searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
+
+ if (searchResult == NULL)
+ {
+ return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
+ }
+
+ /* return the port ID */
+ *portID = ((MacDescriptor *) searchResult->data)->portID;
+
+ ixEthDBReleaseHashNode(searchResult);
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
+
+ ixEthDBPortInfo[portID].agingEnabled = FALSE;
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
+
+ ixEthDBPortInfo[portID].agingEnabled = TRUE;
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
+{
+ HashNode *searchResult;
+ MacDescriptor *descriptor;
+
+ IX_ETH_DB_CHECK_REFERENCE(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+ searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
+
+ if (searchResult == NULL)
+ {
+ return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
+ }
+
+ descriptor = (MacDescriptor *) searchResult->data;
+
+ /* return the port ID */
+ *portID = descriptor->portID;
+
+ /* reset entry age */
+ if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
+ {
+ descriptor->recordData.filteringData.age = 0;
+ }
+ else
+ {
+ descriptor->recordData.filteringVlanData.age = 0;
+ }
+
+ ixEthDBReleaseHashNode(searchResult);
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
+
+ /* force bit at offset 255 to 0 (reserved) */
+ dependencyPortMap[31] &= 0xFE;
+
+ COPY_DEPENDENCY_MAP(ixEthDBPortInfo[portID].dependencyPortMap, dependencyPortMap);
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
+
+ COPY_DEPENDENCY_MAP(dependencyPortMap, ixEthDBPortInfo[portID].dependencyPortMap);
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
+
+ ixEthDBPortInfo[portID].updateMethod.updateEnabled = enableUpdate;
+ ixEthDBPortInfo[portID].updateMethod.userControlled = TRUE;
+
+ return IX_ETH_DB_SUCCESS;
+}
diff --git a/cpu/ixp/npe/IxEthDBAPISupport.c b/cpu/ixp/npe/IxEthDBAPISupport.c
new file mode 100644
index 0000000..25633a3
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBAPISupport.c
@@ -0,0 +1,678 @@
+/**
+ * @file IxEthDBAPISupport.c
+ *
+ * @brief Public API support functions
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include <IxEthDB.h>
+#include <IxNpeMh.h>
+#include <IxFeatureCtrl.h>
+
+#include "IxEthDB_p.h"
+#include "IxEthDBMessages_p.h"
+#include "IxEthDB_p.h"
+#include "IxEthDBLog_p.h"
+
+#ifdef IX_UNIT_TEST
+
+int dbAccessCounter = 0;
+int overflowEvent = 0;
+
+#endif
+
+/*
+ * External declaration
+ */
+extern HashTable dbHashtable;
+
+/*
+ * Internal declaration
+ */
+IX_ETH_DB_PUBLIC
+PortInfo ixEthDBPortInfo[IX_ETH_DB_NUMBER_OF_PORTS];
+
+IX_ETH_DB_PRIVATE
+struct
+{
+ BOOL saved;
+ IxEthDBPriorityTable priorityTable;
+ IxEthDBVlanSet vlanMembership;
+ IxEthDBVlanSet transmitTaggingInfo;
+ IxEthDBFrameFilter frameFilter;
+ IxEthDBTaggingAction taggingAction;
+ IxEthDBFirewallMode firewallMode;
+ BOOL stpBlocked;
+ BOOL srcAddressFilterEnabled;
+ UINT32 maxRxFrameSize;
+ UINT32 maxTxFrameSize;
+} ixEthDBPortState[IX_ETH_DB_NUMBER_OF_PORTS];
+
+#define IX_ETH_DB_DEFAULT_FRAME_SIZE (1518)
+
+/**
+ * @brief initializes a port
+ *
+ * @param portID ID of the port to be initialized
+ *
+ * Note that redundant initializations are silently
+ * dealt with and do not constitute an error
+ *
+ * This function is fully documented in the main
+ * header file, IxEthDB.h
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBPortInit(IxEthDBPortId portID)
+{
+ PortInfo *portInfo;
+
+ if (portID >= IX_ETH_DB_NUMBER_OF_PORTS)
+ {
+ return;
+ }
+
+ portInfo = &ixEthDBPortInfo[portID];
+
+ if (ixEthDBSingleEthNpeCheck(portID) != IX_ETH_DB_SUCCESS)
+ {
+ WARNING_LOG("EthDB: Unavailable Eth %d: Cannot initialize EthDB Port.\n", (UINT32) portID);
+
+ return;
+ }
+
+ if (portInfo->initialized)
+ {
+ /* redundant */
+ return;
+ }
+
+ /* initialize core fields */
+ portInfo->portID = portID;
+ SET_DEPENDENCY_MAP(portInfo->dependencyPortMap, portID);
+
+ /* default values */
+ portInfo->agingEnabled = FALSE;
+ portInfo->enabled = FALSE;
+ portInfo->macAddressUploaded = FALSE;
+ portInfo->maxRxFrameSize = IX_ETHDB_DEFAULT_FRAME_SIZE;
+ portInfo->maxTxFrameSize = IX_ETHDB_DEFAULT_FRAME_SIZE;
+
+ /* default update control values */
+ portInfo->updateMethod.searchTree = NULL;
+ portInfo->updateMethod.searchTreePendingWrite = FALSE;
+ portInfo->updateMethod.treeInitialized = FALSE;
+ portInfo->updateMethod.updateEnabled = FALSE;
+ portInfo->updateMethod.userControlled = FALSE;
+
+ /* default WiFi parameters */
+ memset(portInfo->bbsid, 0, sizeof (portInfo->bbsid));
+ portInfo->frameControlDurationID = 0;
+
+ /* Ethernet NPE-specific initializations */
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ /* update handler */
+ portInfo->updateMethod.updateHandler = ixEthDBNPEUpdateHandler;
+ }
+
+ /* initialize state save */
+ ixEthDBPortState[portID].saved = FALSE;
+
+ portInfo->initialized = TRUE;
+}
+
+/**
+ * @brief enables a port
+ *
+ * @param portID ID of the port to enable
+ *
+ * This function is fully documented in the main
+ * header file, IxEthDB.h
+ *
+ * @return IX_ETH_DB_SUCCESS if enabling was
+ * accomplished, or a meaningful error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID)
+{
+ IxEthDBPortMap triggerPorts;
+ PortInfo *portInfo;
+
+ IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ portInfo = &ixEthDBPortInfo[portID];
+
+ if (portInfo->enabled)
+ {
+ /* redundant */
+ return IX_ETH_DB_SUCCESS;
+ }
+
+ SET_DEPENDENCY_MAP(triggerPorts, portID);
+
+ /* mark as enabled */
+ portInfo->enabled = TRUE;
+
+ /* Operation stops here when Ethernet Learning is not enabled */
+ if(IX_FEATURE_CTRL_SWCONFIG_DISABLED ==
+ ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
+ {
+ return IX_ETH_DB_SUCCESS;
+ }
+
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE && !portInfo->macAddressUploaded)
+ {
+ IX_ETH_DB_SUPPORT_TRACE("DB: (Support) MAC address not set on port %d, enable failed\n", portID);
+
+ /* must use UnicastAddressSet() before enabling an NPE port */
+ return IX_ETH_DB_MAC_UNINITIALIZED;
+ }
+
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Attempting to enable the NPE callback for port %d...\n", portID);
+
+ if (!portInfo->updateMethod.userControlled
+ && ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0))
+ {
+ portInfo->updateMethod.updateEnabled = TRUE;
+ }
+
+ /* if this is first time initialization then we already have
+ write access to the tree and can AccessRelease directly */
+ if (!portInfo->updateMethod.treeInitialized)
+ {
+ IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Initializing tree for port %d\n", portID);
+
+ /* create an initial tree and release access into it */
+ ixEthDBUpdatePortLearningTrees(triggerPorts);
+
+ /* mark tree as being initialized */
+ portInfo->updateMethod.treeInitialized = TRUE;
+ }
+ }
+
+ if (ixEthDBPortState[portID].saved)
+ {
+ /* previous configuration data stored, restore state */
+ if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
+ {
+ ixEthDBFirewallModeSet(portID, ixEthDBPortState[portID].firewallMode);
+ ixEthDBFirewallInvalidAddressFilterEnable(portID, ixEthDBPortState[portID].srcAddressFilterEnabled);
+ }
+
+#if 0 /* test-only */
+ if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
+ {
+ ixEthDBAcceptableFrameTypeSet(portID, ixEthDBPortState[portID].frameFilter);
+ ixEthDBIngressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].taggingAction);
+
+ ixEthDBEgressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].transmitTaggingInfo);
+ ixEthDBPortVlanMembershipSet(portID, ixEthDBPortState[portID].vlanMembership);
+
+ ixEthDBPriorityMappingTableSet(portID, ixEthDBPortState[portID].priorityTable);
+ }
+#endif
+
+ if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
+ {
+ ixEthDBSpanningTreeBlockingStateSet(portID, ixEthDBPortState[portID].stpBlocked);
+ }
+
+ ixEthDBFilteringPortMaximumRxFrameSizeSet(portID, ixEthDBPortState[portID].maxRxFrameSize);
+ ixEthDBFilteringPortMaximumTxFrameSizeSet(portID, ixEthDBPortState[portID].maxTxFrameSize);
+
+ /* discard previous save */
+ ixEthDBPortState[portID].saved = FALSE;
+ }
+
+ IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Enabling succeeded for port %d\n", portID);
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief disables a port
+ *
+ * @param portID ID of the port to disable
+ *
+ * This function is fully documented in the
+ * main header file, IxEthDB.h
+ *
+ * @return IX_ETH_DB_SUCCESS if disabling was
+ * successful or an appropriate error message
+ * otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID)
+{
+ HashIterator iterator;
+ IxEthDBPortMap triggerPorts; /* ports who will have deleted records and therefore will need updating */
+ BOOL result;
+ PortInfo *portInfo;
+ IxEthDBFeature learningEnabled;
+#if 0 /* test-only */
+ IxEthDBPriorityTable classZeroTable;
+#endif
+
+ IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ portInfo = &ixEthDBPortInfo[portID];
+
+ if (!portInfo->enabled)
+ {
+ /* redundant */
+ return IX_ETH_DB_SUCCESS;
+ }
+
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ /* save filtering state */
+ ixEthDBPortState[portID].firewallMode = portInfo->firewallMode;
+ ixEthDBPortState[portID].frameFilter = portInfo->frameFilter;
+ ixEthDBPortState[portID].taggingAction = portInfo->taggingAction;
+ ixEthDBPortState[portID].stpBlocked = portInfo->stpBlocked;
+ ixEthDBPortState[portID].srcAddressFilterEnabled = portInfo->srcAddressFilterEnabled;
+ ixEthDBPortState[portID].maxRxFrameSize = portInfo->maxRxFrameSize;
+ ixEthDBPortState[portID].maxTxFrameSize = portInfo->maxTxFrameSize;
+
+ memcpy(ixEthDBPortState[portID].vlanMembership, portInfo->vlanMembership, sizeof (IxEthDBVlanSet));
+ memcpy(ixEthDBPortState[portID].transmitTaggingInfo, portInfo->transmitTaggingInfo, sizeof (IxEthDBVlanSet));
+ memcpy(ixEthDBPortState[portID].priorityTable, portInfo->priorityTable, sizeof (IxEthDBPriorityTable));
+
+ ixEthDBPortState[portID].saved = TRUE;
+
+ /* now turn off all EthDB filtering features on the port */
+
+#if 0 /* test-only */
+ /* VLAN & QoS */
+ if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
+ {
+ ixEthDBPortVlanMembershipRangeAdd((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID);
+ ixEthDBEgressVlanRangeTaggingEnabledSet((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID, FALSE);
+ ixEthDBAcceptableFrameTypeSet((IxEthDBPortId) portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
+ ixEthDBIngressVlanTaggingEnabledSet((IxEthDBPortId) portID, IX_ETH_DB_PASS_THROUGH);
+
+ memset(classZeroTable, 0, sizeof (classZeroTable));
+ ixEthDBPriorityMappingTableSet((IxEthDBPortId) portID, classZeroTable);
+ }
+#endif
+
+ /* STP */
+ if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
+ {
+ ixEthDBSpanningTreeBlockingStateSet((IxEthDBPortId) portID, FALSE);
+ }
+
+ /* Firewall */
+ if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
+ {
+ ixEthDBFirewallModeSet((IxEthDBPortId) portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
+ ixEthDBFirewallTableDownload((IxEthDBPortId) portID);
+ ixEthDBFirewallInvalidAddressFilterEnable((IxEthDBPortId) portID, FALSE);
+ }
+
+ /* Frame size filter */
+ ixEthDBFilteringPortMaximumFrameSizeSet((IxEthDBPortId) portID, IX_ETH_DB_DEFAULT_FRAME_SIZE);
+
+ /* WiFi */
+ if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
+ {
+ ixEthDBWiFiConversionTableDownload((IxEthDBPortId) portID);
+ }
+
+ /* save and disable the learning feature bit */
+ learningEnabled = portInfo->featureStatus & IX_ETH_DB_LEARNING;
+ portInfo->featureStatus &= ~IX_ETH_DB_LEARNING;
+ }
+ else
+ {
+ /* save the learning feature bit */
+ learningEnabled = portInfo->featureStatus & IX_ETH_DB_LEARNING;
+ }
+
+ SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
+
+ ixEthDBUpdateLock();
+
+ /* wipe out current entries for this port */
+ BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
+
+ while (IS_ITERATOR_VALID(&iterator))
+ {
+ MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
+
+ /* check if the port match. If so, remove the entry */
+ if (descriptor->portID == portID
+ && (descriptor->type == IX_ETH_DB_FILTERING_RECORD || descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
+ && !descriptor->recordData.filteringData.staticEntry)
+ {
+ /* delete entry */
+ BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
+
+ /* add port to the set of update trigger ports */
+ JOIN_PORT_TO_MAP(triggerPorts, portID);
+ }
+ else
+ {
+ /* move to the next record */
+ BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
+ }
+ }
+
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ if (portInfo->updateMethod.searchTree != NULL)
+ {
+ ixEthDBFreeMacTreeNode(portInfo->updateMethod.searchTree);
+ portInfo->updateMethod.searchTree = NULL;
+ }
+
+ ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_FILTERING_RECORD);
+ }
+
+ /* mark as disabled */
+ portInfo->enabled = FALSE;
+
+ /* disable updates unless the user has specifically altered the default behavior */
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ if (!portInfo->updateMethod.userControlled)
+ {
+ portInfo->updateMethod.updateEnabled = FALSE;
+ }
+
+ /* make sure we re-initialize the NPE learning tree when the port is re-enabled */
+ portInfo->updateMethod.treeInitialized = FALSE;
+ }
+
+ ixEthDBUpdateUnlock();
+
+ /* restore learning feature bit */
+ portInfo->featureStatus |= learningEnabled;
+
+ /* if we've removed any records or lost any events make sure to force an update */
+ IS_EMPTY_DEPENDENCY_MAP(result, triggerPorts);
+
+ if (!result)
+ {
+ ixEthDBUpdatePortLearningTrees(triggerPorts);
+ }
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief sends the updated maximum Tx/Rx frame lengths to the NPE
+ *
+ * @param portID ID of the port to update
+ *
+ * @return IX_ETH_DB_SUCCESS if the update completed
+ * successfully or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBPortFrameLengthsUpdate(IxEthDBPortId portID)
+{
+ IxNpeMhMessage message;
+ PortInfo *portInfo = &ixEthDBPortInfo[portID];
+ IX_STATUS result;
+
+ FILL_SETMAXFRAMELENGTHS_MSG(message, portID, portInfo->maxRxFrameSize, portInfo->maxTxFrameSize);
+
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+ return result;
+}
+
+/**
+ * @brief sets the port maximum Rx frame size
+ *
+ * @param portID ID of the port to set the frame size on
+ * @param maximumRxFrameSize maximum Rx frame size
+ *
+ * This function updates the internal data structures and
+ * calls ixEthDBPortFrameLengthsUpdate() for NPE update.
+ *
+ * This function is fully documented in the main header
+ * file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation was
+ * successfull or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringPortMaximumRxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumRxFrameSize)
+{
+ IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ if (!ixEthDBPortInfo[portID].initialized)
+ {
+ return IX_ETH_DB_PORT_UNINITIALIZED;
+ }
+
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ if ((maximumRxFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
+ (maximumRxFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
+ {
+ return IX_ETH_DB_INVALID_ARG;
+ }
+ }
+ else
+ {
+ return IX_ETH_DB_NO_PERMISSION;
+ }
+
+ /* update internal structure */
+ ixEthDBPortInfo[portID].maxRxFrameSize = maximumRxFrameSize;
+
+ /* update the maximum frame size in the NPE */
+ return ixEthDBPortFrameLengthsUpdate(portID);
+}
+
+/**
+ * @brief sets the port maximum Tx frame size
+ *
+ * @param portID ID of the port to set the frame size on
+ * @param maximumTxFrameSize maximum Tx frame size
+ *
+ * This function updates the internal data structures and
+ * calls ixEthDBPortFrameLengthsUpdate() for NPE update.
+ *
+ * This function is fully documented in the main header
+ * file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation was
+ * successfull or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringPortMaximumTxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumTxFrameSize)
+{
+ IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ if (!ixEthDBPortInfo[portID].initialized)
+ {
+ return IX_ETH_DB_PORT_UNINITIALIZED;
+ }
+
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ if ((maximumTxFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
+ (maximumTxFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
+ {
+ return IX_ETH_DB_INVALID_ARG;
+ }
+ }
+ else
+ {
+ return IX_ETH_DB_NO_PERMISSION;
+ }
+
+ /* update internal structure */
+ ixEthDBPortInfo[portID].maxTxFrameSize = maximumTxFrameSize;
+
+ /* update the maximum frame size in the NPE */
+ return ixEthDBPortFrameLengthsUpdate(portID);
+}
+
+/**
+ * @brief sets the port maximum Tx and Rx frame sizes
+ *
+ * @param portID ID of the port to set the frame size on
+ * @param maximumFrameSize maximum Tx and Rx frame sizes
+ *
+ * This function updates the internal data structures and
+ * calls ixEthDBPortFrameLengthsUpdate() for NPE update.
+ *
+ * Note that both the maximum Tx and Rx frame size are set
+ * to the same value. This function is kept for compatibility
+ * reasons.
+ *
+ * This function is fully documented in the main header
+ * file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation was
+ * successfull or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize)
+{
+ IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ if (!ixEthDBPortInfo[portID].initialized)
+ {
+ return IX_ETH_DB_PORT_UNINITIALIZED;
+ }
+
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ if ((maximumFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
+ (maximumFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
+ {
+ return IX_ETH_DB_INVALID_ARG;
+ }
+ }
+ else
+ {
+ return IX_ETH_DB_NO_PERMISSION;
+ }
+
+ /* update internal structure */
+ ixEthDBPortInfo[portID].maxRxFrameSize = maximumFrameSize;
+ ixEthDBPortInfo[portID].maxTxFrameSize = maximumFrameSize;
+
+ /* update the maximum frame size in the NPE */
+ return ixEthDBPortFrameLengthsUpdate(portID);
+}
+
+/**
+ * @brief sets the MAC address of an NPE port
+ *
+ * @param portID port ID to set the MAC address on
+ * @param macAddr pointer to the 6-byte MAC address
+ *
+ * This function is called by the EthAcc
+ * ixEthAccUnicastMacAddressSet() and should not be
+ * manually invoked unless required by special circumstances.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation succeeded
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+{
+ IxNpeMhMessage message;
+ IxOsalMutex *ackPortAddressLock;
+ IX_STATUS result;
+
+ /* use this macro instead CHECK_PORT
+ as the port doesn't need to be enabled */
+ IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+ if (!ixEthDBPortInfo[portID].initialized)
+ {
+ return IX_ETH_DB_PORT_UNINITIALIZED;
+ }
+
+ ackPortAddressLock = &ixEthDBPortInfo[portID].npeAckLock;
+
+ /* Operation stops here when Ethernet Learning is not enabled */
+ if(IX_FEATURE_CTRL_SWCONFIG_DISABLED ==
+ ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
+ {
+ return IX_ETH_DB_SUCCESS;
+ }
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ /* exit if the port is not an Ethernet NPE */
+ if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE)
+ {
+ return IX_ETH_DB_INVALID_PORT;
+ }
+
+ /* populate message */
+ FILL_SETPORTADDRESS_MSG(message, portID, macAddr->macAddress);
+
+ IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Sending SetPortAddress on port %d...\n", portID);
+
+ /* send a SetPortAddress message */
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+ if (result == IX_SUCCESS)
+ {
+ ixEthDBPortInfo[portID].macAddressUploaded = TRUE;
+ }
+
+ return result;
+}
diff --git a/cpu/ixp/npe/IxEthDBCore.c b/cpu/ixp/npe/IxEthDBCore.c
new file mode 100644
index 0000000..25b7cbb
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBCore.c
@@ -0,0 +1,463 @@
+/**
+ * @file IxEthDBDBCore.c
+ *
+ * @brief Database support functions
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB_p.h"
+
+/* list of database hashtables */
+IX_ETH_DB_PUBLIC HashTable dbHashtable;
+IX_ETH_DB_PUBLIC MatchFunction matchFunctions[IX_ETH_DB_MAX_KEY_INDEX + 1];
+IX_ETH_DB_PUBLIC BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
+IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyType[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
+
+/* private initialization flag */
+IX_ETH_DB_PRIVATE BOOL ethDBInitializationComplete = FALSE;
+
+/**
+ * @brief initializes EthDB
+ *
+ * This function must be called to initialize the component.
+ *
+ * It does the following things:
+ * - checks the port definition structure
+ * - scans the capabilities of the NPE images and sets the
+ * capabilities of the ports accordingly
+ * - initializes the memory pools internally used in EthDB
+ * for storing database records and handling data
+ * - registers automatic update handlers for add and remove
+ * operations
+ * - registers hashing match functions, depending on key sets
+ * - initializes the main database hashtable
+ * - allocates contiguous memory zones to be used for NPE
+ * updates
+ * - registers the serialize methods used to convert data
+ * into NPE-readable format
+ * - starts the event processor
+ *
+ * Note that this function is documented in the public
+ * component header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS or an appropriate error if the
+ * component failed to initialize correctly
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBInit(void)
+{
+ IxEthDBStatus result;
+
+ if (ethDBInitializationComplete)
+ {
+ /* redundant */
+ return IX_ETH_DB_SUCCESS;
+ }
+
+ /* trap an invalid port definition structure */
+ IX_ETH_DB_PORTS_ASSERTION;
+
+ /* memory management */
+ ixEthDBInitMemoryPools();
+
+ /* register hashing search methods */
+ ixEthDBMatchMethodsRegister(matchFunctions);
+
+ /* register type-based automatic port updates */
+ ixEthDBUpdateTypeRegister(ixEthDBPortUpdateRequired);
+
+ /* register record to key type mappings */
+ ixEthDBKeyTypeRegister(ixEthDBKeyType);
+
+ /* hash table */
+ ixEthDBInitHash(&dbHashtable, NUM_BUCKETS, ixEthDBEntryXORHash, matchFunctions, (FreeFunction) ixEthDBFreeMacDescriptor);
+
+ /* NPE update zones */
+ ixEthDBNPEUpdateAreasInit();
+
+ /* register record serialization methods */
+ ixEthDBRecordSerializeMethodsRegister();
+
+ /* start the event processor */
+ result = ixEthDBEventProcessorInit();
+
+ /* scan NPE features */
+ if (result == IX_ETH_DB_SUCCESS)
+ {
+ ixEthDBFeatureCapabilityScan();
+ }
+
+ ethDBInitializationComplete = TRUE;
+
+ return result;
+}
+
+/**
+ * @brief prepares EthDB for unloading
+ *
+ * This function must be called before removing the
+ * EthDB component from memory (e.g. doing rmmod in
+ * Linux) if the component is to be re-initialized again
+ * without rebooting the platform.
+ *
+ * All the EthDB ports must be disabled before this
+ * function is to be called. Failure to disable all
+ * the ports will return the IX_ETH_DB_BUSY error.
+ *
+ * This function will destroy mutexes, deallocate
+ * memory and stop the event processor.
+ *
+ * Note that this function is fully documented in the
+ * main component header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if de-initialization
+ * completed successfully or an appropriate error
+ * message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBUnload(void)
+{
+ IxEthDBPortId portIndex;
+
+ if (!ethDBInitializationComplete)
+ {
+ /* redundant */
+ return IX_ETH_DB_SUCCESS;
+ }
+
+ /* check if any ports are enabled */
+ for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+ {
+ if (ixEthDBPortInfo[portIndex].enabled)
+ {
+ return IX_ETH_DB_BUSY;
+ }
+ }
+
+ /* free port resources */
+ for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+ {
+ if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
+ {
+ ixOsalMutexDestroy(&ixEthDBPortInfo[portIndex].npeAckLock);
+ }
+
+ ixEthDBPortInfo[portIndex].initialized = FALSE;
+ }
+
+ /* shutdown event processor */
+ ixEthDBStopLearningFunction();
+
+ /* deallocate NPE update zones */
+ ixEthDBNPEUpdateAreasUnload();
+
+ ethDBInitializationComplete = FALSE;
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief adds a new entry to the Ethernet database
+ *
+ * @param newRecordTemplate address of the record template to use
+ * @param updateTrigger port map containing the update triggers
+ * resulting from this update operation
+ *
+ * Creates a new database entry, populates it with the data
+ * copied from the given template and adds the record to the
+ * database hash table.
+ * It also checks whether the new record type is registered to trigger
+ * automatic updates; if it is, the update trigger will contain the
+ * port on which the record insertion was performed, as well as the
+ * old port in case the addition was a record migration (from one port
+ * to the other). The caller can use the updateTrigger to trigger
+ * automatic updates on the ports changed as a result of this addition.
+ *
+ * @retval IX_ETH_DB_SUCCESS addition successful
+ * @retval IX_ETH_DB_NOMEM insertion failed, no memory left in the mac descriptor memory pool
+ * @retval IX_ETH_DB_BUSY database busy, cannot insert due to locking
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBAdd(MacDescriptor *newRecordTemplate, IxEthDBPortMap updateTrigger)
+{
+ IxEthDBStatus result;
+ MacDescriptor *newDescriptor;
+ IxEthDBPortId originalPortID;
+ HashNode *node = NULL;
+
+ BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, ixEthDBKeyType[newRecordTemplate->type], newRecordTemplate, &node));
+
+ TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
+
+ if (node == NULL)
+ {
+ /* not found, create a new one */
+ newDescriptor = ixEthDBAllocMacDescriptor();
+
+ if (newDescriptor == NULL)
+ {
+ return IX_ETH_DB_NOMEM; /* no memory */
+ }
+
+ /* old port does not exist, avoid unnecessary updates */
+ originalPortID = newRecordTemplate->portID;
+ }
+ else
+ {
+ /* a node with the same key exists, will update node */
+ newDescriptor = (MacDescriptor *) node->data;
+
+ /* save original port id */
+ originalPortID = newDescriptor->portID;
+ }
+
+ /* copy/update fields into new record */
+ memcpy(newDescriptor->macAddress, newRecordTemplate->macAddress, sizeof (IxEthDBMacAddr));
+ memcpy(&newDescriptor->recordData, &newRecordTemplate->recordData, sizeof (IxEthDBRecordData));
+
+ newDescriptor->type = newRecordTemplate->type;
+ newDescriptor->portID = newRecordTemplate->portID;
+ newDescriptor->user = newRecordTemplate->user;
+
+ if (node == NULL)
+ {
+ /* new record, insert into hashtable */
+ BUSY_RETRY_WITH_RESULT(ixEthDBAddHashEntry(&dbHashtable, newDescriptor), result);
+
+ if (result != IX_ETH_DB_SUCCESS)
+ {
+ ixEthDBFreeMacDescriptor(newDescriptor);
+
+ return result; /* insertion failed */
+ }
+ }
+
+ if (node != NULL)
+ {
+ /* release access */
+ ixEthDBReleaseHashNode(node);
+ }
+
+ /* trigger add/remove update if required by type */
+ if (updateTrigger != NULL &&
+ ixEthDBPortUpdateRequired[newRecordTemplate->type])
+ {
+ /* add new port to update list */
+ JOIN_PORT_TO_MAP(updateTrigger, newRecordTemplate->portID);
+
+ /* check if record has moved, we'll need to update the old port as well */
+ if (originalPortID != newDescriptor->portID)
+ {
+ JOIN_PORT_TO_MAP(updateTrigger, originalPortID);
+ }
+ }
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief remove a record from the Ethernet database
+ *
+ * @param templateRecord template record used to determine
+ * what record is to be removed
+ * @param updateTrigger port map containing the update triggers
+ * resulting from this update operation
+ *
+ * This function will examine the template record it receives
+ * and attempts to delete a record of the same type and containing
+ * the same keys as the template record. If deletion is successful
+ * and the record type is registered for automatic port updates the
+ * port will also be set in the updateTrigger port map, so that the
+ * client can perform an update of the port.
+ *
+ * @retval IX_ETH_DB_SUCCESS removal was successful
+ * @retval IX_ETH_DB_NO_SUCH_ADDR the record with the given MAC address was not found
+ * @retval IX_ETH_DB_BUSY database busy, cannot remove due to locking
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBRemove(MacDescriptor *templateRecord, IxEthDBPortMap updateTrigger)
+{
+ IxEthDBStatus result;
+
+ TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
+
+ BUSY_RETRY_WITH_RESULT(ixEthDBRemoveHashEntry(&dbHashtable, ixEthDBKeyType[templateRecord->type], templateRecord), result);
+
+ if (result != IX_ETH_DB_SUCCESS)
+ {
+ return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
+ }
+
+ /* trigger add/remove update if required by type */
+ if (updateTrigger != NULL
+ &&ixEthDBPortUpdateRequired[templateRecord->type])
+ {
+ /* add new port to update list */
+ JOIN_PORT_TO_MAP(updateTrigger, templateRecord->portID);
+ }
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief register record key types
+ *
+ * This function registers the appropriate key types,
+ * depending on record types.
+ *
+ * All filtering records use the MAC address as the key.
+ * WiFi and Firewall records use a compound key consisting
+ * in both the MAC address and the port ID.
+ *
+ * @return the number of registered record types
+ */
+IX_ETH_DB_PUBLIC
+UINT32 ixEthDBKeyTypeRegister(UINT32 *keyType)
+{
+ /* safety */
+ memset(keyType, 0, sizeof (keyType));
+
+ /* register all known record types */
+ keyType[IX_ETH_DB_FILTERING_RECORD] = IX_ETH_DB_MAC_KEY;
+ keyType[IX_ETH_DB_FILTERING_VLAN_RECORD] = IX_ETH_DB_MAC_KEY;
+ keyType[IX_ETH_DB_ALL_FILTERING_RECORDS] = IX_ETH_DB_MAC_KEY;
+ keyType[IX_ETH_DB_WIFI_RECORD] = IX_ETH_DB_MAC_PORT_KEY;
+ keyType[IX_ETH_DB_FIREWALL_RECORD] = IX_ETH_DB_MAC_PORT_KEY;
+
+ return 5;
+}
+
+/**
+ * @brief Sets a user-defined field into a database record
+ *
+ * Note that this function is fully documented in the main component
+ * header file.
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field)
+{
+ HashNode *result = NULL;
+
+ if (macAddr == NULL)
+ {
+ return IX_ETH_DB_INVALID_ARG;
+ }
+
+ if (recordType == IX_ETH_DB_FILTERING_RECORD)
+ {
+ result = ixEthDBSearch(macAddr, recordType);
+ }
+ else if (recordType == IX_ETH_DB_FILTERING_VLAN_RECORD)
+ {
+ result = ixEthDBVlanSearch(macAddr, vlanID, recordType);
+ }
+ else if (recordType == IX_ETH_DB_WIFI_RECORD || recordType == IX_ETH_DB_FIREWALL_RECORD)
+ {
+ IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+ result = ixEthDBPortSearch(macAddr, portID, recordType);
+ }
+ else
+ {
+ return IX_ETH_DB_INVALID_ARG;
+ }
+
+ if (result == NULL)
+ {
+ return IX_ETH_DB_NO_SUCH_ADDR;
+ }
+
+ ((MacDescriptor *) result->data)->user = field;
+
+ ixEthDBReleaseHashNode(result);
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief Retrieves a user-defined field from a database record
+ *
+ * Note that this function is fully documented in the main component
+ * header file.
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void **field)
+{
+ HashNode *result = NULL;
+
+ if (macAddr == NULL || field == NULL)
+ {
+ return IX_ETH_DB_INVALID_ARG;
+ }
+
+ if (recordType == IX_ETH_DB_FILTERING_RECORD)
+ {
+ result = ixEthDBSearch(macAddr, recordType);
+ }
+ else if (recordType == IX_ETH_DB_FILTERING_VLAN_RECORD)
+ {
+ result = ixEthDBVlanSearch(macAddr, vlanID, recordType);
+ }
+ else if (recordType == IX_ETH_DB_WIFI_RECORD || recordType == IX_ETH_DB_FIREWALL_RECORD)
+ {
+ IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+ result = ixEthDBPortSearch(macAddr, portID, recordType);
+ }
+ else
+ {
+ return IX_ETH_DB_INVALID_ARG;
+ }
+
+ if (result == NULL)
+ {
+ return IX_ETH_DB_NO_SUCH_ADDR;
+ }
+
+ *field = ((MacDescriptor *) result->data)->user;
+
+ ixEthDBReleaseHashNode(result);
+
+ return IX_ETH_DB_SUCCESS;
+}
diff --git a/cpu/ixp/npe/IxEthDBEvents.c b/cpu/ixp/npe/IxEthDBEvents.c
new file mode 100644
index 0000000..4d44e03
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBEvents.c
@@ -0,0 +1,520 @@
+/**
+ * @file IxEthDBEvents.c
+ *
+ * @brief Implementation of the event processor component
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include <IxNpeMh.h>
+#include <IxFeatureCtrl.h>
+
+#include "IxEthDB_p.h"
+
+/* forward prototype declarations */
+IX_ETH_DB_PUBLIC void ixEthDBEventProcessorLoop(void *);
+IX_ETH_DB_PUBLIC void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
+IX_ETH_DB_PRIVATE void ixEthDBProcessEvent(PortEvent *local_event, IxEthDBPortMap triggerPorts);
+IX_ETH_DB_PRIVATE IxEthDBStatus ixEthDBTriggerPortUpdate(UINT32 eventType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStartLearningFunction(void);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStopLearningFunction(void);
+
+/* data */
+IX_ETH_DB_PRIVATE IxOsalSemaphore eventQueueSemaphore;
+IX_ETH_DB_PRIVATE PortEventQueue eventQueue;
+IX_ETH_DB_PRIVATE IxOsalMutex eventQueueLock;
+IX_ETH_DB_PRIVATE IxOsalMutex portUpdateLock;
+
+IX_ETH_DB_PRIVATE BOOL ixEthDBLearningShutdown = FALSE;
+IX_ETH_DB_PRIVATE BOOL ixEthDBEventProcessorRunning = FALSE;
+
+/* imported data */
+extern HashTable dbHashtable;
+
+/**
+ * @brief initializes the event processor
+ *
+ * Initializes the event processor queue and processing thread.
+ * Called from ixEthDBInit() DB-subcomponent master init function.
+ *
+ * @warning do not call directly
+ *
+ * @retval IX_ETH_DB_SUCCESS initialization was successful
+ * @retval IX_ETH_DB_FAIL initialization failed (OSAL or mutex init failure)
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBEventProcessorInit(void)
+{
+ if (ixOsalMutexInit(&portUpdateLock) != IX_SUCCESS)
+ {
+ return IX_ETH_DB_FAIL;
+ }
+
+ if (ixOsalMutexInit(&eventQueueLock) != IX_SUCCESS)
+ {
+ return IX_ETH_DB_FAIL;
+ }
+
+ if (IX_FEATURE_CTRL_SWCONFIG_ENABLED ==
+ ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
+ {
+
+ /* start processor loop thread */
+ if (ixEthDBStartLearningFunction() != IX_ETH_DB_SUCCESS)
+ {
+ return IX_ETH_DB_FAIL;
+ }
+ }
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief initializes the event queue and the event processor
+ *
+ * This function is called by the component initialization
+ * function, ixEthDBInit().
+ *
+ * @warning do not call directly
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or IX_ETH_DB_FAIL otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBStartLearningFunction(void)
+{
+ IxOsalThread eventProcessorThread;
+ IxOsalThreadAttr threadAttr;
+
+ threadAttr.name = "EthDB event thread";
+ threadAttr.stackSize = 32 * 1024; /* 32kbytes */
+ threadAttr.priority = 128;
+
+ /* reset event queue */
+ ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER);
+
+ RESET_QUEUE(&eventQueue);
+
+ ixOsalMutexUnlock(&eventQueueLock);
+
+ /* init event queue semaphore */
+ if (ixOsalSemaphoreInit(&eventQueueSemaphore, 0) != IX_SUCCESS)
+ {
+ return IX_ETH_DB_FAIL;
+ }
+
+ ixEthDBLearningShutdown = FALSE;
+
+ /* create processor loop thread */
+ if (ixOsalThreadCreate(&eventProcessorThread, &threadAttr, ixEthDBEventProcessorLoop, NULL) != IX_SUCCESS)
+ {
+ return IX_ETH_DB_FAIL;
+ }
+
+ /* start event processor */
+ ixOsalThreadStart(&eventProcessorThread);
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief stops the event processor
+ *
+ * Stops the event processor and frees the event queue semaphore
+ * Called by the component de-initialization function, ixEthDBUnload()
+ *
+ * @warning do not call directly
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or IX_ETH_DB_FAIL otherwise;
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBStopLearningFunction(void)
+{
+ ixEthDBLearningShutdown = TRUE;
+
+ /* wake up event processing loop to actually process the shutdown event */
+ ixOsalSemaphorePost(&eventQueueSemaphore);
+
+ if (ixOsalSemaphoreDestroy(&eventQueueSemaphore) != IX_SUCCESS)
+ {
+ return IX_ETH_DB_FAIL;
+ }
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief default NPE event processing callback
+ *
+ * @param npeID ID of the NPE that generated the event
+ * @param msg NPE message (encapsulated event)
+ *
+ * Creates an event object on the Ethernet event processor queue
+ * and signals the new event by incrementing the event queue semaphore.
+ * Events are processed by @ref ixEthDBEventProcessorLoop() which runs
+ * at user level.
+ *
+ * @see ixEthDBEventProcessorLoop()
+ *
+ * @warning do not call directly
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg)
+{
+ PortEvent *local_event;
+
+ IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) new event received by processor callback from port %d, id 0x%X\n", IX_ETH_DB_NPE_TO_PORT_ID(npeID), NPE_MSG_ID(msg), 0, 0, 0, 0);
+
+ if (CAN_ENQUEUE(&eventQueue))
+ {
+ TEST_FIXTURE_LOCK_EVENT_QUEUE;
+
+ local_event = QUEUE_HEAD(&eventQueue);
+
+ /* create event structure on queue */
+ local_event->eventType = NPE_MSG_ID(msg);
+ local_event->portID = IX_ETH_DB_NPE_TO_PORT_ID(npeID);
+
+ /* update queue */
+ PUSH_UPDATE_QUEUE(&eventQueue);
+
+ TEST_FIXTURE_UNLOCK_EVENT_QUEUE;
+
+ IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) Waking up main processor loop...\n", 0, 0, 0, 0, 0, 0);
+
+ /* increment event queue semaphore */
+ ixOsalSemaphorePost(&eventQueueSemaphore);
+ }
+ else
+ {
+ IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) Warning: could not enqueue event (overflow)\n", 0, 0, 0, 0, 0, 0);
+ }
+}
+
+/**
+ * @brief Ethernet event processor loop
+ *
+ * Extracts at most EVENT_PROCESSING_LIMIT batches of events and
+ * sends them for processing to @ref ixEthDBProcessEvent().
+ * Triggers port updates which normally follow learning events.
+ *
+ * @warning do not call directly, executes in separate thread
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBEventProcessorLoop(void *unused1)
+{
+ IxEthDBPortMap triggerPorts;
+ IxEthDBPortId portIndex;
+
+ ixEthDBEventProcessorRunning = TRUE;
+
+ IX_ETH_DB_EVENTS_TRACE("DB: (Events) Event processor loop was started\n");
+
+ while (!ixEthDBLearningShutdown)
+ {
+ BOOL keepProcessing = TRUE;
+ UINT32 processedEvents = 0;
+
+ IX_ETH_DB_EVENTS_VERBOSE_TRACE("DB: (Events) Waiting for new learning event...\n");
+
+ ixOsalSemaphoreWait(&eventQueueSemaphore, IX_OSAL_WAIT_FOREVER);
+
+ IX_ETH_DB_EVENTS_VERBOSE_TRACE("DB: (Events) Received new event\n");
+
+ if (!ixEthDBLearningShutdown)
+ {
+ /* port update handling */
+ SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
+
+ while (keepProcessing)
+ {
+ PortEvent local_event;
+ UINT32 intLockKey;
+
+ /* lock queue */
+ ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER);
+
+ /* lock NPE interrupts */
+ intLockKey = ixOsalIrqLock();
+
+ /* extract event */
+ local_event = *(QUEUE_TAIL(&eventQueue));
+
+ SHIFT_UPDATE_QUEUE(&eventQueue);
+
+ ixOsalIrqUnlock(intLockKey);
+
+ ixOsalMutexUnlock(&eventQueueLock);
+
+ IX_ETH_DB_EVENTS_TRACE("DB: (Events) Processing event with ID 0x%X\n", local_event.eventType);
+
+ ixEthDBProcessEvent(&local_event, triggerPorts);
+
+ processedEvents++;
+
+ if (processedEvents > EVENT_PROCESSING_LIMIT /* maximum burst reached? */
+ || ixOsalSemaphoreTryWait(&eventQueueSemaphore) != IX_SUCCESS) /* or empty queue? */
+ {
+ keepProcessing = FALSE;
+ }
+ }
+
+ ixEthDBUpdatePortLearningTrees(triggerPorts);
+ }
+ }
+
+ /* turn off automatic updates */
+ for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+ {
+ ixEthDBPortInfo[portIndex].updateMethod.updateEnabled = FALSE;
+ }
+
+ ixEthDBEventProcessorRunning = FALSE;
+}
+
+/**
+ * @brief event processor routine
+ *
+ * @param event event to be processed
+ * @param triggerPorts port map accumulating ports to be updated
+ *
+ * Processes learning events by synchronizing the database with
+ * newly learnt data. Called only by @ref ixEthDBEventProcessorLoop().
+ *
+ * @warning do not call directly
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBProcessEvent(PortEvent *local_event, IxEthDBPortMap triggerPorts)
+{
+ MacDescriptor recordTemplate;
+
+ switch (local_event->eventType)
+ {
+ case IX_ETH_DB_ADD_FILTERING_RECORD:
+ /* add record */
+ memset(&recordTemplate, 0, sizeof (recordTemplate));
+ memcpy(recordTemplate.macAddress, local_event->macAddr.macAddress, sizeof (IxEthDBMacAddr));
+
+ recordTemplate.type = IX_ETH_DB_FILTERING_RECORD;
+ recordTemplate.portID = local_event->portID;
+ recordTemplate.recordData.filteringData.staticEntry = local_event->staticEntry;
+
+ ixEthDBAdd(&recordTemplate, triggerPorts);
+
+ IX_ETH_DB_EVENTS_TRACE("DB: (Events) Added record on port %d\n", local_event->portID);
+
+ break;
+
+ case IX_ETH_DB_REMOVE_FILTERING_RECORD:
+ /* remove record */
+ memset(&recordTemplate, 0, sizeof (recordTemplate));
+ memcpy(recordTemplate.macAddress, local_event->macAddr.macAddress, sizeof (IxEthDBMacAddr));
+
+ recordTemplate.type = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD;
+
+ ixEthDBRemove(&recordTemplate, triggerPorts);
+
+ IX_ETH_DB_EVENTS_TRACE("DB: (Events) Removed record on port %d\n", local_event->portID);
+
+ break;
+
+ default:
+ /* can't handle/not interested in this event type */
+ ERROR_LOG("DB: (Events) Event processor received an unknown event type (0x%X)\n", local_event->eventType);
+
+ return;
+ }
+}
+
+/**
+ * @brief asynchronously adds a filtering record
+ * by posting an ADD_FILTERING_RECORD event to the event queue
+ *
+ * @param macAddr MAC address of the new record
+ * @param portID port ID of the new record
+ * @param staticEntry TRUE if record is static, FALSE if dynamic
+ *
+ * @return IX_ETH_DB_SUCCESS if the event creation was
+ * successfull or IX_ETH_DB_BUSY if the event queue is full
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBTriggerAddPortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry)
+{
+ MacDescriptor reference;
+
+ TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
+
+ /* fill search fields */
+ memcpy(reference.macAddress, macAddr, sizeof (IxEthDBMacAddr));
+ reference.portID = portID;
+
+ /* set acceptable record types */
+ reference.type = IX_ETH_DB_ALL_FILTERING_RECORDS;
+
+ if (ixEthDBPeekHashEntry(&dbHashtable, IX_ETH_DB_MAC_PORT_KEY, &reference) == IX_ETH_DB_SUCCESS)
+ {
+ /* already have an identical record */
+ return IX_ETH_DB_SUCCESS;
+ }
+ else
+ {
+ return ixEthDBTriggerPortUpdate(IX_ETH_DB_ADD_FILTERING_RECORD, macAddr, portID, staticEntry);
+ }
+}
+
+/**
+ * @brief asynchronously removes a filtering record
+ * by posting a REMOVE_FILTERING_RECORD event to the event queue
+ *
+ * @param macAddr MAC address of the record to remove
+ * @param portID port ID of the record to remove
+ *
+ * @return IX_ETH_DB_SUCCESS if the event creation was
+ * successfull or IX_ETH_DB_BUSY if the event queue is full
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBTriggerRemovePortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID)
+{
+ if (ixEthDBPeek(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS) != IX_ETH_DB_NO_SUCH_ADDR)
+ {
+ return ixEthDBTriggerPortUpdate(IX_ETH_DB_REMOVE_FILTERING_RECORD, macAddr, portID, FALSE);
+ }
+ else
+ {
+ return IX_ETH_DB_NO_SUCH_ADDR;
+ }
+}
+
+/**
+ * @brief adds an ADD or REMOVE event to the main event queue
+ *
+ * @param eventType event type - IX_ETH_DB_ADD_FILTERING_RECORD
+ * to add and IX_ETH_DB_REMOVE_FILTERING_RECORD to remove a
+ * record.
+ *
+ * @return IX_ETH_DB_SUCCESS if the event was successfully
+ * sent or IX_ETH_DB_BUSY if the event queue is full
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBTriggerPortUpdate(UINT32 eventType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry)
+{
+ UINT32 intLockKey;
+
+ /* lock interrupts to protect queue */
+ intLockKey = ixOsalIrqLock();
+
+ if (CAN_ENQUEUE(&eventQueue))
+ {
+ PortEvent *queueEvent = QUEUE_HEAD(&eventQueue);
+
+ /* update fields on the queue */
+ memcpy(queueEvent->macAddr.macAddress, macAddr->macAddress, sizeof (IxEthDBMacAddr));
+
+ queueEvent->eventType = eventType;
+ queueEvent->portID = portID;
+ queueEvent->staticEntry = staticEntry;
+
+ PUSH_UPDATE_QUEUE(&eventQueue);
+
+ /* imcrement event queue semaphore */
+ ixOsalSemaphorePost(&eventQueueSemaphore);
+
+ /* unlock interrupts */
+ ixOsalIrqUnlock(intLockKey);
+
+ return IX_ETH_DB_SUCCESS;
+ }
+ else /* event queue full */
+ {
+ /* unlock interrupts */
+ ixOsalIrqUnlock(intLockKey);
+
+ return IX_ETH_DB_BUSY;
+ }
+}
+
+/**
+ * @brief Locks learning tree updates and port disable
+ *
+ *
+ * This function locks portUpdateLock single mutex. It is primarily used
+ * to avoid executing 'port disable' during ELT maintenance.
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBUpdateLock(void)
+{
+ ixOsalMutexLock(&portUpdateLock, IX_OSAL_WAIT_FOREVER);
+}
+
+/**
+ * @brief Unlocks learning tree updates and port disable
+ *
+ *
+ * This function unlocks a portUpdateLock mutex. It is primarily used
+ * to avoid executing 'port disable' during ELT maintenance.
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBUpdateUnlock(void)
+{
+ ixOsalMutexUnlock(&portUpdateLock);
+}
+
diff --git a/cpu/ixp/npe/IxEthDBFeatures.c b/cpu/ixp/npe/IxEthDBFeatures.c
new file mode 100644
index 0000000..7a58d26
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBFeatures.c
@@ -0,0 +1,662 @@
+/**
+ * @file IxEthDBFeatures.c
+ *
+ * @brief Implementation of the EthDB feature control API
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxNpeDl.h"
+#include "IxEthDBQoS.h"
+#include "IxEthDB_p.h"
+
+/**
+ * @brief scans the capabilities of the loaded NPE images
+ *
+ * This function MUST be called by the ixEthDBInit() function.
+ * No EthDB features (including learning and filtering) are enabled
+ * before this function is called.
+ *
+ * @return none
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBFeatureCapabilityScan(void)
+{
+ IxNpeDlImageId imageId, npeAImageId;
+ IxEthDBPortId portIndex;
+ PortInfo *portInfo;
+ IxEthDBPriorityTable defaultPriorityTable;
+ IX_STATUS result;
+ UINT32 queueIndex;
+ UINT32 queueStructureIndex;
+ UINT32 trafficClassDefinitionIndex;
+
+ /* read version of NPE A - required to set the AQM queues for B and C */
+ npeAImageId.functionalityId = 0;
+ ixNpeDlLoadedImageGet(IX_NPEDL_NPEID_NPEA, &npeAImageId);
+
+ for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+ {
+ IxNpeMhMessage msg;
+
+ portInfo = &ixEthDBPortInfo[portIndex];
+
+ /* check and bypass if NPE B or C is fused out */
+ if (ixEthDBSingleEthNpeCheck(portIndex) != IX_ETH_DB_SUCCESS) continue;
+
+ /* all ports are capable of LEARNING by default */
+ portInfo->featureCapability |= IX_ETH_DB_LEARNING;
+ portInfo->featureStatus |= IX_ETH_DB_LEARNING;
+
+ if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
+ {
+
+ if (ixNpeDlLoadedImageGet(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), &imageId) != IX_SUCCESS)
+ {
+ WARNING_LOG("DB: (FeatureScan) NpeDl did not provide the image ID for NPE port %d\n", portIndex);
+ }
+ else
+ {
+ /* initialize and empty NPE response mutex */
+ ixOsalMutexInit(&portInfo->npeAckLock);
+ ixOsalMutexLock(&portInfo->npeAckLock, IX_OSAL_WAIT_FOREVER);
+
+ /* check NPE response to GetStatus */
+ msg.data[0] = IX_ETHNPE_NPE_GETSTATUS << 24;
+ msg.data[1] = 0;
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), msg, result);
+ if (result != IX_SUCCESS)
+ {
+ WARNING_LOG("DB: (FeatureScan) warning, could not send message to the NPE\n");
+ continue;
+ }
+
+
+ if (imageId.functionalityId == 0x00
+ || imageId.functionalityId == 0x03
+ || imageId.functionalityId == 0x04
+ || imageId.functionalityId == 0x80)
+ {
+ portInfo->featureCapability |= IX_ETH_DB_FILTERING;
+ portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
+ portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
+ }
+ else if (imageId.functionalityId == 0x01
+ || imageId.functionalityId == 0x81)
+ {
+ portInfo->featureCapability |= IX_ETH_DB_FILTERING;
+ portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
+ portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
+ portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS;
+ }
+ else if (imageId.functionalityId == 0x02
+ || imageId.functionalityId == 0x82)
+ {
+ portInfo->featureCapability |= IX_ETH_DB_WIFI_HEADER_CONVERSION;
+ portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
+ portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
+ portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS;
+ }
+
+ /* reset AQM queues */
+ memset(portInfo->ixEthDBTrafficClassAQMAssignments, 0, sizeof (portInfo->ixEthDBTrafficClassAQMAssignments));
+
+ /* ensure there's at least one traffic class record in the definition table, otherwise we have no default case, hence no queues */
+ IX_ENSURE(sizeof (ixEthDBTrafficClassDefinitions) != 0, "DB: no traffic class definitions found, check IxEthDBQoS.h");
+
+ /* find the traffic class definition index compatible with the current NPE A functionality ID */
+ for (trafficClassDefinitionIndex = 0 ;
+ trafficClassDefinitionIndex < sizeof (ixEthDBTrafficClassDefinitions) / sizeof (ixEthDBTrafficClassDefinitions[0]);
+ trafficClassDefinitionIndex++)
+ {
+ if (ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_NPE_A_FUNCTIONALITY_ID_INDEX] == npeAImageId.functionalityId)
+ {
+ /* found it */
+ break;
+ }
+ }
+
+ /* select the default case if we went over the array boundary */
+ if (trafficClassDefinitionIndex == sizeof (ixEthDBTrafficClassDefinitions) / sizeof (ixEthDBTrafficClassDefinitions[0]))
+ {
+ trafficClassDefinitionIndex = 0; /* the first record is the default case */
+ }
+
+ /* select queue assignment structure based on the traffic class configuration index */
+ queueStructureIndex = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_QUEUE_ASSIGNMENT_INDEX];
+
+ /* only traffic class 0 is active at initialization time */
+ portInfo->ixEthDBTrafficClassCount = 1;
+
+ /* enable port, VLAN and Firewall feature bits to initialize QoS/VLAN/Firewall configuration */
+ portInfo->featureStatus |= IX_ETH_DB_VLAN_QOS;
+ portInfo->featureStatus |= IX_ETH_DB_FIREWALL;
+ portInfo->enabled = TRUE;
+
+#define CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
+#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
+ /* set VLAN initial configuration (permissive) */
+ if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0) /* QoS-enabled image */
+ {
+ /* QoS capable */
+ portInfo->ixEthDBTrafficClassAvailable = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_TRAFFIC_CLASS_COUNT_INDEX];
+
+ /* set AQM queues */
+ for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++)
+ {
+ portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] = ixEthDBQueueAssignments[queueStructureIndex][queueIndex];
+ }
+
+ /* set default PVID (0) and default traffic class 0 */
+ ixEthDBPortVlanTagSet(portIndex, 0);
+
+ /* enable reception of all frames */
+ ixEthDBAcceptableFrameTypeSet(portIndex, IX_ETH_DB_ACCEPT_ALL_FRAMES);
+
+ /* clear full VLAN membership */
+ ixEthDBPortVlanMembershipRangeRemove(portIndex, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID);
+
+ /* clear TTI table - no VLAN tagged frames will be transmitted */
+ ixEthDBEgressVlanRangeTaggingEnabledSet(portIndex, 0, 4094, FALSE);
+
+ /* set membership on 0, otherwise no Tx or Rx is working */
+ ixEthDBPortVlanMembershipAdd(portIndex, 0);
+ }
+ else /* QoS not available in this image */
+#endif /* test-only */
+ {
+ /* initialize traffic class availability (only class 0 is available) */
+ portInfo->ixEthDBTrafficClassAvailable = 1;
+
+ /* point all AQM queues to traffic class 0 */
+ for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++)
+ {
+ portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] =
+ ixEthDBQueueAssignments[queueStructureIndex][0];
+ }
+ }
+
+#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
+ /* download priority mapping table and Rx queue configuration */
+ memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable));
+ ixEthDBPriorityMappingTableSet(portIndex, defaultPriorityTable);
+#endif
+
+ /* by default we turn off invalid source MAC address filtering */
+ ixEthDBFirewallInvalidAddressFilterEnable(portIndex, FALSE);
+
+ /* disable port, VLAN, Firewall feature bits */
+ portInfo->featureStatus &= ~IX_ETH_DB_VLAN_QOS;
+ portInfo->featureStatus &= ~IX_ETH_DB_FIREWALL;
+ portInfo->enabled = FALSE;
+
+ /* enable filtering by default if present */
+ if ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0)
+ {
+ portInfo->featureStatus |= IX_ETH_DB_FILTERING;
+ }
+ }
+ }
+ }
+}
+
+/**
+ * @brief returns the capability of a port
+ *
+ * @param portID ID of the port
+ * @param featureSet location to store the port capability in
+ *
+ * This function will save the capability set of the given port
+ * into the given location. Capabilities are bit-ORed, each representing
+ * a bit of the feature set.
+ *
+ * Note that this function is documented in the main component
+ * public header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or IX_ETH_DB_INVALID_PORT if the given port is invalid
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet)
+{
+ IX_ETH_DB_CHECK_PORT_INITIALIZED(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(featureSet);
+
+ *featureSet = ixEthDBPortInfo[portID].featureCapability;
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief enables or disables a port capability
+ *
+ * @param portID ID of the port
+ * @param feature feature to enable or disable
+ * @param enabled TRUE to enable the selected feature or FALSE to disable it
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enable)
+{
+ PortInfo *portInfo;
+ IxEthDBPriorityTable defaultPriorityTable;
+ IxEthDBVlanSet vlanSet;
+ IxEthDBStatus status = IX_ETH_DB_SUCCESS;
+ BOOL portEnabled;
+
+ IX_ETH_DB_CHECK_PORT_INITIALIZED(portID);
+
+ portInfo = &ixEthDBPortInfo[portID];
+ portEnabled = portInfo->enabled;
+
+ /* check that only one feature is selected */
+ if (!ixEthDBCheckSingleBitValue(feature))
+ {
+ return IX_ETH_DB_FEATURE_UNAVAILABLE;
+ }
+
+ /* port capable of this feature? */
+ if ((portInfo->featureCapability & feature) == 0)
+ {
+ return IX_ETH_DB_FEATURE_UNAVAILABLE;
+ }
+
+ /* mutual exclusion between learning and WiFi header conversion */
+ if (enable && ((feature | portInfo->featureStatus) & (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION))
+ == (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION))
+ {
+ return IX_ETH_DB_NO_PERMISSION;
+ }
+
+ /* learning must be enabled before filtering */
+ if (enable && (feature == IX_ETH_DB_FILTERING) && ((portInfo->featureStatus & IX_ETH_DB_LEARNING) == 0))
+ {
+ return IX_ETH_DB_NO_PERMISSION;
+ }
+
+ /* filtering must be disabled before learning */
+ if (!enable && (feature == IX_ETH_DB_LEARNING) && ((portInfo->featureStatus & IX_ETH_DB_FILTERING) != 0))
+ {
+ return IX_ETH_DB_NO_PERMISSION;
+ }
+
+ /* redundant enabling or disabling */
+ if ((!enable && ((portInfo->featureStatus & feature) == 0))
+ || (enable && ((portInfo->featureStatus & feature) != 0)))
+ {
+ /* do nothing */
+ return IX_ETH_DB_SUCCESS;
+ }
+
+ /* force port enabled */
+ portInfo->enabled = TRUE;
+
+ if (enable)
+ {
+ /* turn on enable bit */
+ portInfo->featureStatus |= feature;
+
+#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
+ /* if this is VLAN/QoS set the default priority table */
+ if (feature == IX_ETH_DB_VLAN_QOS)
+ {
+ /* turn on VLAN/QoS (most permissive mode):
+ - set default 802.1Q priority mapping table, in accordance to the
+ availability of traffic classes
+ - set the acceptable frame filter to accept all
+ - set the Ingress tagging mode to pass-through
+ - set full VLAN membership list
+ - set full TTI table
+ - set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0)
+ - enable TPID port extraction
+ */
+
+ portInfo->ixEthDBTrafficClassCount = portInfo->ixEthDBTrafficClassAvailable;
+
+ /* set default 802.1Q priority mapping table - note that C indexing starts from 0, so we substract 1 here */
+ memcpy (defaultPriorityTable,
+ (const void *) ixEthIEEE802_1QUserPriorityToTrafficClassMapping[portInfo->ixEthDBTrafficClassCount - 1],
+ sizeof (defaultPriorityTable));
+
+ /* update priority mapping and AQM queue assignments */
+ status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable);
+
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
+ }
+
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH);
+ }
+
+ /* set membership and TTI tables */
+ memset (vlanSet, 0xFF, sizeof (vlanSet));
+
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ /* use the internal function to bypass PVID check */
+ status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet);
+ }
+
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ /* use the internal function to bypass PVID check */
+ status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet);
+ }
+
+ /* reset the PVID */
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ status = ixEthDBPortVlanTagSet(portID, 0);
+ }
+
+ /* enable TPID port extraction */
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ status = ixEthDBVlanPortExtractionEnable(portID, TRUE);
+ }
+ }
+ else if (feature == IX_ETH_DB_FIREWALL)
+#endif
+ {
+ /* firewall starts in black-list mode unless otherwise configured before *
+ * note that invalid source MAC address filtering is disabled by default */
+ if (portInfo->firewallMode != IX_ETH_DB_FIREWALL_BLACK_LIST
+ && portInfo->firewallMode != IX_ETH_DB_FIREWALL_WHITE_LIST)
+ {
+ status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
+
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ status = ixEthDBFirewallInvalidAddressFilterEnable(portID, FALSE);
+ }
+ }
+ }
+
+ if (status != IX_ETH_DB_SUCCESS)
+ {
+ /* checks failed, disable */
+ portInfo->featureStatus &= ~feature;
+ }
+ }
+ else
+ {
+ /* turn off features */
+ if (feature == IX_ETH_DB_FIREWALL)
+ {
+ /* turning off the firewall is equivalent to:
+ - set to black-list mode
+ - clear all the entries and download the new table
+ - turn off the invalid source address checking
+ */
+
+ status = ixEthDBDatabaseClear(portID, IX_ETH_DB_FIREWALL_RECORD);
+
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
+ }
+
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ status = ixEthDBFirewallInvalidAddressFilterEnable(portID, FALSE);
+ }
+
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ status = ixEthDBFirewallTableDownload(portID);
+ }
+ }
+ else if (feature == IX_ETH_DB_WIFI_HEADER_CONVERSION)
+ {
+ /* turn off header conversion */
+ status = ixEthDBDatabaseClear(portID, IX_ETH_DB_WIFI_RECORD);
+
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ status = ixEthDBWiFiConversionTableDownload(portID);
+ }
+ }
+#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
+ else if (feature == IX_ETH_DB_VLAN_QOS)
+ {
+ /* turn off VLAN/QoS:
+ - set a priority mapping table with one traffic class
+ - set the acceptable frame filter to accept all
+ - set the Ingress tagging mode to pass-through
+ - clear the VLAN membership list
+ - clear the TTI table
+ - set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0)
+ - disable TPID port extraction
+ */
+
+ /* initialize all => traffic class 0 priority mapping table */
+ memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable));
+ portInfo->ixEthDBTrafficClassCount = 1;
+ status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable);
+
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
+ }
+
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH);
+ }
+
+ /* clear membership and TTI tables */
+ memset (vlanSet, 0, sizeof (vlanSet));
+
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ /* use the internal function to bypass PVID check */
+ status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet);
+ }
+
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ /* use the internal function to bypass PVID check */
+ status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet);
+ }
+
+ /* reset the PVID */
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ status = ixEthDBPortVlanTagSet(portID, 0);
+ }
+
+ /* disable TPID port extraction */
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ status = ixEthDBVlanPortExtractionEnable(portID, FALSE);
+ }
+ }
+#endif
+
+ if (status == IX_ETH_DB_SUCCESS)
+ {
+ /* checks passed, disable */
+ portInfo->featureStatus &= ~feature;
+ }
+ }
+
+ /* restore port enabled state */
+ portInfo->enabled = portEnabled;
+
+ return status;
+}
+
+/**
+ * @brief returns the status of a feature
+ *
+ * @param portID port ID
+ * @param present location to store a boolean value indicating
+ * if the feature is present (TRUE) or not (FALSE)
+ * @param enabled location to store a booleam value indicating
+ * if the feature is present (TRUE) or not (FALSE)
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled)
+{
+ PortInfo *portInfo;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(present);
+
+ IX_ETH_DB_CHECK_REFERENCE(enabled);
+
+ portInfo = &ixEthDBPortInfo[portID];
+
+ *present = (portInfo->featureCapability & feature) != 0;
+ *enabled = (portInfo->featureStatus & feature) != 0;
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief returns the value of an EthDB property
+ *
+ * @param portID ID of the port
+ * @param feature feature owning the property
+ * @param property ID of the property
+ * @param type location to store the property type into
+ * @param value location to store the property value into
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value)
+{
+ IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(type);
+
+ IX_ETH_DB_CHECK_REFERENCE(value);
+
+ if (feature == IX_ETH_DB_VLAN_QOS)
+ {
+ if (property == IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY)
+ {
+ * (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount;
+ *type = IX_ETH_DB_INTEGER_PROPERTY;
+
+ return IX_ETH_DB_SUCCESS;
+ }
+ else if (property >= IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY
+ && property <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY)
+ {
+ UINT32 classDelta = property - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY;
+
+ if (classDelta >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount)
+ {
+ return IX_ETH_DB_FAIL;
+ }
+
+ * (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[classDelta];
+ *type = IX_ETH_DB_INTEGER_PROPERTY;
+
+ return IX_ETH_DB_SUCCESS;
+ }
+ }
+
+ return IX_ETH_DB_INVALID_ARG;
+}
+
+/**
+ * @brief sets the value of an EthDB property
+ *
+ * @param portID ID of the port
+ * @param feature feature owning the property
+ * @param property ID of the property
+ * @param value location containing the property value
+ *
+ * This function implements a private property intended
+ * only for EthAcc usage. Upon setting the IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE
+ * property (the value is ignored), the availability of traffic classes is
+ * frozen to whatever traffic class structure is currently in use.
+ * This means that if VLAN_QOS has been enabled before EthAcc
+ * initialization then all the defined traffic classes will be available;
+ * otherwise only one traffic class (0) will be available.
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h as not accepting any parameters. The
+ * current implementation is only intended for the private use of EthAcc.
+ *
+ * Also note that once this function is called the effect is irreversible,
+ * unless EthDB is complete unloaded and re-initialized.
+ *
+ * @return IX_ETH_DB_INVALID_ARG (no read-write properties are
+ * supported in this release)
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value)
+{
+ IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+ if ((feature == IX_ETH_DB_VLAN_QOS) && (property == IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE))
+ {
+ ixEthDBPortInfo[portID].ixEthDBTrafficClassAvailable = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount;
+
+ return IX_ETH_DB_SUCCESS;
+ }
+
+ return IX_ETH_DB_INVALID_ARG;
+}
diff --git a/cpu/ixp/npe/IxEthDBFirewall.c b/cpu/ixp/npe/IxEthDBFirewall.c
new file mode 100644
index 0000000..eb46174
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBFirewall.c
@@ -0,0 +1,266 @@
+/**
+ * @file IxEthDBFirewall.c
+ *
+ * @brief Implementation of the firewall API
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#include "IxEthDB_p.h"
+
+/**
+ * @brief updates the NPE firewall operating mode and
+ * firewall address table
+ *
+ * @param portID ID of the port
+ * @param epDelta initial entry point for binary searches (NPE optimization)
+ * @param address address of the firewall MAC address table
+ *
+ * This function will send a message to the NPE configuring the
+ * firewall mode (white list or black list), invalid source
+ * address filtering and downloading a new MAC address database
+ * to be used for firewall matching.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or IX_ETH_DB_FAIL otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFirewallUpdate(IxEthDBPortId portID, void *address, UINT32 epDelta)
+{
+ IxNpeMhMessage message;
+ IX_STATUS result;
+
+ UINT32 mode = 0;
+ PortInfo *portInfo = &ixEthDBPortInfo[portID];
+
+ mode = (portInfo->srcAddressFilterEnabled != FALSE) << 1 | (portInfo->firewallMode == IX_ETH_DB_FIREWALL_WHITE_LIST);
+
+ FILL_SETFIREWALLMODE_MSG(message,
+ IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID),
+ epDelta,
+ mode,
+ IX_OSAL_MMU_VIRT_TO_PHYS(address));
+
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+ return result;
+}
+
+/**
+ * @brief configures the firewall white list/black list
+ * access mode
+ *
+ * @param portID ID of the port
+ * @param mode firewall filtering mode (IX_ETH_DB_FIREWALL_WHITE_LIST
+ * or IX_ETH_DB_FIREWALL_BLACK_LIST)
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
+
+ if (mode != IX_ETH_DB_FIREWALL_WHITE_LIST
+ && mode != IX_ETH_DB_FIREWALL_BLACK_LIST)
+ {
+ return IX_ETH_DB_INVALID_ARG;
+ }
+
+ ixEthDBPortInfo[portID].firewallMode = mode;
+
+ return ixEthDBFirewallTableDownload(portID);
+}
+
+/**
+ * @brief enables or disables the invalid source MAC address filter
+ *
+ * @param portID ID of the port
+ * @param enable TRUE to enable invalid source MAC address filtering
+ * or FALSE to disable it
+ *
+ * The invalid source MAC address filter will discard, when enabled,
+ * frames whose source MAC address is a multicast or the broadcast MAC
+ * address.
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
+
+ ixEthDBPortInfo[portID].srcAddressFilterEnabled = enable;
+
+ return ixEthDBFirewallTableDownload(portID);
+}
+
+/**
+ * @brief adds a firewall record
+ *
+ * @param portID ID of the port
+ * @param macAddr MAC address of the new record
+ *
+ * This function will add a new firewall record
+ * on the specified port, using the specified
+ * MAC address. If the record already exists this
+ * function will silently return IX_ETH_DB_SUCCESS,
+ * although no duplicate records are added.
+ *
+ * Note that this function is documented in the main
+ * component header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+{
+ MacDescriptor recordTemplate;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
+
+ memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
+
+ recordTemplate.type = IX_ETH_DB_FIREWALL_RECORD;
+ recordTemplate.portID = portID;
+
+ return ixEthDBAdd(&recordTemplate, NULL);
+}
+
+/**
+ * @brief removes a firewall record
+ *
+ * @param portID ID of the port
+ * @param macAddr MAC address of the record to remove
+ *
+ * This function will attempt to remove a firewall
+ * record from the given port, using the specified
+ * MAC address.
+ *
+ * Note that this function is documented in the main
+ * component header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully of an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+{
+ MacDescriptor recordTemplate;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
+
+ memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
+
+ recordTemplate.type = IX_ETH_DB_FIREWALL_RECORD;
+ recordTemplate.portID = portID;
+
+ return ixEthDBRemove(&recordTemplate, NULL);
+}
+
+/**
+ * @brief downloads the firewall address table to an NPE
+ *
+ * @param portID ID of the port
+ *
+ * This function will download the firewall address table to
+ * an NPE port.
+ *
+ * Note that this function is documented in the main
+ * component header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or IX_ETH_DB_FAIL otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID)
+{
+ IxEthDBPortMap query;
+ IxEthDBStatus result;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
+
+ SET_DEPENDENCY_MAP(query, portID);
+
+ ixEthDBUpdateLock();
+
+ ixEthDBPortInfo[portID].updateMethod.searchTree = ixEthDBQuery(NULL, query, IX_ETH_DB_FIREWALL_RECORD, MAX_FW_SIZE);
+
+ result = ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_FIREWALL_RECORD);
+
+ ixEthDBUpdateUnlock();
+
+ return result;
+}
diff --git a/cpu/ixp/npe/IxEthDBHashtable.c b/cpu/ixp/npe/IxEthDBHashtable.c
new file mode 100644
index 0000000..f1b18e6
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBHashtable.c
@@ -0,0 +1,642 @@
+/**
+ * @file ethHash.c
+ *
+ * @brief Hashtable implementation
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#include "IxEthDB_p.h"
+#include "IxEthDBLocks_p.h"
+
+/**
+ * @addtogroup EthDB
+ *
+ * @{
+ */
+
+/**
+ * @brief initializes a hash table object
+ *
+ * @param hashTable uninitialized hash table structure
+ * @param numBuckets number of buckets to use
+ * @param entryHashFunction hash function used
+ * to hash entire hash node data block (for adding)
+ * @param matchFunctions array of match functions, indexed on type,
+ * used to differentiate records with the same hash value
+ * @param freeFunction function used to free node data blocks
+ *
+ * Initializes the given hash table object.
+ *
+ * @internal
+ */
+void ixEthDBInitHash(HashTable *hashTable,
+ UINT32 numBuckets,
+ HashFunction entryHashFunction,
+ MatchFunction *matchFunctions,
+ FreeFunction freeFunction)
+{
+ UINT32 bucketIndex;
+ UINT32 hashSize = numBuckets * sizeof(HashNode *);
+
+ /* entry hashing, matching and freeing methods */
+ hashTable->entryHashFunction = entryHashFunction;
+ hashTable->matchFunctions = matchFunctions;
+ hashTable->freeFunction = freeFunction;
+
+ /* buckets */
+ hashTable->numBuckets = numBuckets;
+
+ /* set to 0 all buckets */
+ memset(hashTable->hashBuckets, 0, hashSize);
+
+ /* init bucket locks - note that initially all mutexes are unlocked after MutexInit()*/
+ for (bucketIndex = 0 ; bucketIndex < numBuckets ; bucketIndex++)
+ {
+ ixOsalFastMutexInit(&hashTable->bucketLocks[bucketIndex]);
+ }
+}
+
+/**
+ * @brief adds an entry to the hash table
+ *
+ * @param hashTable hash table to add the entry to
+ * @param entry entry to add
+ *
+ * The entry will be hashed using the entry hashing function and added to the
+ * hash table, unless a locking blockage occurs, in which case the caller
+ * should retry.
+ *
+ * @retval IX_ETH_DB_SUCCESS if adding <i>entry</i> has succeeded
+ * @retval IX_ETH_DB_NOMEM if there's no memory left in the hash node pool
+ * @retval IX_ETH_DB_BUSY if there's a locking failure on the insertion path
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAddHashEntry(HashTable *hashTable, void *entry)
+{
+ UINT32 hashValue = hashTable->entryHashFunction(entry);
+ UINT32 bucketIndex = hashValue % hashTable->numBuckets;
+ HashNode *bucket = hashTable->hashBuckets[bucketIndex];
+ HashNode *newNode;
+
+ LockStack locks;
+
+ INIT_STACK(&locks);
+
+ /* lock bucket */
+ PUSH_LOCK(&locks, &hashTable->bucketLocks[bucketIndex]);
+
+ /* lock insertion element (first in chain), if any */
+ if (bucket != NULL)
+ {
+ PUSH_LOCK(&locks, &bucket->lock);
+ }
+
+ /* get new node */
+ newNode = ixEthDBAllocHashNode();
+
+ if (newNode == NULL)
+ {
+ /* unlock everything */
+ UNROLL_STACK(&locks);
+
+ return IX_ETH_DB_NOMEM;
+ }
+
+ /* init lock - note that mutexes are unlocked after MutexInit */
+ ixOsalFastMutexInit(&newNode->lock);
+
+ /* populate new link */
+ newNode->data = entry;
+
+ /* add to bucket */
+ newNode->next = bucket;
+ hashTable->hashBuckets[bucketIndex] = newNode;
+
+ /* unlock bucket and insertion point */
+ UNROLL_STACK(&locks);
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief removes an entry from the hashtable
+ *
+ * @param hashTable hash table to remove entry from
+ * @param keyType type of record key used for matching
+ * @param reference reference key used to identify the entry
+ *
+ * The reference key will be hashed using the key hashing function,
+ * the entry is searched using the hashed value and then examined
+ * against the reference entry using the match function. A positive
+ * match will trigger the deletion of the entry.
+ * Locking failures are reported and the caller should retry.
+ *
+ * @retval IX_ETH_DB_SUCCESS if the removal was successful
+ * @retval IX_ETH_DB_NO_SUCH_ADDR if the entry was not found
+ * @retval IX_ETH_DB_BUSY if a locking failure occured during the process
+ *
+ * @internal
+ */
+IxEthDBStatus ixEthDBRemoveHashEntry(HashTable *hashTable, int keyType, void *reference)
+{
+ UINT32 hashValue = hashTable->entryHashFunction(reference);
+ UINT32 bucketIndex = hashValue % hashTable->numBuckets;
+ HashNode *node = hashTable->hashBuckets[bucketIndex];
+ HashNode *previousNode = NULL;
+
+ LockStack locks;
+
+ INIT_STACK(&locks);
+
+ while (node != NULL)
+ {
+ /* try to lock node */
+ PUSH_LOCK(&locks, &node->lock);
+
+ if (hashTable->matchFunctions[keyType](reference, node->data))
+ {
+ /* found entry */
+ if (node->next != NULL)
+ {
+ PUSH_LOCK(&locks, &node->next->lock);
+ }
+
+ if (previousNode == NULL)
+ {
+ /* node is head of chain */
+ PUSH_LOCK(&locks, &hashTable->bucketLocks[bucketIndex]);
+
+ hashTable->hashBuckets[bucketIndex] = node->next;
+
+ POP_LOCK(&locks);
+ }
+ else
+ {
+ /* relink */
+ previousNode->next = node->next;
+ }
+
+ UNROLL_STACK(&locks);
+
+ /* free node */
+ hashTable->freeFunction(node->data);
+ ixEthDBFreeHashNode(node);
+
+ return IX_ETH_DB_SUCCESS;
+ }
+ else
+ {
+ if (previousNode != NULL)
+ {
+ /* unlock previous node */
+ SHIFT_STACK(&locks);
+ }
+
+ /* advance to next element in chain */
+ previousNode = node;
+ node = node->next;
+ }
+ }
+
+ UNROLL_STACK(&locks);
+
+ /* not found */
+ return IX_ETH_DB_NO_SUCH_ADDR;
+}
+
+/**
+ * @brief retrieves an entry from the hash table
+ *
+ * @param hashTable hash table to perform the search into
+ * @param reference search key (a MAC address)
+ * @param keyType type of record key used for matching
+ * @param searchResult pointer where a reference to the located hash node
+ * is placed
+ *
+ * Searches the entry with the same key as <i>reference</i> and places the
+ * pointer to the resulting node in <i>searchResult</i>.
+ * An implicit write access lock is granted after a search, which gives the
+ * caller the opportunity to modify the entry.
+ * Access should be released as soon as possible using @ref ixEthDBReleaseHashNode().
+ *
+ * @see ixEthDBReleaseHashNode()
+ *
+ * @retval IX_ETH_DB_SUCCESS if the search was completed successfully
+ * @retval IX_ETH_DB_NO_SUCH_ADDRESS if no entry with the given key was found
+ * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case
+ * the caller should retry
+ *
+ * @warning unless the return value is <b>IX_ETH_DB_SUCCESS</b> the searchResult
+ * location is NOT modified and therefore using a NULL comparison test when the
+ * value was not properly initialized would be an error
+ *
+ * @internal
+ */
+IxEthDBStatus ixEthDBSearchHashEntry(HashTable *hashTable, int keyType, void *reference, HashNode **searchResult)
+{
+ UINT32 hashValue;
+ HashNode *node;
+
+ hashValue = hashTable->entryHashFunction(reference);
+ node = hashTable->hashBuckets[hashValue % hashTable->numBuckets];
+
+ while (node != NULL)
+ {
+ TRY_LOCK(&node->lock);
+
+ if (hashTable->matchFunctions[keyType](reference, node->data))
+ {
+ *searchResult = node;
+
+ return IX_ETH_DB_SUCCESS;
+ }
+ else
+ {
+ UNLOCK(&node->lock);
+
+ node = node->next;
+ }
+ }
+
+ /* not found */
+ return IX_ETH_DB_NO_SUCH_ADDR;
+}
+
+/**
+ * @brief reports the existence of an entry in the hash table
+ *
+ * @param hashTable hash table to perform the search into
+ * @param reference search key (a MAC address)
+ * @param keyType type of record key used for matching
+ *
+ * Searches the entry with the same key as <i>reference</i>.
+ * No implicit write access lock is granted after a search, hence the
+ * caller cannot access or modify the entry. The result is only temporary.
+ *
+ * @see ixEthDBReleaseHashNode()
+ *
+ * @retval IX_ETH_DB_SUCCESS if the search was completed successfully
+ * @retval IX_ETH_DB_NO_SUCH_ADDRESS if no entry with the given key was found
+ * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case
+ * the caller should retry
+ *
+ * @internal
+ */
+IxEthDBStatus ixEthDBPeekHashEntry(HashTable *hashTable, int keyType, void *reference)
+{
+ UINT32 hashValue;
+ HashNode *node;
+
+ hashValue = hashTable->entryHashFunction(reference);
+ node = hashTable->hashBuckets[hashValue % hashTable->numBuckets];
+
+ while (node != NULL)
+ {
+ TRY_LOCK(&node->lock);
+
+ if (hashTable->matchFunctions[keyType](reference, node->data))
+ {
+ UNLOCK(&node->lock);
+
+ return IX_ETH_DB_SUCCESS;
+ }
+ else
+ {
+ UNLOCK(&node->lock);
+
+ node = node->next;
+ }
+ }
+
+ /* not found */
+ return IX_ETH_DB_NO_SUCH_ADDR;
+}
+
+/**
+ * @brief releases the write access lock
+ *
+ * @pre the node should have been obtained via @ref ixEthDBSearchHashEntry()
+ *
+ * @see ixEthDBSearchHashEntry()
+ *
+ * @internal
+ */
+void ixEthDBReleaseHashNode(HashNode *node)
+{
+ UNLOCK(&node->lock);
+}
+
+/**
+ * @brief initializes a hash iterator
+ *
+ * @param hashTable hash table to be iterated
+ * @param iterator iterator object
+ *
+ * If the initialization is successful the iterator will point to the
+ * first hash table record (if any).
+ * Testing if the iterator has not passed the end of the table should be
+ * done using the IS_ITERATOR_VALID(iteratorPtr) macro.
+ * An implicit write access lock is granted on the entry pointed by the iterator.
+ * The access is automatically revoked when the iterator is incremented.
+ * If the caller decides to terminate the iteration before the end of the table is
+ * passed then the manual access release method, @ref ixEthDBReleaseHashIterator,
+ * must be called.
+ *
+ * @see ixEthDBReleaseHashIterator()
+ *
+ * @retval IX_ETH_DB_SUCCESS if initialization was successful and the iterator points
+ * to the first valid table node
+ * @retval IX_ETH_DB_FAIL if the table is empty
+ * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
+ * should retry
+ *
+ * @warning do not use ixEthDBReleaseHashNode() on entries pointed by the iterator, as this
+ * might place the database in a permanent invalid lock state
+ *
+ * @internal
+ */
+IxEthDBStatus ixEthDBInitHashIterator(HashTable *hashTable, HashIterator *iterator)
+{
+ iterator->bucketIndex = 0;
+ iterator->node = NULL;
+ iterator->previousNode = NULL;
+
+ return ixEthDBIncrementHashIterator(hashTable, iterator);
+}
+
+/**
+ * @brief releases the write access locks of the iterator nodes
+ *
+ * @warning use of this function is required only when the caller terminates an iteration
+ * before reaching the end of the table
+ *
+ * @see ixEthDBInitHashIterator()
+ * @see ixEthDBIncrementHashIterator()
+ *
+ * @param iterator iterator whose node(s) should be unlocked
+ *
+ * @internal
+ */
+void ixEthDBReleaseHashIterator(HashIterator *iterator)
+{
+ if (iterator->previousNode != NULL)
+ {
+ UNLOCK(&iterator->previousNode->lock);
+ }
+
+ if (iterator->node != NULL)
+ {
+ UNLOCK(&iterator->node->lock);
+ }
+}
+
+/**
+ * @brief incremenents an iterator so that it points to the next valid entry of the table
+ * (if any)
+ *
+ * @param hashTable hash table to iterate
+ * @param iterator iterator object
+ *
+ * @pre the iterator object must be initialized using @ref ixEthDBInitHashIterator()
+ *
+ * If the increment operation is successful the iterator will point to the
+ * next hash table record (if any).
+ * Testing if the iterator has not passed the end of the table should be
+ * done using the IS_ITERATOR_VALID(iteratorPtr) macro.
+ * An implicit write access lock is granted on the entry pointed by the iterator.
+ * The access is automatically revoked when the iterator is re-incremented.
+ * If the caller decides to terminate the iteration before the end of the table is
+ * passed then the manual access release method, @ref ixEthDBReleaseHashIterator,
+ * must be called.
+ * Is is guaranteed that no other thread can remove or change the iterated entry until
+ * the iterator is incremented successfully.
+ *
+ * @see ixEthDBReleaseHashIterator()
+ *
+ * @retval IX_ETH_DB_SUCCESS if the operation was successful and the iterator points
+ * to the next valid table node
+ * @retval IX_ETH_DB_FAIL if the iterator has passed the end of the table
+ * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
+ * should retry
+ *
+ * @warning do not use ixEthDBReleaseHashNode() on entries pointed by the iterator, as this
+ * might place the database in a permanent invalid lock state
+ *
+ * @internal
+ */
+IxEthDBStatus ixEthDBIncrementHashIterator(HashTable *hashTable, HashIterator *iterator)
+{
+ /* unless iterator is just initialized... */
+ if (iterator->node != NULL)
+ {
+ /* try next in chain */
+ if (iterator->node->next != NULL)
+ {
+ TRY_LOCK(&iterator->node->next->lock);
+
+ if (iterator->previousNode != NULL)
+ {
+ UNLOCK(&iterator->previousNode->lock);
+ }
+
+ iterator->previousNode = iterator->node;
+ iterator->node = iterator->node->next;
+
+ return IX_ETH_DB_SUCCESS;
+ }
+ else
+ {
+ /* last in chain, prepare for next bucket */
+ iterator->bucketIndex++;
+ }
+ }
+
+ /* try next used bucket */
+ for (; iterator->bucketIndex < hashTable->numBuckets ; iterator->bucketIndex++)
+ {
+ HashNode **nodePtr = &(hashTable->hashBuckets[iterator->bucketIndex]);
+ HashNode *node = *nodePtr;
+#if (CPU!=SIMSPARCSOLARIS) && !defined (__wince)
+ if (((iterator->bucketIndex & IX_ETHDB_BUCKET_INDEX_MASK) == 0) &&
+ (iterator->bucketIndex < (hashTable->numBuckets - IX_ETHDB_BUCKETPTR_AHEAD)))
+ {
+ /* preload next cache line (2 cache line ahead) */
+ nodePtr += IX_ETHDB_BUCKETPTR_AHEAD;
+ __asm__ ("pld [%0];\n": : "r" (nodePtr));
+ }
+#endif
+ if (node != NULL)
+ {
+ TRY_LOCK(&node->lock);
+
+ /* unlock last one or two nodes in the previous chain */
+ if (iterator->node != NULL)
+ {
+ UNLOCK(&iterator->node->lock);
+
+ if (iterator->previousNode != NULL)
+ {
+ UNLOCK(&iterator->previousNode->lock);
+ }
+ }
+
+ /* redirect iterator */
+ iterator->previousNode = NULL;
+ iterator->node = node;
+
+ return IX_ETH_DB_SUCCESS;
+ }
+ }
+
+ /* could not advance iterator */
+ if (iterator->node != NULL)
+ {
+ UNLOCK(&iterator->node->lock);
+
+ if (iterator->previousNode != NULL)
+ {
+ UNLOCK(&iterator->previousNode->lock);
+ }
+
+ iterator->node = NULL;
+ }
+
+ return IX_ETH_DB_END;
+}
+
+/**
+ * @brief removes an entry pointed by an iterator
+ *
+ * @param hashTable iterated hash table
+ * @param iterator iterator object
+ *
+ * Removes the entry currently pointed by the iterator and repositions the iterator
+ * on the next valid entry (if any). Handles locking issues automatically and
+ * implicitely grants write access lock to the new pointed entry.
+ * Failures due to concurrent threads having write access locks in the same region
+ * preserve the state of the database and the iterator object, leaving the caller
+ * free to retry without loss of access. It is guaranteed that only the thread owning
+ * the iterator can remove the object pointed by the iterator.
+ *
+ * @retval IX_ETH_DB_SUCCESS if removal has succeeded
+ * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
+ * should retry
+ *
+ * @internal
+ */
+IxEthDBStatus ixEthDBRemoveEntryAtHashIterator(HashTable *hashTable, HashIterator *iterator)
+{
+ HashIterator nextIteratorPos;
+ LockStack locks;
+
+ INIT_STACK(&locks);
+
+ /* set initial bucket index for next position */
+ nextIteratorPos.bucketIndex = iterator->bucketIndex;
+
+ /* compute iterator position before removing anything and lock ahead */
+ if (iterator->node->next != NULL)
+ {
+ PUSH_LOCK(&locks, &iterator->node->next->lock);
+
+ /* reposition on the next node in the chain */
+ nextIteratorPos.node = iterator->node->next;
+ nextIteratorPos.previousNode = iterator->previousNode;
+ }
+ else
+ {
+ /* try next chain - don't know yet if we'll find anything */
+ nextIteratorPos.node = NULL;
+
+ /* if we find something it's a chain head */
+ nextIteratorPos.previousNode = NULL;
+
+ /* browse up in the buckets to find a non-null chain */
+ while (++nextIteratorPos.bucketIndex < hashTable->numBuckets)
+ {
+ nextIteratorPos.node = hashTable->hashBuckets[nextIteratorPos.bucketIndex];
+
+ if (nextIteratorPos.node != NULL)
+ {
+ /* found a non-empty chain, try to lock head */
+ PUSH_LOCK(&locks, &nextIteratorPos.node->lock);
+
+ break;
+ }
+ }
+ }
+
+ /* restore links over the to-be-deleted item */
+ if (iterator->previousNode == NULL)
+ {
+ /* first in chain, lock bucket */
+ PUSH_LOCK(&locks, &hashTable->bucketLocks[iterator->bucketIndex]);
+
+ hashTable->hashBuckets[iterator->bucketIndex] = iterator->node->next;
+
+ POP_LOCK(&locks);
+ }
+ else
+ {
+ /* relink */
+ iterator->previousNode->next = iterator->node->next;
+
+ /* unlock last remaining node in current chain when moving between chains */
+ if (iterator->node->next == NULL)
+ {
+ UNLOCK(&iterator->previousNode->lock);
+ }
+ }
+
+ /* delete entry */
+ hashTable->freeFunction(iterator->node->data);
+ ixEthDBFreeHashNode(iterator->node);
+
+ /* reposition iterator */
+ *iterator = nextIteratorPos;
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @}
+ */
diff --git a/cpu/ixp/npe/IxEthDBLearning.c b/cpu/ixp/npe/IxEthDBLearning.c
new file mode 100644
index 0000000..2287dbe
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBLearning.c
@@ -0,0 +1,149 @@
+/**
+ * @file IxEthDBLearning.c
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB_p.h"
+
+/**
+ * @brief hashes the mac address in a mac descriptor with a XOR function
+ *
+ * @param entry pointer to a mac descriptor to be hashed
+ *
+ * This function only extracts the mac address and employs ixEthDBKeyXORHash()
+ * to do the actual hashing.
+ * Used only to add a whole entry to a hash table, as opposed to searching which
+ * takes only a key and uses the key hashing directly.
+ *
+ * @see ixEthDBKeyXORHash()
+ *
+ * @return the hash value
+ *
+ * @internal
+ */
+UINT32 ixEthDBEntryXORHash(void *entry)
+{
+ MacDescriptor *descriptor = (MacDescriptor *) entry;
+
+ return ixEthDBKeyXORHash(descriptor->macAddress);
+}
+
+/**
+ * @brief hashes a mac address
+ *
+ * @param key pointer to a 6 byte structure (typically an IxEthDBMacAddr pointer)
+ * to be hashed
+ *
+ * Given a 6 bytes MAC address, the hash used is:
+ *
+ * hash(MAC[0:5]) = MAC[0:1] ^ MAC[2:3] ^ MAC[4:5]
+ *
+ * Used by the hash table to search and remove entries based
+ * solely on their keys (mac addresses).
+ *
+ * @return the hash value
+ *
+ * @internal
+ */
+UINT32 ixEthDBKeyXORHash(void *key)
+{
+ UINT32 hashValue;
+ UINT8 *value = (UINT8 *) key;
+
+ hashValue = (value[5] << 8) | value[4];
+ hashValue ^= (value[3] << 8) | value[2];
+ hashValue ^= (value[1] << 8) | value[0];
+
+ return hashValue;
+}
+
+/**
+ * @brief mac descriptor match function
+ *
+ * @param reference mac address (typically an IxEthDBMacAddr pointer) structure
+ * @param entry pointer to a mac descriptor whose key (mac address) is to be
+ * matched against the reference key
+ *
+ * Used by the hash table to retrieve entries. Hashing entries can produce
+ * collisions, i.e. descriptors with different mac addresses and the same
+ * hash value, where this function is used to differentiate entries.
+ *
+ * @retval TRUE if the entry matches the reference key (equal addresses)
+ * @retval FALSE if the entry does not match the reference key
+ *
+ * @internal
+ */
+BOOL ixEthDBAddressMatch(void *reference, void *entry)
+{
+ return (ixEthDBAddressCompare(reference, ((MacDescriptor *) entry)->macAddress) == 0);
+}
+
+/**
+ * @brief compares two mac addresses
+ *
+ * @param mac1 first mac address to compare
+ * @param mac2 second mac address to compare
+ *
+ * This comparison works in a similar way to strcmp, producing similar results.
+ * Used to insert values keyed on mac addresses into binary search trees.
+ *
+ * @retval -1 if mac1 < mac2
+ * @retval 0 if ma1 == mac2
+ * @retval 1 if mac1 > mac2
+ */
+UINT32 ixEthDBAddressCompare(UINT8 *mac1, UINT8 *mac2)
+{
+ UINT32 local_index;
+
+ for (local_index = 0 ; local_index < IX_IEEE803_MAC_ADDRESS_SIZE ; local_index++)
+ {
+ if (mac1[local_index] > mac2[local_index])
+ {
+ return 1;
+ }
+ else if (mac1[local_index] < mac2[local_index])
+ {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
diff --git a/cpu/ixp/npe/IxEthDBMem.c b/cpu/ixp/npe/IxEthDBMem.c
new file mode 100644
index 0000000..133cbef
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBMem.c
@@ -0,0 +1,649 @@
+/**
+ * @file IxEthDBDBMem.c
+ *
+ * @brief Memory handling routines for the MAC address database
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#include "IxEthDB_p.h"
+
+IX_ETH_DB_PRIVATE HashNode *nodePool = NULL;
+IX_ETH_DB_PRIVATE MacDescriptor *macPool = NULL;
+IX_ETH_DB_PRIVATE MacTreeNode *treePool = NULL;
+
+IX_ETH_DB_PRIVATE HashNode nodePoolArea[NODE_POOL_SIZE];
+IX_ETH_DB_PRIVATE MacDescriptor macPoolArea[MAC_POOL_SIZE];
+IX_ETH_DB_PRIVATE MacTreeNode treePoolArea[TREE_POOL_SIZE];
+
+IX_ETH_DB_PRIVATE IxOsalMutex nodePoolLock;
+IX_ETH_DB_PRIVATE IxOsalMutex macPoolLock;
+IX_ETH_DB_PRIVATE IxOsalMutex treePoolLock;
+
+#define LOCK_NODE_POOL { ixOsalMutexLock(&nodePoolLock, IX_OSAL_WAIT_FOREVER); }
+#define UNLOCK_NODE_POOL { ixOsalMutexUnlock(&nodePoolLock); }
+
+#define LOCK_MAC_POOL { ixOsalMutexLock(&macPoolLock, IX_OSAL_WAIT_FOREVER); }
+#define UNLOCK_MAC_POOL { ixOsalMutexUnlock(&macPoolLock); }
+
+#define LOCK_TREE_POOL { ixOsalMutexLock(&treePoolLock, IX_OSAL_WAIT_FOREVER); }
+#define UNLOCK_TREE_POOL { ixOsalMutexUnlock(&treePoolLock); }
+
+/* private function prototypes */
+IX_ETH_DB_PRIVATE MacDescriptor* ixEthDBPoolAllocMacDescriptor(void);
+IX_ETH_DB_PRIVATE void ixEthDBPoolFreeMacDescriptor(MacDescriptor *macDescriptor);
+
+/**
+ * @addtogroup EthMemoryManagement
+ *
+ * @{
+ */
+
+/**
+ * @brief initializes the memory pools used by the ethernet database component
+ *
+ * Initializes the hash table node, mac descriptor and mac tree node pools.
+ * Called at initialization time by @ref ixEthDBInit().
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBInitMemoryPools(void)
+{
+ int local_index;
+
+ /* HashNode pool */
+ ixOsalMutexInit(&nodePoolLock);
+
+ for (local_index = 0 ; local_index < NODE_POOL_SIZE ; local_index++)
+ {
+ HashNode *freeNode = &nodePoolArea[local_index];
+
+ freeNode->nextFree = nodePool;
+ nodePool = freeNode;
+ }
+
+ /* MacDescriptor pool */
+ ixOsalMutexInit(&macPoolLock);
+
+ for (local_index = 0 ; local_index < MAC_POOL_SIZE ; local_index++)
+ {
+ MacDescriptor *freeDescriptor = &macPoolArea[local_index];
+
+ freeDescriptor->nextFree = macPool;
+ macPool = freeDescriptor;
+ }
+
+ /* MacTreeNode pool */
+ ixOsalMutexInit(&treePoolLock);
+
+ for (local_index = 0 ; local_index < TREE_POOL_SIZE ; local_index++)
+ {
+ MacTreeNode *freeNode = &treePoolArea[local_index];
+
+ freeNode->nextFree = treePool;
+ treePool = freeNode;
+ }
+}
+
+/**
+ * @brief allocates a hash node from the pool
+ *
+ * Allocates a hash node and resets its value.
+ *
+ * @return the allocated hash node or NULL if the pool is empty
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+HashNode* ixEthDBAllocHashNode(void)
+{
+ HashNode *allocatedNode = NULL;
+
+ if (nodePool != NULL)
+ {
+ LOCK_NODE_POOL;
+
+ allocatedNode = nodePool;
+ nodePool = nodePool->nextFree;
+
+ UNLOCK_NODE_POOL;
+
+ memset(allocatedNode, 0, sizeof(HashNode));
+ }
+
+ return allocatedNode;
+}
+
+/**
+ * @brief frees a hash node into the pool
+ *
+ * @param hashNode node to be freed
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBFreeHashNode(HashNode *hashNode)
+{
+ if (hashNode != NULL)
+ {
+ LOCK_NODE_POOL;
+
+ hashNode->nextFree = nodePool;
+ nodePool = hashNode;
+
+ UNLOCK_NODE_POOL;
+ }
+}
+
+/**
+ * @brief allocates a mac descriptor from the pool
+ *
+ * Allocates a mac descriptor and resets its value.
+ * This function is not used directly, instead @ref ixEthDBAllocMacDescriptor()
+ * is used, which keeps track of the pointer reference count.
+ *
+ * @see ixEthDBAllocMacDescriptor()
+ *
+ * @warning this function is not used directly by any other function
+ * apart from ixEthDBAllocMacDescriptor()
+ *
+ * @return the allocated mac descriptor or NULL if the pool is empty
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+MacDescriptor* ixEthDBPoolAllocMacDescriptor(void)
+{
+ MacDescriptor *allocatedDescriptor = NULL;
+
+ if (macPool != NULL)
+ {
+ LOCK_MAC_POOL;
+
+ allocatedDescriptor = macPool;
+ macPool = macPool->nextFree;
+
+ UNLOCK_MAC_POOL;
+
+ memset(allocatedDescriptor, 0, sizeof(MacDescriptor));
+ }
+
+ return allocatedDescriptor;
+}
+
+/**
+ * @brief allocates and initializes a mac descriptor smart pointer
+ *
+ * Uses @ref ixEthDBPoolAllocMacDescriptor() to allocate a mac descriptor
+ * from the pool and initializes its reference count.
+ *
+ * @see ixEthDBPoolAllocMacDescriptor()
+ *
+ * @return the allocated mac descriptor or NULL if the pool is empty
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+MacDescriptor* ixEthDBAllocMacDescriptor(void)
+{
+ MacDescriptor *allocatedDescriptor = ixEthDBPoolAllocMacDescriptor();
+
+ if (allocatedDescriptor != NULL)
+ {
+ LOCK_MAC_POOL;
+
+ allocatedDescriptor->refCount++;
+
+ UNLOCK_MAC_POOL;
+ }
+
+ return allocatedDescriptor;
+}
+
+/**
+ * @brief frees a mac descriptor back into the pool
+ *
+ * @param macDescriptor mac descriptor to be freed
+ *
+ * @warning this function is not to be called by anyone but
+ * ixEthDBFreeMacDescriptor()
+ *
+ * @see ixEthDBFreeMacDescriptor()
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBPoolFreeMacDescriptor(MacDescriptor *macDescriptor)
+{
+ LOCK_MAC_POOL;
+
+ macDescriptor->nextFree = macPool;
+ macPool = macDescriptor;
+
+ UNLOCK_MAC_POOL;
+}
+
+/**
+ * @brief frees or reduces the usage count of a mac descriptor smart pointer
+ *
+ * If the reference count reaches 0 (structure is no longer used anywhere)
+ * then the descriptor is freed back into the pool using ixEthDBPoolFreeMacDescriptor().
+ *
+ * @see ixEthDBPoolFreeMacDescriptor()
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBFreeMacDescriptor(MacDescriptor *macDescriptor)
+{
+ if (macDescriptor != NULL)
+ {
+ LOCK_MAC_POOL;
+
+ if (macDescriptor->refCount > 0)
+ {
+ macDescriptor->refCount--;
+
+ if (macDescriptor->refCount == 0)
+ {
+ UNLOCK_MAC_POOL;
+
+ ixEthDBPoolFreeMacDescriptor(macDescriptor);
+ }
+ else
+ {
+ UNLOCK_MAC_POOL;
+ }
+ }
+ else
+ {
+ UNLOCK_MAC_POOL;
+ }
+ }
+}
+
+/**
+ * @brief clones a mac descriptor smart pointer
+ *
+ * @param macDescriptor mac descriptor to clone
+ *
+ * Increments the usage count of the smart pointer
+ *
+ * @returns the cloned smart pointer
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+MacDescriptor* ixEthDBCloneMacDescriptor(MacDescriptor *macDescriptor)
+{
+ LOCK_MAC_POOL;
+
+ if (macDescriptor->refCount == 0)
+ {
+ UNLOCK_MAC_POOL;
+
+ return NULL;
+ }
+
+ macDescriptor->refCount++;
+
+ UNLOCK_MAC_POOL;
+
+ return macDescriptor;
+}
+
+/**
+ * @brief allocates a mac tree node from the pool
+ *
+ * Allocates and initializes a mac tree node from the pool.
+ *
+ * @return the allocated mac tree node or NULL if the pool is empty
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+MacTreeNode* ixEthDBAllocMacTreeNode(void)
+{
+ MacTreeNode *allocatedNode = NULL;
+
+ if (treePool != NULL)
+ {
+ LOCK_TREE_POOL;
+
+ allocatedNode = treePool;
+ treePool = treePool->nextFree;
+
+ UNLOCK_TREE_POOL;
+
+ memset(allocatedNode, 0, sizeof(MacTreeNode));
+ }
+
+ return allocatedNode;
+}
+
+/**
+ * @brief frees a mac tree node back into the pool
+ *
+ * @param macNode mac tree node to be freed
+ *
+ * @warning not to be used except from ixEthDBFreeMacTreeNode().
+ *
+ * @see ixEthDBFreeMacTreeNode()
+ *
+ * @internal
+ */
+void ixEthDBPoolFreeMacTreeNode(MacTreeNode *macNode)
+{
+ if (macNode != NULL)
+ {
+ LOCK_TREE_POOL;
+
+ macNode->nextFree = treePool;
+ treePool = macNode;
+
+ UNLOCK_TREE_POOL;
+ }
+}
+
+/**
+ * @brief frees or reduces the usage count of a mac tree node smart pointer
+ *
+ * @param macNode mac tree node to free
+ *
+ * Reduces the usage count of the given mac node. If the usage count
+ * reaches 0 the node is freed back into the pool using ixEthDBPoolFreeMacTreeNode()
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBFreeMacTreeNode(MacTreeNode *macNode)
+{
+ if (macNode->descriptor != NULL)
+ {
+ ixEthDBFreeMacDescriptor(macNode->descriptor);
+ }
+
+ if (macNode->left != NULL)
+ {
+ ixEthDBFreeMacTreeNode(macNode->left);
+ }
+
+ if (macNode->right != NULL)
+ {
+ ixEthDBFreeMacTreeNode(macNode->right);
+ }
+
+ ixEthDBPoolFreeMacTreeNode(macNode);
+}
+
+/**
+ * @brief clones a mac tree node
+ *
+ * @param macNode mac tree node to be cloned
+ *
+ * Increments the usage count of the node, <i>its associated descriptor
+ * and <b>recursively</b> of all its child nodes</i>.
+ *
+ * @warning this function is recursive and clones whole trees/subtrees, use only for
+ * root nodes
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+MacTreeNode* ixEthDBCloneMacTreeNode(MacTreeNode *macNode)
+{
+ if (macNode != NULL)
+ {
+ MacTreeNode *clonedMacNode = ixEthDBAllocMacTreeNode();
+
+ if (clonedMacNode != NULL)
+ {
+ if (macNode->right != NULL)
+ {
+ clonedMacNode->right = ixEthDBCloneMacTreeNode(macNode->right);
+ }
+
+ if (macNode->left != NULL)
+ {
+ clonedMacNode->left = ixEthDBCloneMacTreeNode(macNode->left);
+ }
+
+ if (macNode->descriptor != NULL)
+ {
+ clonedMacNode->descriptor = ixEthDBCloneMacDescriptor(macNode->descriptor);
+ }
+ }
+
+ return clonedMacNode;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+#ifndef NDEBUG
+/* Debug statistical functions for memory usage */
+
+extern HashTable dbHashtable;
+int ixEthDBNumHashElements(void);
+
+int ixEthDBNumHashElements(void)
+{
+ UINT32 bucketIndex;
+ int numElements = 0;
+ HashTable *hashTable = &dbHashtable;
+
+ for (bucketIndex = 0 ; bucketIndex < hashTable->numBuckets ; bucketIndex++)
+ {
+ if (hashTable->hashBuckets[bucketIndex] != NULL)
+ {
+ HashNode *node = hashTable->hashBuckets[bucketIndex];
+
+ while (node != NULL)
+ {
+ numElements++;
+
+ node = node->next;
+ }
+ }
+ }
+
+ return numElements;
+}
+
+UINT32 ixEthDBSearchTreeUsageGet(MacTreeNode *tree)
+{
+ if (tree == NULL)
+ {
+ return 0;
+ }
+ else
+ {
+ return 1 /* this node */ + ixEthDBSearchTreeUsageGet(tree->left) + ixEthDBSearchTreeUsageGet(tree->right);
+ }
+}
+
+int ixEthDBShowMemoryStatus(void)
+{
+ MacDescriptor *mac;
+ MacTreeNode *tree;
+ HashNode *node;
+
+ int macCounter = 0;
+ int treeCounter = 0;
+ int nodeCounter = 0;
+
+ int totalTreeUsage = 0;
+ int totalDescriptorUsage = 0;
+ int totalCloneDescriptorUsage = 0;
+ int totalNodeUsage = 0;
+
+ UINT32 portIndex;
+
+ LOCK_NODE_POOL;
+ LOCK_MAC_POOL;
+ LOCK_TREE_POOL;
+
+ mac = macPool;
+ tree = treePool;
+ node = nodePool;
+
+ while (mac != NULL)
+ {
+ macCounter++;
+
+ mac = mac->nextFree;
+
+ if (macCounter > MAC_POOL_SIZE)
+ {
+ break;
+ }
+ }
+
+ while (tree != NULL)
+ {
+ treeCounter++;
+
+ tree = tree->nextFree;
+
+ if (treeCounter > TREE_POOL_SIZE)
+ {
+ break;
+ }
+ }
+
+ while (node != NULL)
+ {
+ nodeCounter++;
+
+ node = node->nextFree;
+
+ if (nodeCounter > NODE_POOL_SIZE)
+ {
+ break;
+ }
+ }
+
+ for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+ {
+ int treeUsage = ixEthDBSearchTreeUsageGet(ixEthDBPortInfo[portIndex].updateMethod.searchTree);
+
+ totalTreeUsage += treeUsage;
+ totalCloneDescriptorUsage += treeUsage; /* each tree node contains a descriptor */
+ }
+
+ totalNodeUsage = ixEthDBNumHashElements();
+ totalDescriptorUsage += totalNodeUsage; /* each hash table entry contains a descriptor */
+
+ UNLOCK_NODE_POOL;
+ UNLOCK_MAC_POOL;
+ UNLOCK_TREE_POOL;
+
+ printf("Ethernet database memory usage stats:\n\n");
+
+ if (macCounter <= MAC_POOL_SIZE)
+ {
+ printf("\tMAC descriptor pool : %d free out of %d entries (%d%%)\n", macCounter, MAC_POOL_SIZE, macCounter * 100 / MAC_POOL_SIZE);
+ }
+ else
+ {
+ printf("\tMAC descriptor pool : invalid state (ring within the pool), normally %d entries\n", MAC_POOL_SIZE);
+ }
+
+ if (treeCounter <= TREE_POOL_SIZE)
+ {
+ printf("\tTree node pool : %d free out of %d entries (%d%%)\n", treeCounter, TREE_POOL_SIZE, treeCounter * 100 / TREE_POOL_SIZE);
+ }
+ else
+ {
+ printf("\tTREE descriptor pool : invalid state (ring within the pool), normally %d entries\n", TREE_POOL_SIZE);
+ }
+
+ if (nodeCounter <= NODE_POOL_SIZE)
+ {
+ printf("\tHash node pool : %d free out of %d entries (%d%%)\n", nodeCounter, NODE_POOL_SIZE, nodeCounter * 100 / NODE_POOL_SIZE);
+ }
+ else
+ {
+ printf("\tNODE descriptor pool : invalid state (ring within the pool), normally %d entries\n", NODE_POOL_SIZE);
+ }
+
+ printf("\n");
+ printf("\tMAC descriptor usage : %d entries, %d cloned\n", totalDescriptorUsage, totalCloneDescriptorUsage);
+ printf("\tTree node usage : %d entries\n", totalTreeUsage);
+ printf("\tHash node usage : %d entries\n", totalNodeUsage);
+ printf("\n");
+
+ /* search for duplicate nodes in the mac pool */
+ {
+ MacDescriptor *reference = macPool;
+
+ while (reference != NULL)
+ {
+ MacDescriptor *comparison = reference->nextFree;
+
+ while (comparison != NULL)
+ {
+ if (reference == comparison)
+ {
+ printf("Warning: reached a duplicate (%p), invalid MAC pool state\n", reference);
+
+ return 1;
+ }
+
+ comparison = comparison->nextFree;
+ }
+
+ reference = reference->nextFree;
+ }
+ }
+
+ printf("No duplicates found in the MAC pool (sanity check ok)\n");
+
+ return 0;
+}
+
+#endif /* NDEBUG */
+
+/**
+ * @} EthMemoryManagement
+ */
diff --git a/cpu/ixp/npe/IxEthDBNPEAdaptor.c b/cpu/ixp/npe/IxEthDBNPEAdaptor.c
new file mode 100644
index 0000000..112a46c
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBNPEAdaptor.c
@@ -0,0 +1,719 @@
+/**
+ * @file IxEthDBDBNPEAdaptor.c
+ *
+ * @brief Routines that read and write learning/search trees in NPE-specific format
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB_p.h"
+#include "IxEthDBLog_p.h"
+
+/* forward prototype declarations */
+IX_ETH_DB_PUBLIC void ixEthDBELTShow(IxEthDBPortId portID);
+IX_ETH_DB_PUBLIC void ixEthDBShowNpeMsgHistory(void);
+
+/* data */
+UINT8* ixEthDBNPEUpdateArea[IX_ETH_DB_NUMBER_OF_PORTS];
+UINT32 dumpEltSize;
+
+/* private data */
+IX_ETH_DB_PRIVATE IxEthDBNoteWriteFn ixEthDBNPENodeWrite[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
+
+#define IX_ETH_DB_MAX_DELTA_ZONES (6) /* at most 6 EP Delta zones, according to NPE FS */
+IX_ETH_DB_PRIVATE UINT32 ixEthDBEPDeltaOffset[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1][IX_ETH_DB_MAX_DELTA_ZONES];
+IX_ETH_DB_PRIVATE UINT32 ixEthDBEPDelta[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1][IX_ETH_DB_MAX_DELTA_ZONES];
+
+/**
+ * @brief allocates non-cached or contiguous NPE tree update areas for all the ports
+ *
+ * This function is called only once at initialization time from
+ * @ref ixEthDBInit().
+ *
+ * @warning do not call manually
+ *
+ * @see ixEthDBInit()
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBNPEUpdateAreasInit(void)
+{
+ UINT32 portIndex;
+ PortUpdateMethod *update;
+
+ for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+ {
+ update = &ixEthDBPortInfo[portIndex].updateMethod;
+
+ if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
+ {
+ update->npeUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_ELT_BYTE_SIZE);
+ update->npeGwUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_GW_BYTE_SIZE);
+ update->vlanUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_VLAN_BYTE_SIZE);
+
+ if (update->npeUpdateZone == NULL
+ || update->npeGwUpdateZone == NULL
+ || update->vlanUpdateZone == NULL)
+ {
+ ERROR_LOG("Fatal error: IX_ACC_DRV_DMA_MALLOC() returned NULL, no NPE update zones available\n");
+ }
+ else
+ {
+ memset(update->npeUpdateZone, 0, FULL_ELT_BYTE_SIZE);
+ memset(update->npeGwUpdateZone, 0, FULL_GW_BYTE_SIZE);
+ memset(update->vlanUpdateZone, 0, FULL_VLAN_BYTE_SIZE);
+ }
+ }
+ else
+ {
+ /* unused */
+ update->npeUpdateZone = NULL;
+ update->npeGwUpdateZone = NULL;
+ update->vlanUpdateZone = NULL;
+ }
+ }
+}
+
+/**
+ * @brief deallocates the NPE update areas for all the ports
+ *
+ * This function is called at component de-initialization time
+ * by @ref ixEthDBUnload().
+ *
+ * @warning do not call manually
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBNPEUpdateAreasUnload(void)
+{
+ UINT32 portIndex;
+
+ for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+ {
+ if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
+ {
+ IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone);
+ IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.npeGwUpdateZone);
+ IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.vlanUpdateZone);
+ }
+ }
+}
+
+/**
+ * @brief general-purpose NPE callback function
+ *
+ * @param npeID NPE ID
+ * @param msg NPE message
+ *
+ * This function will unblock the caller by unlocking
+ * the npeAckLock mutex defined for each NPE port
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBNpeMsgAck(IxNpeMhNpeId npeID, IxNpeMhMessage msg)
+{
+ IxEthDBPortId portID = IX_ETH_DB_NPE_TO_PORT_ID(npeID);
+ PortInfo *portInfo;
+
+ if (portID >= IX_ETH_DB_NUMBER_OF_PORTS)
+ {
+ /* invalid port */
+ return;
+ }
+
+ if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE)
+ {
+ /* not an NPE */
+ return;
+ }
+
+ portInfo = &ixEthDBPortInfo[portID];
+
+ ixOsalMutexUnlock(&portInfo->npeAckLock);
+}
+
+/**
+ * @brief synchronizes the database with tree
+ *
+ * @param portID port ID of the NPE whose tree is to be scanned
+ * @param eltBaseAddress memory base address of the NPE serialized tree
+ * @param eltSize size in bytes of the NPE serialized tree
+ *
+ * Scans the NPE learning tree and resets the age of active database records.
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBNPESyncScan(IxEthDBPortId portID, void *eltBaseAddress, UINT32 eltSize)
+{
+ UINT32 eltEntryOffset;
+ UINT32 entryPortID;
+
+ /* invalidate cache */
+ IX_OSAL_CACHE_INVALIDATE(eltBaseAddress, eltSize);
+
+ for (eltEntryOffset = ELT_ROOT_OFFSET ; eltEntryOffset < eltSize ; eltEntryOffset += ELT_ENTRY_SIZE)
+ {
+ /* (eltBaseAddress + eltEntryOffset) points to a valid NPE tree node
+ *
+ * the format of the node is MAC[6 bytes]:PortID[1 byte]:Reserved[6 bits]:Active[1 bit]:Valid[1 bit]
+ * therefore we can just use the pointer for database searches as only the first 6 bytes are checked
+ */
+ void *eltNodeAddress = (void *) ((UINT32) eltBaseAddress + eltEntryOffset);
+
+ /* debug */
+ IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) checking node at offset %d...\n", eltEntryOffset / ELT_ENTRY_SIZE);
+
+ if (IX_EDB_NPE_NODE_VALID(eltNodeAddress) != TRUE)
+ {
+ IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is empty\n");
+ }
+ else if (eltEntryOffset == ELT_ROOT_OFFSET)
+ {
+ IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is root\n");
+ }
+
+ if (IX_EDB_NPE_NODE_VALID(eltNodeAddress))
+ {
+ entryPortID = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(IX_EDB_NPE_NODE_PORT_ID(eltNodeAddress));
+
+ /* check only active entries belonging to this port */
+ if (ixEthDBPortInfo[portID].agingEnabled && IX_EDB_NPE_NODE_ACTIVE(eltNodeAddress) && (portID == entryPortID)
+ && ((ixEthDBPortDefinitions[portID].capabilities & IX_ETH_ENTRY_AGING) == 0))
+ {
+ /* search record */
+ HashNode *node = ixEthDBSearch((IxEthDBMacAddr *) eltNodeAddress, IX_ETH_DB_ALL_FILTERING_RECORDS);
+
+ /* safety check, maybe user deleted record right before sync? */
+ if (node != NULL)
+ {
+ /* found record */
+ MacDescriptor *descriptor = (MacDescriptor *) node->data;
+
+ IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) synced entry [%s] already in the database, updating fields\n", mac2string(eltNodeAddress));
+
+ /* reset age - set to -1 so that maintenance will restore it to 0 (or more) when incrementing */
+ if (!descriptor->recordData.filteringData.staticEntry)
+ {
+ if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
+ {
+ descriptor->recordData.filteringData.age = AGE_RESET;
+ }
+ else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
+ {
+ descriptor->recordData.filteringVlanData.age = AGE_RESET;
+ }
+ }
+
+ /* end transaction */
+ ixEthDBReleaseHashNode(node);
+ }
+ }
+ else
+ {
+ IX_ETH_DB_NPE_VERBOSE_TRACE("\t... found portID %d, we check only port %d\n", entryPortID, portID);
+ }
+ }
+ }
+}
+
+/**
+ * @brief writes a search tree in NPE format
+ *
+ * @param type type of records to be written into the NPE update zone
+ * @param totalSize maximum size of the linearized tree
+ * @param baseAddress memory base address where to write the NPE tree into
+ * @param tree search tree to write in NPE format
+ * @param blocks number of written 64-byte blocks
+ * @param startIndex optimal binary search start index
+ *
+ * Serializes the given tree in NPE linear format
+ *
+ * @return none
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBNPETreeWrite(IxEthDBRecordType type, UINT32 totalSize, void *baseAddress, MacTreeNode *tree, UINT32 *epDelta, UINT32 *blocks)
+{
+ MacTreeNodeStack *stack;
+ UINT32 maxOffset = 0;
+ UINT32 emptyOffset;
+
+ stack = ixOsalCacheDmaMalloc(sizeof (MacTreeNodeStack));
+
+ if (stack == NULL)
+ {
+ ERROR_LOG("DB: (NPEAdaptor) failed to allocate the node stack for learning tree linearization, out of memory?\n");
+ return;
+ }
+
+ /* zero out empty root */
+ memset(baseAddress, 0, ELT_ENTRY_SIZE);
+
+ NODE_STACK_INIT(stack);
+
+ if (tree != NULL)
+ {
+ /* push tree root at offset 1 */
+ NODE_STACK_PUSH(stack, tree, 1);
+
+ maxOffset = 1;
+ }
+
+ while (NODE_STACK_NONEMPTY(stack))
+ {
+ MacTreeNode *node;
+ UINT32 offset;
+
+ NODE_STACK_POP(stack, node, offset);
+
+ /* update maximum offset */
+ if (offset > maxOffset)
+ {
+ maxOffset = offset;
+ }
+
+ IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) writing MAC [%s] at offset %d\n", mac2string(node->descriptor->macAddress), offset);
+
+ /* add node to NPE ELT at position indicated by offset */
+ if (offset < MAX_ELT_SIZE)
+ {
+ ixEthDBNPENodeWrite[type]((void *) (((UINT32) baseAddress) + offset * ELT_ENTRY_SIZE), node);
+ }
+
+ if (node->left != NULL)
+ {
+ NODE_STACK_PUSH(stack, node->left, LEFT_CHILD_OFFSET(offset));
+ }
+ else
+ {
+ /* ensure this entry is zeroed */
+ memset((void *) ((UINT32) baseAddress + LEFT_CHILD_OFFSET(offset) * ELT_ENTRY_SIZE), 0, ELT_ENTRY_SIZE);
+ }
+
+ if (node->right != NULL)
+ {
+ NODE_STACK_PUSH(stack, node->right, RIGHT_CHILD_OFFSET(offset));
+ }
+ else
+ {
+ /* ensure this entry is zeroed */
+ memset((void *) ((UINT32) baseAddress + RIGHT_CHILD_OFFSET(offset) * ELT_ENTRY_SIZE), 0, ELT_ENTRY_SIZE);
+ }
+ }
+
+ emptyOffset = maxOffset + 1;
+
+ /* zero out rest of the tree */
+ IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Emptying tree from offset %d, address 0x%08X, %d bytes\n",
+ emptyOffset, ((UINT32) baseAddress) + emptyOffset * ELT_ENTRY_SIZE, totalSize - (emptyOffset * ELT_ENTRY_SIZE));
+
+ if (emptyOffset < MAX_ELT_SIZE - 1)
+ {
+ memset((void *) (((UINT32) baseAddress) + (emptyOffset * ELT_ENTRY_SIZE)), 0, totalSize - (emptyOffset * ELT_ENTRY_SIZE));
+ }
+
+ /* flush cache */
+ IX_OSAL_CACHE_FLUSH(baseAddress, totalSize);
+
+ /* debug */
+ IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Ethernet learning/filtering tree XScale wrote at address 0x%08X (max %d bytes):\n\n",
+ (UINT32) baseAddress, FULL_ELT_BYTE_SIZE);
+
+ IX_ETH_DB_NPE_DUMP_ELT(baseAddress, FULL_ELT_BYTE_SIZE);
+
+ /* compute number of 64-byte blocks */
+ if (blocks != NULL)
+ {
+ *blocks = maxOffset != 0 ? 1 + maxOffset / 8 : 0;
+
+ IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Wrote %d 64-byte blocks\n", *blocks);
+ }
+
+ /* compute epDelta - start index for binary search */
+ if (epDelta != NULL)
+ {
+ UINT32 deltaIndex = 0;
+
+ *epDelta = 0;
+
+ for (; deltaIndex < IX_ETH_DB_MAX_DELTA_ZONES ; deltaIndex ++)
+ {
+ if (ixEthDBEPDeltaOffset[type][deltaIndex] >= maxOffset)
+ {
+ *epDelta = ixEthDBEPDelta[type][deltaIndex];
+ break;
+ }
+ }
+
+ IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Computed epDelta %d (based on maxOffset %d)\n", *epDelta, maxOffset);
+ }
+
+ ixOsalCacheDmaFree(stack);
+}
+
+/**
+ * @brief implements a dummy node serialization function
+ *
+ * @param address address of where the node is to be serialized (unused)
+ * @param node tree node to be serialized (unused)
+ *
+ * This function is registered for safety reasons and should
+ * never be called. It will display an error message if this
+ * function is called.
+ *
+ * @return none
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBNullSerialize(void *address, MacTreeNode *node)
+{
+ IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Warning, the NullSerialize function was called, wrong record type?\n");
+}
+
+/**
+ * @brief writes a filtering entry in NPE linear format
+ *
+ * @param address memory address to write node to
+ * @param node node to be written
+ *
+ * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
+ * in NPE-readable format.
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBNPELearningNodeWrite(void *address, MacTreeNode *node)
+{
+ /* copy mac address */
+ memcpy(address, node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
+
+ /* copy port ID */
+ NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET) = IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(node->descriptor->portID);
+
+ /* copy flags (valid and not active, as the NPE sets it to active) and clear reserved section (bits 2-7) */
+ NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) = (UINT8) IX_EDB_FLAGS_INACTIVE_VALID;
+
+ IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) writing ELT node 0x%08x:0x%08x\n", * (UINT32 *) address, * (((UINT32 *) (address)) + 1));
+}
+
+/**
+ * @brief writes a WiFi header conversion record in
+ * NPE linear format
+ *
+ * @param address memory address to write node to
+ * @param node node to be written
+ *
+ * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
+ * in NPE-readable format.
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBNPEWiFiNodeWrite(void *address, MacTreeNode *node)
+{
+ /* copy mac address */
+ memcpy(address, node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
+
+ /* copy index */
+ NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_WIFI_INDEX_OFFSET) = node->descriptor->recordData.wifiData.gwAddressIndex;
+
+ /* copy flags (type and valid) */
+ NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_WIFI_FLAGS_OFFSET) = node->descriptor->recordData.wifiData.type << 1 | IX_EDB_FLAGS_VALID;
+}
+
+/**
+ * @brief writes a WiFi gateway header conversion record in
+ * NPE linear format
+ *
+ * @param address memory address to write node to
+ * @param node node to be written
+ *
+ * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
+ * in NPE-readable format.
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBNPEGatewayNodeWrite(void *address, MacTreeNode *node)
+{
+ /* copy mac address */
+ memcpy(address, node->descriptor->recordData.wifiData.gwMacAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
+
+ /* set reserved field, two bytes */
+ NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET) = 0;
+ NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET + 1) = 0;
+}
+
+/**
+ * @brief writes a firewall record in
+ * NPE linear format
+ *
+ * @param address memory address to write node to
+ * @param node node to be written
+ *
+ * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
+ * in NPE-readable format.
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBNPEFirewallNodeWrite(void *address, MacTreeNode *node)
+{
+ /* set reserved field */
+ NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET) = 0;
+
+ /* set flags */
+ NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_FLAGS_OFFSET) = IX_EDB_FLAGS_VALID;
+
+ /* copy mac address */
+ memcpy((void *) ((UINT32) address + IX_EDB_NPE_NODE_FW_ADDR_OFFSET), node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
+}
+
+/**
+ * @brief registers the NPE serialization methods
+ *
+ * This functions registers NPE serialization methods
+ * for writing the following types of records in NPE
+ * readable linear format:
+ * - filtering records
+ * - WiFi header conversion records
+ * - WiFi gateway header conversion records
+ * - firewall records
+ *
+ * Note that this function should be called by the
+ * component initialization function.
+ *
+ * @return number of registered record types
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+UINT32 ixEthDBRecordSerializeMethodsRegister()
+{
+ int i;
+
+ /* safety - register a blank method for everybody first */
+ for ( i = 0 ; i < IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1 ; i++)
+ {
+ ixEthDBNPENodeWrite[i] = ixEthDBNullSerialize;
+ }
+
+ /* register real methods */
+ ixEthDBNPENodeWrite[IX_ETH_DB_FILTERING_RECORD] = ixEthDBNPELearningNodeWrite;
+ ixEthDBNPENodeWrite[IX_ETH_DB_FILTERING_VLAN_RECORD] = ixEthDBNPELearningNodeWrite;
+ ixEthDBNPENodeWrite[IX_ETH_DB_WIFI_RECORD] = ixEthDBNPEWiFiNodeWrite;
+ ixEthDBNPENodeWrite[IX_ETH_DB_FIREWALL_RECORD] = ixEthDBNPEFirewallNodeWrite;
+ ixEthDBNPENodeWrite[IX_ETH_DB_GATEWAY_RECORD] = ixEthDBNPEGatewayNodeWrite;
+
+ /* EP Delta arrays */
+ memset(ixEthDBEPDeltaOffset, 0, sizeof (ixEthDBEPDeltaOffset));
+ memset(ixEthDBEPDelta, 0, sizeof (ixEthDBEPDelta));
+
+ /* filtering records */
+ ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][0] = 1;
+ ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][0] = 0;
+
+ ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][1] = 3;
+ ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][1] = 7;
+
+ ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][2] = 511;
+ ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][2] = 14;
+
+ /* wifi records */
+ ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][0] = 1;
+ ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][0] = 0;
+
+ ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][1] = 3;
+ ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][1] = 7;
+
+ ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][2] = 511;
+ ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][2] = 14;
+
+ /* firewall records */
+ ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][0] = 0;
+ ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][0] = 0;
+
+ ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][1] = 1;
+ ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][1] = 5;
+
+ ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][2] = 3;
+ ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][2] = 13;
+
+ ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][3] = 7;
+ ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][3] = 21;
+
+ ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][4] = 15;
+ ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][4] = 29;
+
+ ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][5] = 31;
+ ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][5] = 37;
+
+ return 5; /* 5 methods registered */
+}
+
+#ifndef IX_NDEBUG
+
+IX_ETH_DB_PUBLIC UINT32 npeMsgHistory[IX_ETH_DB_NPE_MSG_HISTORY_DEPTH][2];
+IX_ETH_DB_PUBLIC UINT32 npeMsgHistoryLen = 0;
+
+/**
+ * When compiled in DEBUG mode, this function can be used to display
+ * the history of messages sent to the NPEs (up to 100).
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBShowNpeMsgHistory()
+{
+ UINT32 i = 0;
+ UINT32 base, len;
+
+ if (npeMsgHistoryLen <= IX_ETH_DB_NPE_MSG_HISTORY_DEPTH)
+ {
+ base = 0;
+ len = npeMsgHistoryLen;
+ }
+ else
+ {
+ base = npeMsgHistoryLen % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH;
+ len = IX_ETH_DB_NPE_MSG_HISTORY_DEPTH;
+ }
+
+ printf("NPE message history [last %d messages, from least to most recent]:\n", len);
+
+ for (; i < len ; i++)
+ {
+ UINT32 pos = (base + i) % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH;
+ printf("msg[%d]: 0x%08x:0x%08x\n", i, npeMsgHistory[pos][0], npeMsgHistory[pos][1]);
+ }
+}
+
+IX_ETH_DB_PUBLIC
+void ixEthDBELTShow(IxEthDBPortId portID)
+{
+ IxNpeMhMessage message;
+ IX_STATUS result;
+
+ /* send EDB_GetMACAddressDatabase message */
+ FILL_GETMACADDRESSDATABASE(message,
+ 0 /* reserved */,
+ IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portID].updateMethod.npeUpdateZone));
+
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+ if (result == IX_SUCCESS)
+ {
+ /* analyze NPE copy */
+ UINT32 eltEntryOffset;
+ UINT32 entryPortID;
+
+ UINT32 eltBaseAddress = (UINT32) ixEthDBPortInfo[portID].updateMethod.npeUpdateZone;
+ UINT32 eltSize = FULL_ELT_BYTE_SIZE;
+
+ /* invalidate cache */
+ IX_OSAL_CACHE_INVALIDATE((void *) eltBaseAddress, eltSize);
+
+ printf("Listing records in main learning tree for port %d\n", portID);
+
+ for (eltEntryOffset = ELT_ROOT_OFFSET ; eltEntryOffset < eltSize ; eltEntryOffset += ELT_ENTRY_SIZE)
+ {
+ /* (eltBaseAddress + eltEntryOffset) points to a valid NPE tree node
+ *
+ * the format of the node is MAC[6 bytes]:PortID[1 byte]:Reserved[6 bits]:Active[1 bit]:Valid[1 bit]
+ * therefore we can just use the pointer for database searches as only the first 6 bytes are checked
+ */
+ void *eltNodeAddress = (void *) ((UINT32) eltBaseAddress + eltEntryOffset);
+
+ if (IX_EDB_NPE_NODE_VALID(eltNodeAddress))
+ {
+ HashNode *node;
+
+ entryPortID = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(IX_EDB_NPE_NODE_PORT_ID(eltNodeAddress));
+
+ /* search record */
+ node = ixEthDBSearch((IxEthDBMacAddr *) eltNodeAddress, IX_ETH_DB_ALL_RECORD_TYPES);
+
+ printf("%s - port %d - %s ", mac2string((unsigned char *) eltNodeAddress), entryPortID,
+ IX_EDB_NPE_NODE_ACTIVE(eltNodeAddress) ? "active" : "inactive");
+
+ /* safety check, maybe user deleted record right before sync? */
+ if (node != NULL)
+ {
+ /* found record */
+ MacDescriptor *descriptor = (MacDescriptor *) node->data;
+
+ printf("- %s ",
+ descriptor->type == IX_ETH_DB_FILTERING_RECORD ? "filtering" :
+ descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD ? "vlan" :
+ descriptor->type == IX_ETH_DB_WIFI_RECORD ? "wifi" : "other (check main DB)");
+
+ if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) printf("- age %d - %s ",
+ descriptor->recordData.filteringData.age,
+ descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
+
+ if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) printf("- age %d - %s - tci %d ",
+ descriptor->recordData.filteringVlanData.age,
+ descriptor->recordData.filteringVlanData.staticEntry ? "static" : "dynamic",
+ descriptor->recordData.filteringVlanData.ieee802_1qTag);
+
+ /* end transaction */
+ ixEthDBReleaseHashNode(node);
+ }
+ else
+ {
+ printf("- not synced");
+ }
+
+ printf("\n");
+ }
+ }
+ }
+ else
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_FATAL, IX_OSAL_LOG_DEV_STDOUT,
+ "EthDB: (ShowELT) Could not complete action (communication failure)\n",
+ portID, 0, 0, 0, 0, 0);
+ }
+}
+
+#endif
diff --git a/cpu/ixp/npe/IxEthDBPortUpdate.c b/cpu/ixp/npe/IxEthDBPortUpdate.c
new file mode 100644
index 0000000..cdf114b
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBPortUpdate.c
@@ -0,0 +1,740 @@
+/**
+ * @file IxEthDBDBPortUpdate.c
+ *
+ * @brief Implementation of dependency and port update handling
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB_p.h"
+
+/* forward prototype declarations */
+IX_ETH_DB_PRIVATE MacTreeNode* ixEthDBTreeInsert(MacTreeNode *searchTree, MacDescriptor *descriptor);
+IX_ETH_DB_PRIVATE void ixEthDBCreateTrees(IxEthDBPortMap updatePorts);
+IX_ETH_DB_PRIVATE MacTreeNode* ixEthDBTreeRebalance(MacTreeNode *searchTree);
+IX_ETH_DB_PRIVATE void ixEthDBRebalanceTreeToVine(MacTreeNode *root, UINT32 *size);
+IX_ETH_DB_PRIVATE void ixEthDBRebalanceVineToTree(MacTreeNode *root, UINT32 size);
+IX_ETH_DB_PRIVATE void ixEthDBRebalanceCompression(MacTreeNode *root, UINT32 count);
+IX_ETH_DB_PRIVATE UINT32 ixEthDBRebalanceLog2Floor(UINT32 x);
+
+extern HashTable dbHashtable;
+
+/**
+ * @brief register types requiring automatic updates
+ *
+ * @param typeArray array indexed on record types, each
+ * element indicating whether the record type requires an
+ * automatic update (TRUE) or not (FALSE)
+ *
+ * Automatic updates are done for registered record types
+ * upon adding, updating (that is, updating the record portID)
+ * and removing records. Whenever an automatic update is triggered
+ * the appropriate ports will be provided with new database
+ * information.
+ *
+ * It is assumed that the typeArray parameter is allocated large
+ * enough to hold all the user defined types. Also, the type
+ * array should be initialized to FALSE as this function only
+ * caters for types which do require automatic updates.
+ *
+ * Note that this function should be called by the component
+ * initialization function.
+ *
+ * @return number of record types registered for automatic
+ * updates
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+UINT32 ixEthDBUpdateTypeRegister(BOOL *typeArray)
+{
+ typeArray[IX_ETH_DB_FILTERING_RECORD] = TRUE;
+ typeArray[IX_ETH_DB_FILTERING_VLAN_RECORD] = TRUE;
+
+ return 2;
+}
+
+/**
+ * @brief computes dependencies and triggers port learning tree updates
+ *
+ * @param triggerPorts port map consisting in the ports which triggered the update
+ *
+ * This function browses through all the ports and determines how to waterfall the update
+ * event from the trigger ports to all other ports depending on them.
+ *
+ * Once the list of ports to be updated is determined this function
+ * calls @ref ixEthDBCreateTrees.
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBUpdatePortLearningTrees(IxEthDBPortMap triggerPorts)
+{
+ IxEthDBPortMap updatePorts;
+ UINT32 portIndex;
+
+ ixEthDBUpdateLock();
+
+ SET_EMPTY_DEPENDENCY_MAP(updatePorts);
+
+ for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+ {
+ PortInfo *port = &ixEthDBPortInfo[portIndex];
+ BOOL mapsCollide;
+
+ MAPS_COLLIDE(mapsCollide, triggerPorts, port->dependencyPortMap);
+
+ if (mapsCollide /* do triggers influence this port? */
+ && !IS_PORT_INCLUDED(portIndex, updatePorts) /* and it's not already in the update list */
+ && port->updateMethod.updateEnabled) /* and we're allowed to update it */
+ {
+ IX_ETH_DB_UPDATE_TRACE("DB: (Update) Adding port %d to update set\n", portIndex);
+
+ JOIN_PORT_TO_MAP(updatePorts, portIndex);
+ }
+ else
+ {
+ IX_ETH_DB_UPDATE_TRACE("DB: (Update) Didn't add port %d to update set, reasons follow:\n", portIndex);
+
+ if (!mapsCollide)
+ {
+ IX_ETH_DB_UPDATE_TRACE("\tMaps don't collide on port %d\n", portIndex);
+ }
+
+ if (IS_PORT_INCLUDED(portIndex, updatePorts))
+ {
+ IX_ETH_DB_UPDATE_TRACE("\tPort %d is already in the update set\n", portIndex);
+ }
+
+ if (!port->updateMethod.updateEnabled)
+ {
+ IX_ETH_DB_UPDATE_TRACE("\tPort %d doesn't have updateEnabled set\n", portIndex);
+ }
+ }
+ }
+
+ IX_ETH_DB_UPDATE_TRACE("DB: (Update) Updating port set\n");
+
+ ixEthDBCreateTrees(updatePorts);
+
+ ixEthDBUpdateUnlock();
+}
+
+/**
+ * @brief creates learning trees and calls the port update handlers
+ *
+ * @param updatePorts set of ports in need of learning trees
+ *
+ * This function determines the optimal method of creating learning
+ * trees using a minimal number of database queries, keeping in mind
+ * that different ports can either use the same learning trees or they
+ * can partially share them. The actual tree building routine is
+ * @ref ixEthDBQuery.
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBCreateTrees(IxEthDBPortMap updatePorts)
+{
+ UINT32 portIndex;
+ BOOL result;
+ BOOL portsLeft = TRUE;
+
+ while (portsLeft)
+ {
+ /* get port with minimal dependency map and NULL search tree */
+ UINT32 minPortIndex = MAX_PORT_SIZE;
+ UINT32 minimalSize = MAX_PORT_SIZE;
+
+ for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+ {
+ UINT32 size;
+ PortInfo *port = &ixEthDBPortInfo[portIndex];
+
+ /* generate trees only for ports that need them */
+ if (!port->updateMethod.searchTreePendingWrite && IS_PORT_INCLUDED(portIndex, updatePorts))
+ {
+ GET_MAP_SIZE(port->dependencyPortMap, size);
+
+ IX_ETH_DB_UPDATE_TRACE("DB: (Update) Dependency map for port %d: size %d\n",
+ portIndex, size);
+
+ if (size < minimalSize)
+ {
+ minPortIndex = portIndex;
+ minimalSize = size;
+ }
+ }
+ else
+ {
+ IX_ETH_DB_UPDATE_TRACE("DB: (Update) Skipped port %d from tree diff (%s)\n", portIndex,
+ port->updateMethod.searchTreePendingWrite ? "pending write access" : "ignored by query");
+ }
+ }
+
+ /* if a port was found than minimalSize is not MAX_PORT_SIZE */
+ if (minimalSize != MAX_PORT_SIZE)
+ {
+ /* minPortIndex is the port we seek */
+ PortInfo *port = &ixEthDBPortInfo[minPortIndex];
+
+ IxEthDBPortMap query;
+ MacTreeNode *baseTree;
+
+ /* now try to find a port with minimal map difference */
+ PortInfo *minimalDiffPort = NULL;
+ UINT32 minimalDiff = MAX_PORT_SIZE;
+
+ IX_ETH_DB_UPDATE_TRACE("DB: (Update) Minimal size port is %d\n", minPortIndex);
+
+ for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+ {
+ PortInfo *diffPort = &ixEthDBPortInfo[portIndex];
+ BOOL mapIsSubset;
+
+ IS_MAP_SUBSET(mapIsSubset, diffPort->dependencyPortMap, port->dependencyPortMap);
+
+
+ if (portIndex != minPortIndex
+ && diffPort->updateMethod.searchTree != NULL
+ && mapIsSubset)
+ {
+ /* compute size and pick only minimal size difference */
+ UINT32 diffPortSize;
+ UINT32 sizeDifference;
+
+ GET_MAP_SIZE(diffPort->dependencyPortMap, diffPortSize);
+
+ IX_ETH_DB_UPDATE_TRACE("DB: (Update) Checking port %d for differences...\n", portIndex);
+
+ sizeDifference = minimalSize - diffPortSize;
+
+ if (sizeDifference < minimalDiff)
+ {
+ minimalDiffPort = diffPort;
+ minimalDiff = sizeDifference;
+
+ IX_ETH_DB_UPDATE_TRACE("DB: (Update) Minimal difference 0x%x was found on port %d\n",
+ minimalDiff, portIndex);
+ }
+ }
+ }
+
+ /* check if filtering is enabled on this port */
+ if ((port->featureStatus & IX_ETH_DB_FILTERING) != 0)
+ {
+ /* if minimalDiff is not MAX_PORT_SIZE minimalDiffPort points to the most similar port */
+ if (minimalDiff != MAX_PORT_SIZE)
+ {
+ baseTree = ixEthDBCloneMacTreeNode(minimalDiffPort->updateMethod.searchTree);
+ DIFF_MAPS(query, port->dependencyPortMap , minimalDiffPort->dependencyPortMap);
+
+ IX_ETH_DB_UPDATE_TRACE("DB: (Update) Found minimal diff, extending tree %d on query\n",
+ minimalDiffPort->portID);
+ }
+ else /* .. otherwise no similar port was found, build tree from scratch */
+ {
+ baseTree = NULL;
+
+ COPY_DEPENDENCY_MAP(query, port->dependencyPortMap);
+
+ IX_ETH_DB_UPDATE_TRACE("DB: (Update) No similar diff, creating tree from query\n");
+ }
+
+ IS_EMPTY_DEPENDENCY_MAP(result, query);
+
+ if (!result) /* otherwise we don't need anything more on top of the cloned tree */
+ {
+ IX_ETH_DB_UPDATE_TRACE("DB: (Update) Adding query tree to port %d\n", minPortIndex);
+
+ /* build learning tree */
+ port->updateMethod.searchTree = ixEthDBQuery(baseTree, query, IX_ETH_DB_ALL_FILTERING_RECORDS, MAX_ELT_SIZE);
+ }
+ else
+ {
+ IX_ETH_DB_UPDATE_TRACE("DB: (Update) Query is empty, assuming identical nearest tree\n");
+
+ port->updateMethod.searchTree = baseTree;
+ }
+ }
+ else
+ {
+ /* filtering is not enabled, will download an empty tree */
+ if (port->updateMethod.searchTree != NULL)
+ {
+ ixEthDBFreeMacTreeNode(port->updateMethod.searchTree);
+ }
+
+ port->updateMethod.searchTree = NULL;
+ }
+
+ /* mark tree as valid */
+ port->updateMethod.searchTreePendingWrite = TRUE;
+ }
+ else
+ {
+ portsLeft = FALSE;
+
+ IX_ETH_DB_UPDATE_TRACE("DB: (Update) No trees to create this round\n");
+ }
+ }
+
+ for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+ {
+ PortInfo *updatePort = &ixEthDBPortInfo[portIndex];
+
+ if (updatePort->updateMethod.searchTreePendingWrite)
+ {
+ IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) Starting procedure to upload new search tree (%snull) into NPE %d\n",
+ updatePort->updateMethod.searchTree != NULL ? "not " : "",
+ portIndex);
+
+ updatePort->updateMethod.updateHandler(portIndex, IX_ETH_DB_FILTERING_RECORD);
+ }
+ }
+}
+
+/**
+ * @brief standard NPE update handler
+ *
+ * @param portID id of the port to be updated
+ * @param type record type to be pushed during this update
+ *
+ * The NPE update handler manages updating the NPE databases
+ * given a certain record type.
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBNPEUpdateHandler(IxEthDBPortId portID, IxEthDBRecordType type)
+{
+ UINT32 epDelta, blockCount;
+ IxNpeMhMessage message;
+ UINT32 treeSize = 0;
+ PortInfo *port = &ixEthDBPortInfo[portID];
+
+ /* size selection and type check */
+ if (type == IX_ETH_DB_FILTERING_RECORD || type == IX_ETH_DB_WIFI_RECORD)
+ {
+ treeSize = FULL_ELT_BYTE_SIZE;
+ }
+ else if (type == IX_ETH_DB_FIREWALL_RECORD)
+ {
+ treeSize = FULL_FW_BYTE_SIZE;
+ }
+ else
+ {
+ return IX_ETH_DB_INVALID_ARG;
+ }
+
+ /* serialize tree into memory */
+ ixEthDBNPETreeWrite(type, treeSize, port->updateMethod.npeUpdateZone, port->updateMethod.searchTree, &epDelta, &blockCount);
+
+ /* free internal copy */
+ if (port->updateMethod.searchTree != NULL)
+ {
+ ixEthDBFreeMacTreeNode(port->updateMethod.searchTree);
+ }
+
+ /* forget last used search tree */
+ port->updateMethod.searchTree = NULL;
+ port->updateMethod.searchTreePendingWrite = FALSE;
+
+ /* dependending on the update type we do different things */
+ if (type == IX_ETH_DB_FILTERING_RECORD || type == IX_ETH_DB_WIFI_RECORD)
+ {
+ IX_STATUS result;
+
+ FILL_SETMACADDRESSDATABASE_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID),
+ epDelta, blockCount,
+ IX_OSAL_MMU_VIRT_TO_PHYS(port->updateMethod.npeUpdateZone));
+
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+ if (result == IX_SUCCESS)
+ {
+ IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) Finished downloading NPE tree on port %d\n", portID);
+ }
+ else
+ {
+ ixEthDBPortInfo[portID].agingEnabled = FALSE;
+ ixEthDBPortInfo[portID].updateMethod.updateEnabled = FALSE;
+ ixEthDBPortInfo[portID].updateMethod.userControlled = TRUE;
+
+ ERROR_LOG("EthDB: (PortUpdate) disabling aging and updates on port %d (assumed dead)\n", portID);
+
+ ixEthDBDatabaseClear(portID, IX_ETH_DB_ALL_RECORD_TYPES);
+
+ return IX_ETH_DB_FAIL;
+ }
+
+ return IX_ETH_DB_SUCCESS;
+ }
+ else if (type == IX_ETH_DB_FIREWALL_RECORD)
+ {
+ return ixEthDBFirewallUpdate(portID, port->updateMethod.npeUpdateZone, epDelta);
+ }
+
+ return IX_ETH_DB_INVALID_ARG;
+}
+
+/**
+ * @brief queries the database for a set of records to be inserted into a given tree
+ *
+ * @param searchTree pointer to a tree where insertions will be performed; can be NULL
+ * @param query set of ports that a database record must match to be inserted into the tree
+ *
+ * The query method browses through the database, extracts all the descriptors matching
+ * the given query parameter and inserts them into the given learning tree.
+ * Note that this is an append procedure, the given tree needs not to be empty.
+ * A "descriptor matching the query" is a descriptor whose port id is in the query map.
+ * If the given tree is empty (NULL) a new tree is created and returned.
+ *
+ * @return the tree root
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+MacTreeNode* ixEthDBQuery(MacTreeNode *searchTree, IxEthDBPortMap query, IxEthDBRecordType recordFilter, UINT32 maxEntries)
+{
+ HashIterator iterator;
+ UINT32 entryCount = 0;
+
+ /* browse database */
+ BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
+
+ while (IS_ITERATOR_VALID(&iterator))
+ {
+ MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
+
+ IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) querying [%s]:%d on port map ... ",
+ mac2string(descriptor->macAddress),
+ descriptor->portID);
+
+ if ((descriptor->type & recordFilter) != 0
+ && IS_PORT_INCLUDED(descriptor->portID, query))
+ {
+ MacDescriptor *descriptorClone = ixEthDBCloneMacDescriptor(descriptor);
+
+ IX_ETH_DB_UPDATE_TRACE("match\n");
+
+ if (descriptorClone != NULL)
+ {
+ /* add descriptor to tree */
+ searchTree = ixEthDBTreeInsert(searchTree, descriptorClone);
+
+ entryCount++;
+ }
+ }
+ else
+ {
+ IX_ETH_DB_UPDATE_TRACE("no match\n");
+ }
+
+ if (entryCount < maxEntries)
+ {
+ /* advance to the next record */
+ BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
+ }
+ else
+ {
+ /* the NPE won't accept more entries so we can stop now */
+ ixEthDBReleaseHashIterator(&iterator);
+
+ IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) number of elements reached maximum supported by port\n");
+
+ break;
+ }
+ }
+
+ IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) query inserted %d records in the search tree\n", entryCount);
+
+ return ixEthDBTreeRebalance(searchTree);
+}
+
+/**
+ * @brief inserts a mac descriptor into an tree
+ *
+ * @param searchTree tree where the insertion is to be performed (may be NULL)
+ * @param descriptor descriptor to insert into tree
+ *
+ * @return the tree root
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+MacTreeNode* ixEthDBTreeInsert(MacTreeNode *searchTree, MacDescriptor *descriptor)
+{
+ MacTreeNode *currentNode = searchTree;
+ MacTreeNode *insertLocation = NULL;
+ MacTreeNode *newNode;
+ INT32 insertPosition = RIGHT;
+
+ if (descriptor == NULL)
+ {
+ return searchTree;
+ }
+
+ /* create a new node */
+ newNode = ixEthDBAllocMacTreeNode();
+
+ if (newNode == NULL)
+ {
+ /* out of memory */
+ ERROR_LOG("Warning: ixEthDBAllocMacTreeNode returned NULL in file %s:%d (out of memory?)\n", __FILE__, __LINE__);
+
+ ixEthDBFreeMacDescriptor(descriptor);
+
+ return NULL;
+ }
+
+ /* populate node */
+ newNode->descriptor = descriptor;
+
+ /* an empty initial tree is a special case */
+ if (searchTree == NULL)
+ {
+ return newNode;
+ }
+
+ /* get insertion location */
+ while (insertLocation == NULL)
+ {
+ MacTreeNode *nextNode;
+
+ /* compare given key with current node key */
+ insertPosition = ixEthDBAddressCompare(descriptor->macAddress, currentNode->descriptor->macAddress);
+
+ /* navigate down */
+ if (insertPosition == RIGHT)
+ {
+ nextNode = currentNode->right;
+ }
+ else if (insertPosition == LEFT)
+ {
+ nextNode = currentNode->left;
+ }
+ else
+ {
+ /* error, duplicate key */
+ ERROR_LOG("Warning: trapped insertion of a duplicate MAC address in an NPE search tree\n");
+
+ /* this will free the MAC descriptor as well */
+ ixEthDBFreeMacTreeNode(newNode);
+
+ return searchTree;
+ }
+
+ /* when we can no longer dive through the tree we found the insertion place */
+ if (nextNode != NULL)
+ {
+ currentNode = nextNode;
+ }
+ else
+ {
+ insertLocation = currentNode;
+ }
+ }
+
+ /* insert node */
+ if (insertPosition == RIGHT)
+ {
+ insertLocation->right = newNode;
+ }
+ else
+ {
+ insertLocation->left = newNode;
+ }
+
+ return searchTree;
+}
+
+/**
+ * @brief balance a tree
+ *
+ * @param searchTree tree to balance
+ *
+ * Converts a tree into a balanced tree and returns the root of
+ * the balanced tree. The resulting tree is <i>route balanced</i>
+ * not <i>perfectly balanced</i>. This makes no difference to the
+ * average tree search time which is the same in both cases, O(log2(n)).
+ *
+ * @return root of the balanced tree or NULL if there's no memory left
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+MacTreeNode* ixEthDBTreeRebalance(MacTreeNode *searchTree)
+{
+ MacTreeNode *pseudoRoot = ixEthDBAllocMacTreeNode();
+ UINT32 size;
+
+ if (pseudoRoot == NULL)
+ {
+ /* out of memory */
+ return NULL;
+ }
+
+ pseudoRoot->right = searchTree;
+
+ ixEthDBRebalanceTreeToVine(pseudoRoot, &size);
+ ixEthDBRebalanceVineToTree(pseudoRoot, size);
+
+ searchTree = pseudoRoot->right;
+
+ /* remove pseudoRoot right branch, otherwise it will free the entire tree */
+ pseudoRoot->right = NULL;
+
+ ixEthDBFreeMacTreeNode(pseudoRoot);
+
+ return searchTree;
+}
+
+/**
+ * @brief converts a tree into a vine
+ *
+ * @param root root of tree to convert
+ * @param size depth of vine (equal to the number of nodes in the tree)
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBRebalanceTreeToVine(MacTreeNode *root, UINT32 *size)
+{
+ MacTreeNode *vineTail = root;
+ MacTreeNode *remainder = vineTail->right;
+ MacTreeNode *tempPtr;
+
+ *size = 0;
+
+ while (remainder != NULL)
+ {
+ if (remainder->left == NULL)
+ {
+ /* move tail down one */
+ vineTail = remainder;
+ remainder = remainder->right;
+ (*size)++;
+ }
+ else
+ {
+ /* rotate around remainder */
+ tempPtr = remainder->left;
+ remainder->left = tempPtr->right;
+ tempPtr->right = remainder;
+ remainder = tempPtr;
+ vineTail->right = tempPtr;
+ }
+ }
+}
+
+/**
+ * @brief converts a vine into a balanced tree
+ *
+ * @param root vine to convert
+ * @param size depth of vine
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBRebalanceVineToTree(MacTreeNode *root, UINT32 size)
+{
+ UINT32 leafCount = size + 1 - (1 << ixEthDBRebalanceLog2Floor(size + 1));
+
+ ixEthDBRebalanceCompression(root, leafCount);
+
+ size = size - leafCount;
+
+ while (size > 1)
+ {
+ ixEthDBRebalanceCompression(root, size / 2);
+
+ size /= 2;
+ }
+}
+
+/**
+ * @brief compresses a vine/tree stage into a more balanced vine/tree
+ *
+ * @param root root of the tree to compress
+ * @param count number of "spine" nodes
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBRebalanceCompression(MacTreeNode *root, UINT32 count)
+{
+ MacTreeNode *scanner = root;
+ MacTreeNode *child;
+ UINT32 local_index;
+
+ for (local_index = 0 ; local_index < count ; local_index++)
+ {
+ child = scanner->right;
+ scanner->right = child->right;
+ scanner = scanner->right;
+ child->right = scanner->left;
+ scanner->left = child;
+ }
+}
+
+/**
+ * @brief computes |_log2(x)_| (a.k.a. floor(log2(x)))
+ *
+ * @param x number to compute |_log2(x)_| for
+ *
+ * @return |_log2(x)_|
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+UINT32 ixEthDBRebalanceLog2Floor(UINT32 x)
+{
+ UINT32 log = 0;
+ UINT32 val = 1;
+
+ while (val < x)
+ {
+ log++;
+ val <<= 1;
+ }
+
+ return val == x ? log : log - 1;
+}
+
diff --git a/cpu/ixp/npe/IxEthDBReports.c b/cpu/ixp/npe/IxEthDBReports.c
new file mode 100644
index 0000000..9c7ae1c
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBReports.c
@@ -0,0 +1,652 @@
+/**
+ * @file IxEthDBAPI.c
+ *
+ * @brief Implementation of the public API
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB_p.h"
+
+extern HashTable dbHashtable;
+IX_ETH_DB_PRIVATE void ixEthDBPortInfoShow(IxEthDBPortId portID, IxEthDBRecordType recordFilter);
+IX_ETH_DB_PRIVATE IxEthDBStatus ixEthDBHeaderShow(IxEthDBRecordType recordFilter);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBDependencyPortMapShow(IxEthDBPortId portID, IxEthDBPortMap map);
+
+/**
+ * @brief displays a port dependency map
+ *
+ * @param portID ID of the port
+ * @param map port map to display
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBDependencyPortMapShow(IxEthDBPortId portID, IxEthDBPortMap map)
+{
+ UINT32 portIndex;
+ BOOL mapSelf = TRUE, mapNone = TRUE, firstPort = TRUE;
+
+ /* dependency port maps */
+ printf("Dependency port map: ");
+
+ /* browse the port map */
+ for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+ {
+ if (IS_PORT_INCLUDED(portIndex, map))
+ {
+ mapNone = FALSE;
+
+ if (portIndex != portID)
+ {
+ mapSelf = FALSE;
+ }
+
+ printf("%s%d", firstPort ? "{" : ", ", portIndex);
+
+ firstPort = FALSE;
+ }
+ }
+
+ if (mapNone)
+ {
+ mapSelf = FALSE;
+ }
+
+ printf("%s (%s)\n", firstPort ? "" : "}", mapSelf ? "self" : mapNone ? "none" : "group");
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief displays all the filtering records belonging to a port
+ *
+ * @param portID ID of the port to display
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @warning deprecated, use @ref ixEthDBFilteringDatabaseShowRecords()
+ * instead. Calling this function is equivalent to calling
+ * ixEthDBFilteringDatabaseShowRecords(portID, IX_ETH_DB_FILTERING_RECORD)
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID)
+{
+ IxEthDBStatus local_result;
+ HashIterator iterator;
+ PortInfo *portInfo;
+ UINT32 recordCount = 0;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ portInfo = &ixEthDBPortInfo[portID];
+
+ /* display table header */
+ printf("Ethernet database records for port ID [%d]\n", portID);
+
+ ixEthDBDependencyPortMapShow(portID, portInfo->dependencyPortMap);
+
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ printf("NPE updates are %s\n\n", portInfo->updateMethod.updateEnabled ? "enabled" : "disabled");
+ }
+ else
+ {
+ printf("updates disabled (not an NPE)\n\n");
+ }
+
+ printf(" MAC address | Age | Type \n");
+ printf("___________________________________\n");
+
+ /* browse database */
+ BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
+
+ while (IS_ITERATOR_VALID(&iterator))
+ {
+ MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
+
+ if (descriptor->portID == portID && descriptor->type == IX_ETH_DB_FILTERING_RECORD)
+ {
+ recordCount++;
+
+ /* display entry */
+ printf(" %02X:%02X:%02X:%02X:%02X:%02X | %5d | %s\n",
+ descriptor->macAddress[0],
+ descriptor->macAddress[1],
+ descriptor->macAddress[2],
+ descriptor->macAddress[3],
+ descriptor->macAddress[4],
+ descriptor->macAddress[5],
+ descriptor->recordData.filteringData.age,
+ descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
+ }
+
+ /* move to the next record */
+ BUSY_RETRY_WITH_RESULT(ixEthDBIncrementHashIterator(&dbHashtable, &iterator), local_result);
+
+ /* debug */
+ if (local_result == IX_ETH_DB_BUSY)
+ {
+ return IX_ETH_DB_FAIL;
+ }
+ }
+
+ /* display number of records */
+ printf("\nFound %d records\n", recordCount);
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief displays all the filtering records belonging to all the ports
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @warning deprecated, use @ref ixEthDBFilteringDatabaseShowRecords()
+ * instead. Calling this function is equivalent to calling
+ * ixEthDBFilteringDatabaseShowRecords(IX_ETH_DB_ALL_PORTS, IX_ETH_DB_FILTERING_RECORD)
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBFilteringDatabaseShowAll()
+{
+ IxEthDBPortId portIndex;
+
+ printf("\nEthernet learning/filtering database: listing %d ports\n\n", (UINT32) IX_ETH_DB_NUMBER_OF_PORTS);
+
+ for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+ {
+ ixEthDBFilteringDatabaseShow(portIndex);
+
+ if (portIndex < IX_ETH_DB_NUMBER_OF_PORTS - 1)
+ {
+ printf("\n");
+ }
+ }
+}
+
+/**
+ * @brief displays one record in a format depending on the record filter
+ *
+ * @param descriptor pointer to the record
+ * @param recordFilter format filter
+ *
+ * This function will display the fields in a record depending on the
+ * selected record filter.
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBRecordShow(MacDescriptor *descriptor, IxEthDBRecordType recordFilter)
+{
+ if (recordFilter == IX_ETH_DB_FILTERING_VLAN_RECORD
+ || recordFilter == (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD))
+ {
+ /* display VLAN record header - leave this commented code in place, its purpose is to align the print format with the header
+ printf(" MAC address | Age | Type | VLAN ID | CFI | QoS class \n");
+ printf("___________________________________________________________________\n"); */
+
+ if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
+ {
+ printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s | %d | %d | %d\n",
+ descriptor->macAddress[0],
+ descriptor->macAddress[1],
+ descriptor->macAddress[2],
+ descriptor->macAddress[3],
+ descriptor->macAddress[4],
+ descriptor->macAddress[5],
+ descriptor->recordData.filteringVlanData.age,
+ descriptor->recordData.filteringVlanData.staticEntry ? "static" : "dynamic",
+ IX_ETH_DB_GET_VLAN_ID(descriptor->recordData.filteringVlanData.ieee802_1qTag),
+ (descriptor->recordData.filteringVlanData.ieee802_1qTag & 0x1000) >> 12,
+ IX_ETH_DB_GET_QOS_PRIORITY(descriptor->recordData.filteringVlanData.ieee802_1qTag));
+ }
+ else if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
+ {
+ printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s | - | - | -\n",
+ descriptor->macAddress[0],
+ descriptor->macAddress[1],
+ descriptor->macAddress[2],
+ descriptor->macAddress[3],
+ descriptor->macAddress[4],
+ descriptor->macAddress[5],
+ descriptor->recordData.filteringData.age,
+ descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
+ }
+ }
+ else if (recordFilter == IX_ETH_DB_FILTERING_RECORD)
+ {
+ /* display filtering record header - leave this commented code in place, its purpose is to align the print format with the header
+ printf(" MAC address | Age | Type \n");
+ printf("_______________________________________\n"); */
+
+ if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
+ {
+ printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s \n",
+ descriptor->macAddress[0],
+ descriptor->macAddress[1],
+ descriptor->macAddress[2],
+ descriptor->macAddress[3],
+ descriptor->macAddress[4],
+ descriptor->macAddress[5],
+ descriptor->recordData.filteringData.age,
+ descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
+ }
+ }
+ else if (recordFilter == IX_ETH_DB_WIFI_RECORD)
+ {
+ /* display WiFi record header - leave this commented code in place, its purpose is to align the print format with the header
+ printf(" MAC address | GW MAC address \n");
+ printf("_______________________________________\n"); */
+
+ if (descriptor->type == IX_ETH_DB_WIFI_RECORD)
+ {
+ if (descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP)
+ {
+ /* gateway address present */
+ printf("%02X:%02X:%02X:%02X:%02X:%02X | %02X:%02X:%02X:%02X:%02X:%02X \n",
+ descriptor->macAddress[0],
+ descriptor->macAddress[1],
+ descriptor->macAddress[2],
+ descriptor->macAddress[3],
+ descriptor->macAddress[4],
+ descriptor->macAddress[5],
+ descriptor->recordData.wifiData.gwMacAddress[0],
+ descriptor->recordData.wifiData.gwMacAddress[1],
+ descriptor->recordData.wifiData.gwMacAddress[2],
+ descriptor->recordData.wifiData.gwMacAddress[3],
+ descriptor->recordData.wifiData.gwMacAddress[4],
+ descriptor->recordData.wifiData.gwMacAddress[5]);
+ }
+ else
+ {
+ /* no gateway */
+ printf("%02X:%02X:%02X:%02X:%02X:%02X | ----no gateway----- \n",
+ descriptor->macAddress[0],
+ descriptor->macAddress[1],
+ descriptor->macAddress[2],
+ descriptor->macAddress[3],
+ descriptor->macAddress[4],
+ descriptor->macAddress[5]);
+ }
+ }
+ }
+ else if (recordFilter == IX_ETH_DB_FIREWALL_RECORD)
+ {
+ /* display Firewall record header - leave this commented code in place, its purpose is to align the print format with the header
+ printf(" MAC address \n");
+ printf("__________________\n"); */
+
+ if (descriptor->type == IX_ETH_DB_FIREWALL_RECORD)
+ {
+ printf("%02X:%02X:%02X:%02X:%02X:%02X \n",
+ descriptor->macAddress[0],
+ descriptor->macAddress[1],
+ descriptor->macAddress[2],
+ descriptor->macAddress[3],
+ descriptor->macAddress[4],
+ descriptor->macAddress[5]);
+ }
+ }
+ else if (recordFilter == IX_ETH_DB_ALL_RECORD_TYPES)
+ {
+ /* display composite record header - leave this commented code in place, its purpose is to align the print format with the header
+ printf(" MAC address | Record | Age| Type | VLAN |CFI| QoS | GW MAC address \n");
+ printf("_______________________________________________________________________________\n"); */
+
+ if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
+ {
+ printf("%02X:%02X:%02X:%02X:%02X:%02X | VLAN | %2d | %s | %4d | %1d | %1d | -----------------\n",
+ descriptor->macAddress[0],
+ descriptor->macAddress[1],
+ descriptor->macAddress[2],
+ descriptor->macAddress[3],
+ descriptor->macAddress[4],
+ descriptor->macAddress[5],
+ descriptor->recordData.filteringVlanData.age,
+ descriptor->recordData.filteringVlanData.staticEntry ? "static " : "dynamic",
+ IX_ETH_DB_GET_VLAN_ID(descriptor->recordData.filteringVlanData.ieee802_1qTag),
+ (descriptor->recordData.filteringVlanData.ieee802_1qTag & 0x1000) >> 12,
+ IX_ETH_DB_GET_QOS_PRIORITY(descriptor->recordData.filteringVlanData.ieee802_1qTag));
+ }
+ else if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
+ {
+ printf("%02X:%02X:%02X:%02X:%02X:%02X | Filter | %2d | %s | ---- | - | --- | -----------------\n",
+ descriptor->macAddress[0],
+ descriptor->macAddress[1],
+ descriptor->macAddress[2],
+ descriptor->macAddress[3],
+ descriptor->macAddress[4],
+ descriptor->macAddress[5],
+ descriptor->recordData.filteringData.age,
+ descriptor->recordData.filteringData.staticEntry ? "static " : "dynamic");
+ }
+ else if (descriptor->type == IX_ETH_DB_WIFI_RECORD)
+ {
+ if (descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP)
+ {
+ /* gateway address present */
+ printf("%02X:%02X:%02X:%02X:%02X:%02X | WiFi | -- | AP=>AP | ---- | - | --- | %02X:%02X:%02X:%02X:%02X:%02X\n",
+ descriptor->macAddress[0],
+ descriptor->macAddress[1],
+ descriptor->macAddress[2],
+ descriptor->macAddress[3],
+ descriptor->macAddress[4],
+ descriptor->macAddress[5],
+ descriptor->recordData.wifiData.gwMacAddress[0],
+ descriptor->recordData.wifiData.gwMacAddress[1],
+ descriptor->recordData.wifiData.gwMacAddress[2],
+ descriptor->recordData.wifiData.gwMacAddress[3],
+ descriptor->recordData.wifiData.gwMacAddress[4],
+ descriptor->recordData.wifiData.gwMacAddress[5]);
+ }
+ else
+ {
+ /* no gateway */
+ printf("%02X:%02X:%02X:%02X:%02X:%02X | WiFi | -- | AP=>ST | ---- | - | --- | -- no gateway -- \n",
+ descriptor->macAddress[0],
+ descriptor->macAddress[1],
+ descriptor->macAddress[2],
+ descriptor->macAddress[3],
+ descriptor->macAddress[4],
+ descriptor->macAddress[5]);
+ }
+ }
+ else if (descriptor->type == IX_ETH_DB_FIREWALL_RECORD)
+ {
+ printf("%02X:%02X:%02X:%02X:%02X:%02X | FW | -- | ------- | ---- | - | --- | -----------------\n",
+ descriptor->macAddress[0],
+ descriptor->macAddress[1],
+ descriptor->macAddress[2],
+ descriptor->macAddress[3],
+ descriptor->macAddress[4],
+ descriptor->macAddress[5]);
+ }
+ }
+ else
+ {
+ printf("invalid record filter\n");
+ }
+}
+
+/**
+ * @brief displays the status, records and configuration information of a port
+ *
+ * @param portID ID of the port
+ * @param recordFilter record filter to display
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBPortInfoShow(IxEthDBPortId portID, IxEthDBRecordType recordFilter)
+{
+ PortInfo *portInfo = &ixEthDBPortInfo[portID];
+ UINT32 recordCount = 0;
+ HashIterator iterator;
+ IxEthDBStatus local_result;
+
+ /* display port status */
+ printf("== Port ID %d ==\n", portID);
+
+ /* display capabilities */
+ printf("- Capabilities: ");
+
+ if ((portInfo->featureCapability & IX_ETH_DB_LEARNING) != 0)
+ {
+ printf("Learning (%s) ", ((portInfo->featureStatus & IX_ETH_DB_LEARNING) != 0) ? "on" : "off");
+ }
+
+ if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
+ {
+ printf("VLAN/QoS (%s) ", ((portInfo->featureStatus & IX_ETH_DB_VLAN_QOS) != 0) ? "on" : "off");
+ }
+
+ if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
+ {
+ printf("Firewall (%s) ", ((portInfo->featureStatus & IX_ETH_DB_FIREWALL) != 0) ? "on" : "off");
+ }
+
+ if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
+ {
+ printf("WiFi (%s) ", ((portInfo->featureStatus & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0) ? "on" : "off");
+ }
+
+ if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
+ {
+ printf("STP (%s) ", ((portInfo->featureStatus & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0) ? "on" : "off");
+ }
+
+ printf("\n");
+
+ /* dependency map */
+ ixEthDBDependencyPortMapShow(portID, portInfo->dependencyPortMap);
+
+ /* NPE dynamic updates */
+ if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+ {
+ printf(" - NPE dynamic update is %s\n", portInfo->updateMethod.updateEnabled ? "enabled" : "disabled");
+ }
+ else
+ {
+ printf(" - dynamic update disabled (not an NPE)\n");
+ }
+
+ if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
+ {
+ if ((portInfo->featureStatus & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
+ {
+ /* WiFi header conversion */
+ if ((portInfo->frameControlDurationID
+ + portInfo->bbsid[0]
+ + portInfo->bbsid[1]
+ + portInfo->bbsid[2]
+ + portInfo->bbsid[3]
+ + portInfo->bbsid[4]
+ + portInfo->bbsid[5]) == 0)
+ {
+ printf(" - WiFi header conversion not configured\n");
+ }
+ else
+ {
+ printf(" - WiFi header conversion: BBSID [%02X:%02X:%02X:%02X:%02X:%02X], Frame Control 0x%X, Duration/ID 0x%X\n",
+ portInfo->bbsid[0],
+ portInfo->bbsid[1],
+ portInfo->bbsid[2],
+ portInfo->bbsid[3],
+ portInfo->bbsid[4],
+ portInfo->bbsid[5],
+ portInfo->frameControlDurationID >> 16,
+ portInfo->frameControlDurationID & 0xFFFF);
+ }
+ }
+ else
+ {
+ printf(" - WiFi header conversion not enabled\n");
+ }
+ }
+
+ /* Firewall */
+ if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
+ {
+ if ((portInfo->featureStatus & IX_ETH_DB_FIREWALL) != 0)
+ {
+ printf(" - Firewall is in %s-list mode\n", portInfo->firewallMode == IX_ETH_DB_FIREWALL_BLACK_LIST ? "black" : "white");
+ printf(" - Invalid source MAC address filtering is %s\n", portInfo->srcAddressFilterEnabled ? "enabled" : "disabled");
+ }
+ else
+ {
+ printf(" - Firewall not enabled\n");
+ }
+ }
+
+ /* browse database if asked to display records */
+ if (recordFilter != IX_ETH_DB_NO_RECORD_TYPE)
+ {
+ printf("\n");
+ ixEthDBHeaderShow(recordFilter);
+
+ BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
+
+ while (IS_ITERATOR_VALID(&iterator))
+ {
+ MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
+
+ if (descriptor->portID == portID && (descriptor->type & recordFilter) != 0)
+ {
+ recordCount++;
+
+ /* display entry */
+ ixEthDBRecordShow(descriptor, recordFilter);
+ }
+
+ /* move to the next record */
+ BUSY_RETRY_WITH_RESULT(ixEthDBIncrementHashIterator(&dbHashtable, &iterator), local_result);
+
+ /* debug */
+ if (local_result == IX_ETH_DB_BUSY)
+ {
+ printf("EthDB (API): Error, database browser failed (no access), giving up\n");
+ }
+ }
+
+ printf("\nFound %d records\n\n", recordCount);
+ }
+}
+
+/**
+ * @brief displays a record header
+ *
+ * @param recordFilter record type filter
+ *
+ * This function displays a record header, depending on
+ * the given record type filter. It is useful when used
+ * in conjunction with ixEthDBRecordShow which will display
+ * record fields formatted for the header, provided the same
+ * record filter is used.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or IX_ETH_DB_INVALID_ARG if the recordFilter
+ * parameter is invalid or not supported
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBHeaderShow(IxEthDBRecordType recordFilter)
+{
+ if (recordFilter == IX_ETH_DB_FILTERING_VLAN_RECORD
+ || recordFilter == (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD))
+ {
+ /* display VLAN record header */
+ printf(" MAC address | Age | Type | VLAN ID | CFI | QoS class \n");
+ printf("___________________________________________________________________\n");
+ }
+ else if (recordFilter == IX_ETH_DB_FILTERING_RECORD)
+ {
+ /* display filtering record header */
+ printf(" MAC address | Age | Type \n");
+ printf("_______________________________________\n");
+ }
+ else if (recordFilter == IX_ETH_DB_WIFI_RECORD)
+ {
+ /* display WiFi record header */
+ printf(" MAC address | GW MAC address \n");
+ printf("_______________________________________\n");
+ }
+ else if (recordFilter == IX_ETH_DB_FIREWALL_RECORD)
+ {
+ /* display Firewall record header */
+ printf(" MAC address \n");
+ printf("__________________\n");
+ }
+ else if (recordFilter == IX_ETH_DB_ALL_RECORD_TYPES)
+ {
+ /* display composite record header */
+ printf(" MAC address | Record | Age| Type | VLAN |CFI| QoS | GW MAC address \n");
+ printf("_______________________________________________________________________________\n");
+ }
+ else
+ {
+ return IX_ETH_DB_INVALID_ARG;
+ }
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief displays database information (records and port information)
+ *
+ * @param portID ID of the port to display (or IX_ETH_DB_ALL_PORTS for all the ports)
+ * @param recordFilter record filter (use IX_ETH_DB_NO_RECORD_TYPE to display only
+ * port information)
+ *
+ * Note that this function is documented in the main component header
+ * file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully or
+ * an appropriate error code otherwise
+ *
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter)
+{
+ IxEthDBPortId currentPort;
+ BOOL showAllPorts = (portID == IX_ETH_DB_ALL_PORTS);
+
+ IX_ETH_DB_CHECK_PORT_ALL(portID);
+
+ printf("\nEthernet learning/filtering database: listing %d port(s)\n\n", showAllPorts ? (UINT32) IX_ETH_DB_NUMBER_OF_PORTS : 1);
+
+ currentPort = showAllPorts ? 0 : portID;
+
+ while (currentPort != IX_ETH_DB_NUMBER_OF_PORTS)
+ {
+ /* display port info */
+ ixEthDBPortInfoShow(currentPort, recordFilter);
+
+ /* next port */
+ currentPort = showAllPorts ? currentPort + 1 : IX_ETH_DB_NUMBER_OF_PORTS;
+ }
+
+ return IX_ETH_DB_SUCCESS;
+}
+
diff --git a/cpu/ixp/npe/IxEthDBSearch.c b/cpu/ixp/npe/IxEthDBSearch.c
new file mode 100644
index 0000000..4a10878
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBSearch.c
@@ -0,0 +1,327 @@
+/**
+ * @file IxEthDBSearch.c
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB_p.h"
+
+extern HashTable dbHashtable;
+
+/**
+ * @brief matches two database records based on their MAC addresses
+ *
+ * @param untypedReference record to match against
+ * @param untypedEntry record to match
+ *
+ * @return TRUE if the match is successful or FALSE otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+BOOL ixEthDBAddressRecordMatch(void *untypedReference, void *untypedEntry)
+{
+ MacDescriptor *entry = (MacDescriptor *) untypedEntry;
+ MacDescriptor *reference = (MacDescriptor *) untypedReference;
+
+ /* check accepted record types */
+ if ((entry->type & reference->type) == 0) return FALSE;
+
+ return (ixEthDBAddressCompare((UINT8 *) entry->macAddress, (UINT8 *) reference->macAddress) == 0);
+}
+
+/**
+ * @brief matches two database records based on their MAC addresses
+ * and VLAN IDs
+ *
+ * @param untypedReference record to match against
+ * @param untypedEntry record to match
+ *
+ * @return TRUE if the match is successful or FALSE otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+BOOL ixEthDBVlanRecordMatch(void *untypedReference, void *untypedEntry)
+{
+ MacDescriptor *entry = (MacDescriptor *) untypedEntry;
+ MacDescriptor *reference = (MacDescriptor *) untypedReference;
+
+ /* check accepted record types */
+ if ((entry->type & reference->type) == 0) return FALSE;
+
+ return (IX_ETH_DB_GET_VLAN_ID(entry->recordData.filteringVlanData.ieee802_1qTag) ==
+ IX_ETH_DB_GET_VLAN_ID(reference->recordData.filteringVlanData.ieee802_1qTag)) &&
+ (ixEthDBAddressCompare(entry->macAddress, reference->macAddress) == 0);
+}
+
+/**
+ * @brief matches two database records based on their MAC addresses
+ * and port IDs
+ *
+ * @param untypedReference record to match against
+ * @param untypedEntry record to match
+ *
+ * @return TRUE if the match is successful or FALSE otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+BOOL ixEthDBPortRecordMatch(void *untypedReference, void *untypedEntry)
+{
+ MacDescriptor *entry = (MacDescriptor *) untypedEntry;
+ MacDescriptor *reference = (MacDescriptor *) untypedReference;
+
+ /* check accepted record types */
+ if ((entry->type & reference->type) == 0) return FALSE;
+
+ return (entry->portID == reference->portID) &&
+ (ixEthDBAddressCompare(entry->macAddress, reference->macAddress) == 0);
+}
+
+/**
+ * @brief dummy matching function, registered for safety
+ *
+ * @param reference record to match against (unused)
+ * @param entry record to match (unused)
+ *
+ * This function is registered in the matching functions
+ * array on invalid types. Calling it will display an
+ * error message, indicating an error in the component logic.
+ *
+ * @return FALSE
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+BOOL ixEthDBNullMatch(void *reference, void *entry)
+{
+ /* display an error message */
+
+ ixOsalLog(IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, "DB: (Search) The NullMatch function was called, wrong key type?\n", 0, 0, 0, 0, 0, 0);
+
+
+ return FALSE;
+}
+
+/**
+ * @brief registers hash matching methods
+ *
+ * @param matchFunctions table of match functions to be populated
+ *
+ * This function registers the available record matching functions
+ * by indexing them on record types into the given function array.
+ *
+ * Note that it is compulsory to call this in ixEthDBInit(),
+ * otherwise hashtable searching and removal will not work
+ *
+ * @return number of registered functions
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+UINT32 ixEthDBMatchMethodsRegister(MatchFunction *matchFunctions)
+{
+ UINT32 i;
+
+ /* safety first */
+ for ( i = 0 ; i < IX_ETH_DB_MAX_KEY_INDEX + 1 ; i++)
+ {
+ matchFunctions[i] = ixEthDBNullMatch;
+ }
+
+ /* register MAC search method */
+ matchFunctions[IX_ETH_DB_MAC_KEY] = ixEthDBAddressRecordMatch;
+
+ /* register MAC/PortID search method */
+ matchFunctions[IX_ETH_DB_MAC_PORT_KEY] = ixEthDBPortRecordMatch;
+
+ /* register MAC/VLAN ID search method */
+ matchFunctions[IX_ETH_DB_MAC_VLAN_KEY] = ixEthDBVlanRecordMatch;
+
+ return 3; /* three methods */
+}
+
+/**
+ * @brief search a record in the Ethernet datbase
+ *
+ * @param macAddress MAC address to perform the search on
+ * @param typeFilter type of records to consider for matching
+ *
+ * @warning if searching is successful an implicit write lock
+ * to the search result is granted, therefore unlock the
+ * entry using @ref ixEthDBReleaseHashNode() as soon as possible.
+ *
+ * @see ixEthDBReleaseHashNode()
+ *
+ * @return the search result, or NULL if a record with the given
+ * MAC address was not found
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+HashNode* ixEthDBSearch(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter)
+{
+ HashNode *searchResult = NULL;
+ MacDescriptor reference;
+
+ TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
+
+ if (macAddress == NULL)
+ {
+ return NULL;
+ }
+
+ /* fill search fields */
+ memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
+
+ /* set acceptable record types */
+ reference.type = typeFilter;
+
+ BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_KEY, &reference, &searchResult));
+
+ return searchResult;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPeek(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter)
+{
+ MacDescriptor reference;
+ IxEthDBStatus result;
+
+ TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
+
+ if (macAddress == NULL)
+ {
+ return IX_ETH_DB_INVALID_ARG;
+ }
+
+ /* fill search fields */
+ memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
+
+ /* set acceptable record types */
+ reference.type = typeFilter;
+
+ result = ixEthDBPeekHashEntry(&dbHashtable, IX_ETH_DB_MAC_KEY, &reference);
+
+ return result;
+}
+
+/**
+ * @brief search a record in the Ethernet datbase
+ *
+ * @param macAddress MAC address to perform the search on
+ * @param portID port ID to perform the search on
+ * @param typeFilter type of records to consider for matching
+ *
+ * @warning if searching is successful an implicit write lock
+ * to the search result is granted, therefore unlock the
+ * entry using @ref ixEthDBReleaseHashNode() as soon as possible.
+ *
+ * @see ixEthDBReleaseHashNode()
+ *
+ * @return the search result, or NULL if a record with the given
+ * MAC address/port ID combination was not found
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+HashNode* ixEthDBPortSearch(IxEthDBMacAddr *macAddress, IxEthDBPortId portID, IxEthDBRecordType typeFilter)
+{
+ HashNode *searchResult = NULL;
+ MacDescriptor reference;
+
+ if (macAddress == NULL)
+ {
+ return NULL;
+ }
+
+ /* fill search fields */
+ memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
+ reference.portID = portID;
+
+ /* set acceptable record types */
+ reference.type = typeFilter;
+
+ BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_PORT_KEY, &reference, &searchResult));
+
+ return searchResult;
+}
+
+/**
+ * @brief search a record in the Ethernet datbase
+ *
+ * @param macAddress MAC address to perform the search on
+ * @param vlanID VLAN ID to perform the search on
+ * @param typeFilter type of records to consider for matching
+ *
+ * @warning if searching is successful an implicit write lock
+ * to the search result is granted, therefore unlock the
+ * entry using @ref ixEthDBReleaseHashNode() as soon as possible.
+ *
+ * @see ixEthDBReleaseHashNode()
+ *
+ * @return the search result, or NULL if a record with the given
+ * MAC address/VLAN ID combination was not found
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+HashNode* ixEthDBVlanSearch(IxEthDBMacAddr *macAddress, IxEthDBVlanId vlanID, IxEthDBRecordType typeFilter)
+{
+ HashNode *searchResult = NULL;
+ MacDescriptor reference;
+
+ if (macAddress == NULL)
+ {
+ return NULL;
+ }
+
+ /* fill search fields */
+ memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
+ reference.recordData.filteringVlanData.ieee802_1qTag =
+ IX_ETH_DB_SET_VLAN_ID(reference.recordData.filteringVlanData.ieee802_1qTag, vlanID);
+
+ /* set acceptable record types */
+ reference.type = typeFilter;
+
+ BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_VLAN_KEY, &reference, &searchResult));
+
+ return searchResult;
+}
diff --git a/cpu/ixp/npe/IxEthDBSpanningTree.c b/cpu/ixp/npe/IxEthDBSpanningTree.c
new file mode 100644
index 0000000..6d9fd6e
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBSpanningTree.c
@@ -0,0 +1,107 @@
+/**
+ * @file IxEthDBSpanningTree.c
+ *
+ * @brief Implementation of the STP API
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#include "IxEthDB_p.h"
+
+/**
+ * @brief sets the STP blocking state of a port
+ *
+ * @param portID ID of the port
+ * @param blocked TRUE to block the port or FALSE to unblock it
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked)
+{
+ IxNpeMhMessage message;
+ IX_STATUS result;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_SPANNING_TREE_PROTOCOL);
+
+ ixEthDBPortInfo[portID].stpBlocked = blocked;
+
+ FILL_SETBLOCKINGSTATE_MSG(message, portID, blocked);
+
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+ return result;
+}
+
+/**
+ * @brief retrieves the STP blocking state of a port
+ *
+ * @param portID ID of the port
+ * @param blocked address to write the blocked status into
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_SPANNING_TREE_PROTOCOL);
+
+ IX_ETH_DB_CHECK_REFERENCE(blocked);
+
+ *blocked = ixEthDBPortInfo[portID].stpBlocked;
+
+ return IX_ETH_DB_SUCCESS;
+}
diff --git a/cpu/ixp/npe/IxEthDBUtil.c b/cpu/ixp/npe/IxEthDBUtil.c
new file mode 100644
index 0000000..e708bf1
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBUtil.c
@@ -0,0 +1,120 @@
+/**
+ * @file ethUtil.c
+ *
+ * @brief Utility functions
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#include "IxFeatureCtrl.h"
+#include "IxEthDB_p.h"
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBSingleEthNpeCheck(IxEthDBPortId portID)
+{
+ /* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */
+ if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+ (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+ || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+ {
+ if ((portID == 0) &&
+ (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED))
+ {
+ return IX_ETH_DB_FAIL;
+ }
+
+ if ((portID == 1) &&
+ (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED))
+ {
+ return IX_ETH_DB_FAIL;
+ }
+
+ if ((portID == 2) &&
+ (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) ==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED))
+ {
+ return IX_ETH_DB_FAIL;
+ }
+ }
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+IX_ETH_DB_PUBLIC
+BOOL ixEthDBCheckSingleBitValue(UINT32 value)
+{
+#if (CPU != SIMSPARCSOLARIS) && !defined (__wince)
+ UINT32 shift;
+
+ /* use the count-leading-zeros XScale instruction */
+ __asm__ ("clz %0, %1\n" : "=r" (shift) : "r" (value));
+
+ return ((value << shift) == 0x80000000UL);
+
+#else
+
+ while (value != 0)
+ {
+ if (value == 1) return TRUE;
+ else if ((value & 1) == 1) return FALSE;
+
+ value >>= 1;
+ }
+
+ return FALSE;
+
+#endif
+}
+
+const char *mac2string(const unsigned char *mac)
+{
+ static char str[19];
+
+ if (mac == NULL)
+ {
+ return NULL;
+ }
+
+ sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+ return str;
+}
diff --git a/cpu/ixp/npe/IxEthDBVlan.c b/cpu/ixp/npe/IxEthDBVlan.c
new file mode 100644
index 0000000..e2efb9b
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBVlan.c
@@ -0,0 +1,1179 @@
+/**
+ * @file IxEthDBVlan.c
+ *
+ * @brief Implementation of the VLAN API
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB.h"
+#include "IxEthDB_p.h"
+
+/* forward prototypes */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBUpdateTrafficClass(IxEthDBPortId portID, UINT32 classIndex);
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBVlanTableGet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet);
+
+/* contants used by various functions as "action" parameter */
+#define ADD_VLAN (0x1)
+#define REMOVE_VLAN (0x2)
+
+/**
+ * @brief adds or removes a VLAN from a VLAN set
+ *
+ * @param vlanID VLAN ID to add or remove
+ * @param table VLAN set to add into or remove from
+ * @param action ADD_VLAN or REMOVE_VLAN
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBLocalVlanMembershipChange(UINT32 vlanID, IxEthDBVlanSet table, UINT32 action)
+{
+ UINT32 setOffset;
+
+ /* add/remove VID to membership table */
+ setOffset = VLAN_SET_OFFSET(vlanID); /* we need 9 bits to index the 512 byte membership array */
+
+ if (action == ADD_VLAN)
+ {
+ table[setOffset] |= 1 << VLAN_SET_MASK(vlanID);
+ }
+ else if (action == REMOVE_VLAN)
+ {
+ table[setOffset] &= ~(1 << VLAN_SET_MASK(vlanID));
+ }
+}
+
+/**
+ * @brief updates a set of 8 VLANs in an NPE
+ *
+ * @param portID ID of the port
+ * @param setOffset offset of the 8 VLANs
+ *
+ * This function updates the VLAN membership table
+ * and Transmit Tagging Info table for 8 consecutive
+ * VLAN IDs indexed by setOffset.
+ *
+ * For example, a setOffset of 0 indexes VLAN IDs 0
+ * through 7, 1 indexes VLAN IDs 8 through 9 etc.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBVlanTableEntryUpdate(IxEthDBPortId portID, UINT32 setOffset)
+{
+ PortInfo *portInfo = &ixEthDBPortInfo[portID];
+ IxNpeMhMessage message;
+ IX_STATUS result;
+
+ FILL_SETPORTVLANTABLEENTRY_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID),
+ 2 * setOffset,
+ portInfo->vlanMembership[setOffset],
+ portInfo->transmitTaggingInfo[setOffset]);
+
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+ return result;
+}
+
+/**
+ * @brief updates a VLAN range in an NPE
+ *
+ * @param portID ID of the port
+ *
+ * This function is similar to @ref ixEthDBVlanTableEntryUpdate
+ * except that it can update more than one VLAN set (up to
+ * the entire VLAN membership and TTI tables if the offset is 0
+ * and length is sizeof (IxEthDBVlanSet) (512 bytes).
+ *
+ * Updating the NPE via this method is slower as it requires
+ * a memory copy from SDRAM, hence it is recommended that the
+ * ixEthDBVlanTableEntryUpdate function is used where possible.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBVlanTableRangeUpdate(IxEthDBPortId portID)
+{
+ PortInfo *portInfo = &ixEthDBPortInfo[portID];
+ UINT8 *vlanUpdateZone = (UINT8 *) portInfo->updateMethod.vlanUpdateZone;
+ IxNpeMhMessage message;
+ UINT32 setIndex;
+ IX_STATUS result;
+
+ /* copy membership info and transmit tagging into into exchange area */
+ for (setIndex = 0 ; setIndex < sizeof (portInfo->vlanMembership) ; setIndex++)
+ {
+ /* membership and TTI data are interleaved */
+ vlanUpdateZone[setIndex * 2] = portInfo->vlanMembership[setIndex];
+ vlanUpdateZone[setIndex * 2 + 1] = portInfo->transmitTaggingInfo[setIndex];
+ }
+
+ IX_OSAL_CACHE_FLUSH(vlanUpdateZone, FULL_VLAN_BYTE_SIZE);
+
+ /* build NPE message */
+ FILL_SETPORTVLANTABLERANGE_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), 0, 0,
+ IX_OSAL_MMU_VIRT_TO_PHYS(vlanUpdateZone));
+
+ /* send message */
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+ return result;
+}
+
+/**
+ * @brief adds or removes a VLAN from a port's VLAN membership table
+ * or Transmit Tagging Information table
+ *
+ * @param portID ID of the port
+ * @param vlanID VLAN ID to add or remove
+ * @param table to add or remove from
+ * @param action ADD_VLAN or REMOVE_VLAN
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBPortVlanMembershipChange(IxEthDBPortId portID, IxEthDBVlanId vlanID, IxEthDBVlanSet table, UINT32 action)
+{
+ /* change VLAN in local membership table */
+ ixEthDBLocalVlanMembershipChange(vlanID, table, action);
+
+ /* send updated entry to NPE */
+ return ixEthDBVlanTableEntryUpdate(portID, VLAN_SET_OFFSET(vlanID));
+}
+
+/**
+ * @brief sets the default port VLAN tag (the lower 3 bytes are the PVID)
+ *
+ * @param portID ID of the port
+ * @param vlanTag port VLAN tag (802.1Q tag)
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag)
+{
+ IxNpeMhMessage message;
+ IX_STATUS result;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_VLAN_TAG(vlanTag);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ /* add VLAN ID to local membership table */
+ ixEthDBPortVlanMembershipChange(portID,
+ vlanTag & IX_ETH_DB_802_1Q_VLAN_MASK,
+ ixEthDBPortInfo[portID].vlanMembership,
+ ADD_VLAN);
+
+ /* set tag in portInfo */
+ ixEthDBPortInfo[portID].vlanTag = vlanTag;
+
+ /* build VLAN_SetDefaultRxVID message */
+ FILL_SETDEFAULTRXVID_MSG(message,
+ IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID),
+ IX_IEEE802_1Q_VLAN_TPID,
+ vlanTag);
+
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+ return result;
+}
+
+/**
+ * @brief retrieves the default port VLAN tag (the lower 3 bytes are the PVID)
+ *
+ * @param portID ID of the port
+ * @param vlanTag address to write the port VLAN tag (802.1Q tag) into
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ IX_ETH_DB_CHECK_REFERENCE(vlanTag);
+
+ *vlanTag = ixEthDBPortInfo[portID].vlanTag;
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief sets the VLAN tag (the lower 3 bytes are the PVID) of a
+ * database filtering record
+ *
+ * @param portID ID of the port
+ * @param vlanTag VLAN tag (802.1Q tag)
+ *
+ * Important: filtering records are automatically converted to
+ * IX_ETH_DB_FILTERING_VLAN record when added a VLAN tag.
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag)
+{
+ HashNode *searchResult;
+ MacDescriptor *descriptor;
+
+ IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+ IX_ETH_DB_CHECK_VLAN_TAG(vlanTag);
+
+ searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
+
+ if (searchResult == NULL)
+ {
+ return IX_ETH_DB_NO_SUCH_ADDR;
+ }
+
+ descriptor = (MacDescriptor *) searchResult->data;
+
+ /* set record type to VLAN if not already set */
+ descriptor->type = IX_ETH_DB_FILTERING_VLAN_RECORD;
+
+ /* add vlan tag */
+ descriptor->recordData.filteringVlanData.ieee802_1qTag = vlanTag;
+
+ /* transaction completed */
+ ixEthDBReleaseHashNode(searchResult);
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief retrieves the VLAN tag (the lower 3 bytes are the PVID) from a
+ * database VLAN filtering record
+ *
+ * @param portID ID of the port
+ * @param vlanTag address to write the VLAN tag (802.1Q tag) into
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag)
+{
+ HashNode *searchResult;
+ MacDescriptor *descriptor;
+
+ IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+ IX_ETH_DB_CHECK_REFERENCE(vlanTag);
+
+ searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_FILTERING_VLAN_RECORD);
+
+ if (searchResult == NULL)
+ {
+ return IX_ETH_DB_NO_SUCH_ADDR;
+ }
+
+ descriptor = (MacDescriptor *) searchResult->data;
+
+ /* get vlan tag */
+ *vlanTag = descriptor->recordData.filteringVlanData.ieee802_1qTag;
+
+ /* transaction completed */
+ ixEthDBReleaseHashNode(searchResult);
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief adds a VLAN to a port's VLAN membership table
+ *
+ * @param portID ID of the port
+ * @param vlanID VLAN ID to add
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_VLAN_ID(vlanID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].vlanMembership, ADD_VLAN);
+}
+
+/**
+ * @brief removes a VLAN from a port's VLAN membership table
+ *
+ * @param portID ID of the port
+ * @param vlanID VLAN ID to remove
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ IX_ETH_DB_CHECK_VLAN_ID(vlanID);
+
+ /* for safety isolate only the VLAN ID in the tag (the lower 12 bits) */
+ vlanID = vlanID & IX_ETH_DB_802_1Q_VLAN_MASK;
+
+ /* check we're not asked to remove the default port VID */
+ if (vlanID == IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag))
+ {
+ return IX_ETH_DB_NO_PERMISSION;
+ }
+
+ return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].vlanMembership, REMOVE_VLAN);
+}
+
+/**
+ * @brief adds or removes a VLAN range from a port's
+ * VLAN membership table or TTI table
+ *
+ * @param portID ID of the port
+ * @param vlanIDMin start of the VLAN range
+ * @param vlanIDMax end of the VLAN range
+ * @param table VLAN set to add or remove from
+ * @param action ADD_VLAN or REMOVE_VLAN
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBPortVlanMembershipRangeChange(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, IxEthDBVlanSet table, UINT32 action)
+{
+ UINT32 setOffsetMin, setOffsetMax;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ IX_ETH_DB_CHECK_VLAN_ID(vlanIDMin);
+
+ IX_ETH_DB_CHECK_VLAN_ID(vlanIDMax);
+
+ /* for safety isolate only the VLAN ID in the tags (the lower 12 bits) */
+ vlanIDMin = vlanIDMin & IX_ETH_DB_802_1Q_VLAN_MASK;
+ vlanIDMax = vlanIDMax & IX_ETH_DB_802_1Q_VLAN_MASK;
+
+ /* is this a range? */
+ if (vlanIDMax < vlanIDMin)
+ {
+ return IX_ETH_DB_INVALID_VLAN;
+ }
+
+ /* check that we're not specifically asked to remove the default port VID */
+ if (action == REMOVE_VLAN && vlanIDMax == vlanIDMin && IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag) == vlanIDMin)
+ {
+ return IX_ETH_DB_NO_PERMISSION;
+ }
+
+ /* compute set offsets */
+ setOffsetMin = VLAN_SET_OFFSET(vlanIDMin);
+ setOffsetMax = VLAN_SET_OFFSET(vlanIDMax);
+
+ /* change VLAN range */
+ for (; vlanIDMin <= vlanIDMax ; vlanIDMin++)
+ {
+ /* change vlan in local membership table */
+ ixEthDBLocalVlanMembershipChange(vlanIDMin, table, action);
+ }
+
+ /* if the range is within one set (max 8 VLANs in one table byte) we can just update that entry in the NPE */
+ if (setOffsetMin == setOffsetMax)
+ {
+ /* send updated entry to NPE */
+ return ixEthDBVlanTableEntryUpdate(portID, setOffsetMin);
+ }
+ else
+ {
+ /* update a zone of the membership/transmit tag info table */
+ return ixEthDBVlanTableRangeUpdate(portID);
+ }
+}
+
+/**
+ * @brief adds a VLAN range to a port's VLAN membership table
+ *
+ * @param portID ID of the port
+ * @param vlanIDMin start of the VLAN range
+ * @param vlanIDMax end of the VLAN range
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].vlanMembership, ADD_VLAN);
+}
+
+/**
+ * @brief removes a VLAN range from a port's VLAN membership table
+ *
+ * @param portID ID of the port
+ * @param vlanIDMin start of the VLAN range
+ * @param vlanIDMax end of the VLAN range
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].vlanMembership, REMOVE_VLAN);
+}
+
+/**
+ * @brief sets a port's VLAN membership table or TTI table and
+ * updates the NPE VLAN configuration
+ *
+ * @param portID ID of the port
+ * @param portVlanTable port VLAN table to set
+ * @param vlanSet new set contents
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanTableSet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ IX_ETH_DB_CHECK_REFERENCE(vlanSet);
+
+ memcpy(portVlanTable, vlanSet, sizeof (IxEthDBVlanSet));
+
+ return ixEthDBVlanTableRangeUpdate(portID);
+}
+
+/**
+ * @brief retireves a port's VLAN membership table or TTI table
+ *
+ * @param portID ID of the port
+ * @param portVlanTable port VLAN table to retrieve
+ * @param vlanSet address to
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBVlanTableGet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ IX_ETH_DB_CHECK_REFERENCE(vlanSet);
+
+ memcpy(vlanSet, portVlanTable, sizeof (IxEthDBVlanSet));
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief sets a port's VLAN membership table
+ *
+ * @param portID ID of the port
+ * @param vlanSet new VLAN membership table
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
+{
+ IxEthDBVlanId vlanID;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(vlanSet);
+
+ /* set the bit corresponding to the PVID just in case */
+ vlanID = IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag);
+ vlanSet[VLAN_SET_OFFSET(vlanID)] |= 1 << VLAN_SET_MASK(vlanID);
+
+ return ixEthDBPortVlanTableSet(portID, ixEthDBPortInfo[portID].vlanMembership, vlanSet);
+}
+
+/**
+ * @brief retrieves a port's VLAN membership table
+ *
+ * @param portID ID of the port
+ * @param vlanSet location to store the port's VLAN membership table
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ return ixEthDBVlanTableGet(portID, ixEthDBPortInfo[portID].vlanMembership, vlanSet);
+}
+
+/**
+ * @brief enables or disables Egress tagging for one VLAN ID
+ *
+ * @param portID ID of the port
+ * @param vlanID VLAN ID to enable or disable Egress tagging on
+ * @param enabled TRUE to enable and FALSE to disable tagging
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_VLAN_ID(vlanID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].transmitTaggingInfo, enabled? ADD_VLAN : REMOVE_VLAN);
+}
+
+/**
+ * @brief retrieves the Egress tagging status for one VLAN ID
+ *
+ * @param portID ID of the port
+ * @param vlanID VLAN ID to retrieve the tagging status for
+ * @param enabled location to store the tagging status
+ * (TRUE - tagging enabled, FALSE - tagging disabled)
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ IX_ETH_DB_CHECK_REFERENCE(enabled);
+
+ IX_ETH_DB_CHECK_VLAN_ID(vlanID);
+
+ *enabled = ((ixEthDBPortInfo[portID].transmitTaggingInfo[VLAN_SET_OFFSET(vlanID)] & (1 << VLAN_SET_MASK(vlanID))) != 0);
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief enables or disables Egress VLAN tagging for a VLAN range
+ *
+ * @param portID ID of the port
+ * @param vlanIDMin start of VLAN range
+ * @param vlanIDMax end of VLAN range
+ * @param enabled TRUE to enable or FALSE to disable VLAN tagging
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].transmitTaggingInfo, enabled? ADD_VLAN : REMOVE_VLAN);
+}
+
+/**
+ * @brief sets the Egress VLAN tagging table (the Transmit Tagging
+ * Information table)
+ *
+ * @param portID ID of the port
+ * @param vlanSet new TTI table
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
+{
+ IxEthDBVlanId vlanID;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(vlanSet);
+
+ /* set the PVID bit just in case */
+ vlanID = IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag);
+ vlanSet[VLAN_SET_OFFSET(vlanID)] |= 1 << VLAN_SET_MASK(vlanID);
+
+ return ixEthDBPortVlanTableSet(portID, ixEthDBPortInfo[portID].transmitTaggingInfo, vlanSet);
+}
+
+/**
+ * @brief retrieves the Egress VLAN tagging table (the Transmit
+ * Tagging Information table)
+ *
+ * @param portID ID of the port
+ * @param vlanSet location to store the port's TTI table
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ return ixEthDBVlanTableGet(portID, ixEthDBPortInfo[portID].transmitTaggingInfo, vlanSet);
+}
+
+/**
+ * @brief sends the NPE the updated frame filter and default
+ * Ingress tagging
+ *
+ * @param portID ID of the port
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBIngressVlanModeUpdate(IxEthDBPortId portID)
+{
+ PortInfo *portInfo = &ixEthDBPortInfo[portID];
+ IxNpeMhMessage message;
+ IX_STATUS result;
+
+ FILL_SETRXTAGMODE_MSG(message, portID, portInfo->npeFrameFilter, portInfo->npeTaggingAction);
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+ return result;
+}
+
+/**
+ * @brief sets the default Ingress tagging behavior
+ *
+ * @param portID ID of the port
+ * @param taggingAction default tagging behavior
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction)
+{
+ PortInfo *portInfo;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ portInfo = &ixEthDBPortInfo[portID];
+
+ if (taggingAction == IX_ETH_DB_PASS_THROUGH)
+ {
+ portInfo->npeTaggingAction = 0x00;
+ }
+ else if (taggingAction == IX_ETH_DB_ADD_TAG)
+ {
+ portInfo->npeTaggingAction = 0x02;
+ }
+ else if (taggingAction == IX_ETH_DB_REMOVE_TAG)
+ {
+ portInfo->npeTaggingAction = 0x01;
+ }
+ else
+ {
+ return IX_ETH_DB_INVALID_ARG;
+ }
+
+ portInfo->taggingAction = taggingAction;
+
+ return ixEthDBIngressVlanModeUpdate(portID);
+}
+
+/**
+ * @brief retrieves the default Ingress tagging behavior of a port
+ *
+ * @param portID ID of the port
+ * @param taggingAction location to save the default tagging behavior
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ IX_ETH_DB_CHECK_REFERENCE(taggingAction);
+
+ *taggingAction = ixEthDBPortInfo[portID].taggingAction;
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief sets the Ingress acceptable frame type filter
+ *
+ * @param portID ID of the port
+ * @param frameFilter acceptable frame type filter
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter)
+{
+ PortInfo *portInfo;
+ IxEthDBStatus result = IX_ETH_DB_SUCCESS;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ /* check parameter range
+ the ORed value of the valid values is 0x7
+ a value having extra bits is invalid */
+ if ((frameFilter | 0x7) != 0x7 || frameFilter == 0)
+ {
+ return IX_ETH_DB_INVALID_ARG;
+ }
+
+ portInfo = &ixEthDBPortInfo[portID];
+
+ portInfo->frameFilter = frameFilter;
+ portInfo->npeFrameFilter = 0; /* allow all by default */
+
+ /* if accepting priority tagged but not all VLAN tagged
+ set the membership table to contain only VLAN ID 0
+ hence remove vlans 1-4094 and add VLAN ID 0 */
+ if (((frameFilter & IX_ETH_DB_PRIORITY_TAGGED_FRAMES) != 0)
+ && ((frameFilter & IX_ETH_DB_VLAN_TAGGED_FRAMES) == 0))
+ {
+ result = ixEthDBPortVlanMembershipRangeChange(portID,
+ 1, IX_ETH_DB_802_1Q_MAX_VLAN_ID, portInfo->vlanMembership, REMOVE_VLAN);
+
+ if (result == IX_ETH_DB_SUCCESS)
+ {
+ ixEthDBLocalVlanMembershipChange(0, portInfo->vlanMembership, ADD_VLAN);
+ result = ixEthDBVlanTableRangeUpdate(portID);
+ }
+ }
+
+ /* untagged only? */
+ if (frameFilter == IX_ETH_DB_UNTAGGED_FRAMES)
+ {
+ portInfo->npeFrameFilter = 0x01;
+ }
+
+ /* tagged only? */
+ if ((frameFilter & IX_ETH_DB_UNTAGGED_FRAMES) == 0)
+ {
+ portInfo->npeFrameFilter = 0x02;
+ }
+
+ if (result == IX_ETH_DB_SUCCESS)
+ {
+ result = ixEthDBIngressVlanModeUpdate(portID);
+ }
+
+ return result;
+}
+
+/**
+ * @brief retrieves the acceptable frame type filter for a port
+ *
+ * @param portID ID of the port
+ * @param frameFilter location to store the frame filter
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ IX_ETH_DB_CHECK_REFERENCE(frameFilter);
+
+ *frameFilter = ixEthDBPortInfo[portID].frameFilter;
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief sends an NPE the updated configuration related
+ * to one QoS priority (associated traffic class and AQM mapping)
+ *
+ * @param portID ID of the port
+ * @param classIndex QoS priority (traffic class index)
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBUpdateTrafficClass(IxEthDBPortId portID, UINT32 classIndex)
+{
+ IxNpeMhMessage message;
+ IX_STATUS result;
+
+ UINT32 trafficClass = ixEthDBPortInfo[portID].priorityTable[classIndex];
+ UINT32 aqmQueue = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[trafficClass];
+
+ FILL_SETRXQOSENTRY(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), classIndex, trafficClass, aqmQueue);
+
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+ return result;
+}
+
+/**
+ * @brief sets the priority mapping table
+ *
+ * @param portID ID of the port
+ * @param priorityTable new priority mapping table
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable)
+{
+ UINT32 classIndex;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ IX_ETH_DB_CHECK_REFERENCE(priorityTable);
+
+ for (classIndex = 0 ; classIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; classIndex++)
+ {
+ /* check range */
+ if (priorityTable[classIndex] >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount)
+ {
+ return IX_ETH_DB_INVALID_PRIORITY;
+ }
+ }
+
+ /* set new traffic classes */
+ for (classIndex = 0 ; classIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; classIndex++)
+ {
+ ixEthDBPortInfo[portID].priorityTable[classIndex] = priorityTable[classIndex];
+
+ if (ixEthDBUpdateTrafficClass(portID, classIndex) != IX_ETH_DB_SUCCESS)
+ {
+ return IX_ETH_DB_FAIL;
+ }
+ }
+
+ return IX_ETH_DB_SUCCESS;
+ }
+
+/**
+ * @brief retrieves a port's priority mapping table
+ *
+ * @param portID ID of the port
+ * @param priorityTable location to store the priority table
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ IX_ETH_DB_CHECK_REFERENCE(priorityTable);
+
+ memcpy(priorityTable, ixEthDBPortInfo[portID].priorityTable, sizeof (IxEthDBPriorityTable));
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief sets one QoS priority => traffic class mapping
+ *
+ * @param portID ID of the port
+ * @param userPriority QoS (user) priority
+ * @param trafficClass associated traffic class
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ /* check ranges for userPriority and trafficClass */
+ if (userPriority >= IX_IEEE802_1Q_QOS_PRIORITY_COUNT || trafficClass >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount)
+ {
+ return IX_ETH_DB_INVALID_PRIORITY;
+ }
+
+ ixEthDBPortInfo[portID].priorityTable[userPriority] = trafficClass;
+
+ return ixEthDBUpdateTrafficClass(portID, userPriority);
+}
+
+/**
+ * @brief retrieves one QoS priority => traffic class mapping
+ *
+ * @param portID ID of the port
+ * @param userPriority QoS (user) priority
+ * @param trafficClass location to store the associated traffic class
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ IX_ETH_DB_CHECK_REFERENCE(trafficClass);
+
+ /* check userPriority range */
+ if (userPriority >= IX_IEEE802_1Q_QOS_PRIORITY_COUNT)
+ {
+ return IX_ETH_DB_INVALID_PRIORITY;
+ }
+
+ *trafficClass = ixEthDBPortInfo[portID].priorityTable[userPriority];
+
+ return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief enables or disables the source port extraction
+ * from the VLAN TPID field
+ *
+ * @param portID ID of the port
+ * @param enable TRUE to enable or FALSE to disable
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable)
+{
+ IxNpeMhMessage message;
+ IX_STATUS result;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+ FILL_SETPORTIDEXTRACTIONMODE(message, portID, enable);
+
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+ return result;
+}
diff --git a/cpu/ixp/npe/IxEthDBWiFi.c b/cpu/ixp/npe/IxEthDBWiFi.c
new file mode 100644
index 0000000..0a6043f
--- /dev/null
+++ b/cpu/ixp/npe/IxEthDBWiFi.c
@@ -0,0 +1,480 @@
+/**
+ * @file IxEthDBAPI.c
+ *
+ * @brief Implementation of the public API
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB_p.h"
+
+/* forward prototypes */
+IX_ETH_DB_PUBLIC
+MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations);
+
+/**
+ * @brief sets the BBSID value for the WiFi header conversion feature
+ *
+ * @param portID ID of the port
+ * @param bbsid pointer to the 6-byte BBSID value
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid)
+{
+ IxNpeMhMessage message;
+ IX_STATUS result;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
+
+ IX_ETH_DB_CHECK_REFERENCE(bbsid);
+
+ memcpy(ixEthDBPortInfo[portID].bbsid, bbsid, sizeof (IxEthDBMacAddr));
+
+ FILL_SETBBSID_MSG(message, portID, bbsid);
+
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+ return result;
+}
+
+/**
+ * @brief updates the Frame Control and Duration/ID WiFi header
+ * conversion parameters in an NPE
+ *
+ * @param portID ID of the port
+ *
+ * This function will send a message to the NPE updating the
+ * frame conversion parameters for 802.3 => 802.11 header conversion.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or IX_ETH_DB_FAIL otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBWiFiFrameControlDurationIDUpdate(IxEthDBPortId portID)
+{
+ IxNpeMhMessage message;
+ IX_STATUS result;
+
+ FILL_SETFRAMECONTROLDURATIONID(message, portID, ixEthDBPortInfo[portID].frameControlDurationID);
+
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+ return result;
+}
+
+/**
+ * @brief sets the Duration/ID WiFi frame header conversion parameter
+ *
+ * @param portID ID of the port
+ * @param durationID 16-bit value containing the new Duration/ID parameter
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
+
+ ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF0000) | durationID;
+
+ return ixEthDBWiFiFrameControlDurationIDUpdate(portID);
+}
+
+/**
+ * @brief sets the Frame Control WiFi frame header conversion parameter
+ *
+ * @param portID ID of the port
+ * @param durationID 16-bit value containing the new Frame Control parameter
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl)
+{
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
+
+ ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF) | (frameControl << 16);
+
+ return ixEthDBWiFiFrameControlDurationIDUpdate(portID);
+}
+
+/**
+ * @brief removes a WiFi header conversion record
+ *
+ * @param portID ID of the port
+ * @param macAddr MAC address of the record to remove
+ *
+ * Note that this function is documented in the main
+ * component header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+{
+ MacDescriptor recordTemplate;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
+
+ memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
+
+ recordTemplate.type = IX_ETH_DB_WIFI_RECORD;
+ recordTemplate.portID = portID;
+
+ return ixEthDBRemove(&recordTemplate, NULL);
+}
+
+/**
+ * @brief adds a WiFi header conversion record
+ *
+ * @param portID ID of the port
+ * @param macAddr MAC address of the record to add
+ * @param gatewayMacAddr address of the gateway (or
+ * NULL if this is a station record)
+ *
+ * This function adds a record of type AP_TO_AP (gateway is not NULL)
+ * or AP_TO_STA (gateway is NULL) in the main database as a
+ * WiFi header conversion record.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBWiFiEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr)
+{
+ MacDescriptor recordTemplate;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
+
+ memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
+
+ recordTemplate.type = IX_ETH_DB_WIFI_RECORD;
+ recordTemplate.portID = portID;
+
+ if (gatewayMacAddr != NULL)
+ {
+ memcpy(recordTemplate.recordData.wifiData.gwMacAddress, gatewayMacAddr, sizeof (IxEthDBMacAddr));
+
+ recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_AP;
+ }
+ else
+ {
+ memset(recordTemplate.recordData.wifiData.gwMacAddress, 0, sizeof (IxEthDBMacAddr));
+
+ recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_STA;
+ }
+
+ return ixEthDBAdd(&recordTemplate, NULL);
+}
+
+/**
+ * @brief adds a WiFi header conversion record
+ *
+ * @param portID ID of the port
+ * @param macAddr MAC address of the record to add
+ * @param gatewayMacAddr address of the gateway
+ *
+ * This function adds a record of type AP_TO_AP
+ * in the main database as a WiFi header conversion record.
+ *
+ * This is simply a wrapper over @ref ixEthDBWiFiEntryAdd().
+ *
+ * Note that this function is documented in the main
+ * component header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr)
+{
+ IX_ETH_DB_CHECK_REFERENCE(gatewayMacAddr);
+
+ return ixEthDBWiFiEntryAdd(portID, macAddr, gatewayMacAddr);
+}
+
+/**
+ * @brief adds a WiFi header conversion record
+ *
+ * @param portID ID of the port
+ * @param macAddr MAC address of the record to add
+ *
+ * This function adds a record of type AP_TO_STA
+ * in the main database as a WiFi header conversion record.
+ *
+ * This is simply a wrapper over @ref ixEthDBWiFiEntryAdd().
+ *
+ * Note that this function is documented in the main
+ * component header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+{
+ return ixEthDBWiFiEntryAdd(portID, macAddr, NULL);
+}
+
+/**
+ * @brief selects a set of gateways from a tree of
+ * WiFi header conversion records
+ *
+ * @param stations binary tree containing pointers to WiFi header
+ * conversion records
+ *
+ * This function browses through the input binary tree, identifies
+ * records of type AP_TO_AP, clones these records and appends them
+ * to a vine (a single right-branch binary tree) which is returned
+ * as result. A maximum of MAX_GW_SIZE entries containing gateways
+ * will be cloned from the original tree.
+ *
+ * @return vine (linear binary tree) containing record
+ * clones of AP_TO_AP type, which have a gateway field
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations)
+{
+ MacTreeNodeStack *stack;
+ MacTreeNode *gateways, *insertionPlace;
+ UINT32 gwIndex = 1; /* skip the empty root */
+
+ if (stations == NULL)
+ {
+ return NULL;
+ }
+
+ stack = ixOsalCacheDmaMalloc(sizeof (MacTreeNodeStack));
+
+ if (stack == NULL)
+ {
+ ERROR_LOG("DB: (WiFi) failed to allocate the node stack for gateway tree linearization, out of memory?\n");
+ return NULL;
+ }
+
+ /* initialize root node */
+ gateways = insertionPlace = NULL;
+
+ /* start browsing the station tree */
+ NODE_STACK_INIT(stack);
+
+ /* initialize stack by pushing the tree root at offset 0 */
+ NODE_STACK_PUSH(stack, stations, 0);
+
+ while (NODE_STACK_NONEMPTY(stack))
+ {
+ MacTreeNode *node;
+ UINT32 offset;
+
+ NODE_STACK_POP(stack, node, offset);
+
+ /* we can store maximum 31 (32 total, 1 empty root) entries in the gateway tree */
+ if (offset > (MAX_GW_SIZE - 1)) break;
+
+ /* check if this record has a gateway address */
+ if (node->descriptor != NULL && node->descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP)
+ {
+ /* found a record, create an insertion place */
+ if (insertionPlace != NULL)
+ {
+ insertionPlace->right = ixEthDBAllocMacTreeNode();
+ insertionPlace = insertionPlace->right;
+ }
+ else
+ {
+ gateways = ixEthDBAllocMacTreeNode();
+ insertionPlace = gateways;
+ }
+
+ if (insertionPlace == NULL)
+ {
+ /* no nodes left, bail out with what we have */
+ ixOsalCacheDmaFree(stack);
+ return gateways;
+ }
+
+ /* clone the original record for the gateway tree */
+ insertionPlace->descriptor = ixEthDBCloneMacDescriptor(node->descriptor);
+
+ /* insert and update the offset in the original record */
+ node->descriptor->recordData.wifiData.gwAddressIndex = gwIndex++;
+ }
+
+ /* browse the tree */
+ if (node->left != NULL)
+ {
+ NODE_STACK_PUSH(stack, node->left, LEFT_CHILD_OFFSET(offset));
+ }
+
+ if (node->right != NULL)
+ {
+ NODE_STACK_PUSH(stack, node->right, RIGHT_CHILD_OFFSET(offset));
+ }
+ }
+
+ ixOsalCacheDmaFree(stack);
+ return gateways;
+}
+
+/**
+ * @brief downloads the WiFi header conversion table to an NPE
+ *
+ * @param portID ID of the port
+ *
+ * This function prepares the WiFi header conversion tables and
+ * downloads them to the specified NPE port.
+ *
+ * The header conversion tables consist in the main table of
+ * addresses and the secondary table of gateways. AP_TO_AP records
+ * from the first table contain index fields into the second table
+ * for gateway selection.
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID)
+{
+ IxEthDBPortMap query;
+ MacTreeNode *stations = NULL, *gateways = NULL, *gateway = NULL;
+ IxNpeMhMessage message;
+ PortInfo *portInfo;
+ IX_STATUS result;
+
+ IX_ETH_DB_CHECK_PORT(portID);
+
+ IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+ IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
+
+ portInfo = &ixEthDBPortInfo[portID];
+
+ SET_DEPENDENCY_MAP(query, portID);
+
+ ixEthDBUpdateLock();
+
+ stations = ixEthDBQuery(NULL, query, IX_ETH_DB_WIFI_RECORD, MAX_ELT_SIZE);
+ gateways = ixEthDBGatewaySelect(stations);
+
+ /* clean up gw area */
+ memset((void *) portInfo->updateMethod.npeGwUpdateZone, FULL_GW_BYTE_SIZE, 0);
+
+ /* write all gateways */
+ gateway = gateways;
+
+ while (gateway != NULL)
+ {
+ ixEthDBNPEGatewayNodeWrite((void *) (((UINT32) portInfo->updateMethod.npeGwUpdateZone)
+ + gateway->descriptor->recordData.wifiData.gwAddressIndex * ELT_ENTRY_SIZE),
+ gateway);
+
+ gateway = gateway->right;
+ }
+
+ /* free the gateway tree */
+ if (gateways != NULL)
+ {
+ ixEthDBFreeMacTreeNode(gateways);
+ }
+
+ FILL_SETAPMACTABLE_MSG(message,
+ IX_OSAL_MMU_VIRT_TO_PHYS(portInfo->updateMethod.npeGwUpdateZone));
+
+ IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+ if (result == IX_SUCCESS)
+ {
+ /* update the main tree (the stations tree) */
+ portInfo->updateMethod.searchTree = stations;
+
+ result = ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_WIFI_RECORD);
+ }
+
+ ixEthDBUpdateUnlock();
+
+ return result;
+}
diff --git a/cpu/ixp/npe/IxEthMii.c b/cpu/ixp/npe/IxEthMii.c
new file mode 100644
index 0000000..4d92f17
--- /dev/null
+++ b/cpu/ixp/npe/IxEthMii.c
@@ -0,0 +1,497 @@
+/**
+ * @file IxEthMii.c
+ *
+ * @author Intel Corporation
+ * @date
+ *
+ * @brief MII control functions
+ *
+ * Design Notes:
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxOsal.h"
+
+#include "IxEthAcc.h"
+#include "IxEthMii_p.h"
+
+#ifdef __wince
+#include "IxOsPrintf.h"
+#endif
+
+/* Array to store the phy IDs of the discovered phys */
+PRIVATE UINT32 ixEthMiiPhyId[IXP425_ETH_ACC_MII_MAX_ADDR];
+
+/*********************************************************
+ *
+ * Scan for PHYs on the MII bus. This function returns
+ * an array of booleans, one for each PHY address.
+ * If a PHY is found at a particular address, the
+ * corresponding entry in the array is set to TRUE.
+ *
+ */
+
+PUBLIC IX_STATUS
+ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount)
+{
+ UINT32 i;
+ UINT16 regval, regvalId1, regvalId2;
+
+ /*Search for PHYs on the MII*/
+ /*Search for existant phys on the MDIO bus*/
+
+ if ((phyPresent == NULL) ||
+ (maxPhyCount > IXP425_ETH_ACC_MII_MAX_ADDR))
+ {
+ return IX_FAIL;
+ }
+
+ /* fill the array */
+ for(i=0;
+ i<IXP425_ETH_ACC_MII_MAX_ADDR;
+ i++)
+ {
+ phyPresent[i] = FALSE;
+ }
+
+ /* iterate through the PHY addresses */
+ for(i=0;
+ maxPhyCount > 0 && i<IXP425_ETH_ACC_MII_MAX_ADDR;
+ i++)
+ {
+ ixEthMiiPhyId[i] = IX_ETH_MII_INVALID_PHY_ID;
+ if(ixEthAccMiiReadRtn(i,
+ IX_ETH_MII_CTRL_REG,
+ &regval) == IX_ETH_ACC_SUCCESS)
+ {
+ if((regval & 0xffff) != 0xffff)
+ {
+ maxPhyCount--;
+ /*Need to read the register twice here to flush PHY*/
+ ixEthAccMiiReadRtn(i, IX_ETH_MII_PHY_ID1_REG, &regvalId1);
+ ixEthAccMiiReadRtn(i, IX_ETH_MII_PHY_ID1_REG, &regvalId1);
+ ixEthAccMiiReadRtn(i, IX_ETH_MII_PHY_ID2_REG, &regvalId2);
+ ixEthMiiPhyId[i] = (regvalId1 << IX_ETH_MII_REG_SHL) | regvalId2;
+ if ((ixEthMiiPhyId[i] == IX_ETH_MII_KS8995_PHY_ID)
+ || (ixEthMiiPhyId[i] == IX_ETH_MII_LXT971_PHY_ID)
+ || (ixEthMiiPhyId[i] == IX_ETH_MII_LXT972_PHY_ID)
+ || (ixEthMiiPhyId[i] == IX_ETH_MII_LXT973_PHY_ID)
+ || (ixEthMiiPhyId[i] == IX_ETH_MII_LXT973A3_PHY_ID)
+ || (ixEthMiiPhyId[i] == IX_ETH_MII_LXT9785_PHY_ID)
+ )
+ {
+ /* supported phy */
+ phyPresent[i] = TRUE;
+ } /* end of if(ixEthMiiPhyId) */
+ else
+ {
+ if (ixEthMiiPhyId[i] != IX_ETH_MII_INVALID_PHY_ID)
+ {
+ /* unsupported phy */
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "ixEthMiiPhyScan : unexpected Mii PHY ID %8.8x\n",
+ ixEthMiiPhyId[i], 2, 3, 4, 5, 6);
+ ixEthMiiPhyId[i] = IX_ETH_MII_UNKNOWN_PHY_ID;
+ phyPresent[i] = TRUE;
+ }
+ }
+ }
+ }
+ }
+ return IX_SUCCESS;
+}
+
+/************************************************************
+ *
+ * Configure the PHY at the specified address
+ *
+ */
+PUBLIC IX_STATUS
+ixEthMiiPhyConfig(UINT32 phyAddr,
+ BOOL speed100,
+ BOOL fullDuplex,
+ BOOL autonegotiate)
+{
+ UINT16 regval=0;
+
+ /* parameter check */
+ if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
+ (ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
+ {
+ /*
+ * set the control register
+ */
+ if(autonegotiate)
+ {
+ regval |= IX_ETH_MII_CR_AUTO_EN | IX_ETH_MII_CR_RESTART;
+ }
+ else
+ {
+ if(speed100)
+ {
+ regval |= IX_ETH_MII_CR_100;
+ }
+ if(fullDuplex)
+ {
+ regval |= IX_ETH_MII_CR_FDX;
+ }
+ } /* end of if-else() */
+ if (ixEthAccMiiWriteRtn(phyAddr,
+ IX_ETH_MII_CTRL_REG,
+ regval) == IX_ETH_ACC_SUCCESS)
+ {
+ return IX_SUCCESS;
+ }
+ } /* end of if(phyAddr) */
+ return IX_FAIL;
+}
+
+/******************************************************************
+ *
+ * Enable the PHY Loopback at the specified address
+ */
+PUBLIC IX_STATUS
+ixEthMiiPhyLoopbackEnable (UINT32 phyAddr)
+{
+ UINT16 regval ;
+
+ if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
+ (IX_ETH_MII_INVALID_PHY_ID != ixEthMiiPhyId[phyAddr]))
+ {
+ /* read/write the control register */
+ if(ixEthAccMiiReadRtn (phyAddr,
+ IX_ETH_MII_CTRL_REG,
+ &regval)
+ == IX_ETH_ACC_SUCCESS)
+ {
+ if(ixEthAccMiiWriteRtn (phyAddr,
+ IX_ETH_MII_CTRL_REG,
+ regval | IX_ETH_MII_CR_LOOPBACK)
+ == IX_ETH_ACC_SUCCESS)
+ {
+ return IX_SUCCESS;
+ }
+ }
+ }
+ return IX_FAIL;
+}
+
+/******************************************************************
+ *
+ * Disable the PHY Loopback at the specified address
+ */
+PUBLIC IX_STATUS
+ixEthMiiPhyLoopbackDisable (UINT32 phyAddr)
+{
+ UINT16 regval ;
+
+ if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
+ (IX_ETH_MII_INVALID_PHY_ID != ixEthMiiPhyId[phyAddr]))
+ {
+ /* read/write the control register */
+ if(ixEthAccMiiReadRtn (phyAddr,
+ IX_ETH_MII_CTRL_REG,
+ &regval)
+ == IX_ETH_ACC_SUCCESS)
+ {
+ if(ixEthAccMiiWriteRtn (phyAddr,
+ IX_ETH_MII_CTRL_REG,
+ regval & (~IX_ETH_MII_CR_LOOPBACK))
+ == IX_ETH_ACC_SUCCESS)
+ {
+ return IX_SUCCESS;
+ }
+ }
+ }
+ return IX_FAIL;
+}
+
+/******************************************************************
+ *
+ * Reset the PHY at the specified address
+ */
+PUBLIC IX_STATUS
+ixEthMiiPhyReset(UINT32 phyAddr)
+{
+ UINT32 timeout;
+ UINT16 regval;
+
+ if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
+ (ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
+ {
+ if ((ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT971_PHY_ID) ||
+ (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT972_PHY_ID) ||
+ (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT973_PHY_ID) ||
+ (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT973A3_PHY_ID) ||
+ (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT9785_PHY_ID)
+ )
+ {
+ /* use the control register to reset the phy */
+ ixEthAccMiiWriteRtn(phyAddr,
+ IX_ETH_MII_CTRL_REG,
+ IX_ETH_MII_CR_RESET);
+
+ /* poll until the reset bit is cleared */
+ timeout = 0;
+ do
+ {
+ ixOsalSleep (IX_ETH_MII_RESET_POLL_MS);
+
+ /* read the control register and check for timeout */
+ ixEthAccMiiReadRtn(phyAddr,
+ IX_ETH_MII_CTRL_REG,
+ &regval);
+ if ((regval & IX_ETH_MII_CR_RESET) == 0)
+ {
+ /* timeout bit is self-cleared */
+ break;
+ }
+ timeout += IX_ETH_MII_RESET_POLL_MS;
+ }
+ while (timeout < IX_ETH_MII_RESET_DELAY_MS);
+
+ /* check for timeout */
+ if (timeout >= IX_ETH_MII_RESET_DELAY_MS)
+ {
+ ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
+ IX_ETH_MII_CR_NORM_EN);
+ return IX_FAIL;
+ }
+
+ return IX_SUCCESS;
+ } /* end of if(ixEthMiiPhyId) */
+ else if (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_KS8995_PHY_ID)
+ {
+ /* reset bit is reserved, just reset the control register */
+ ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
+ IX_ETH_MII_CR_NORM_EN);
+ return IX_SUCCESS;
+ }
+ else
+ {
+ /* unknown PHY, set the control register reset bit,
+ * wait 2 s. and clear the control register.
+ */
+ ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
+ IX_ETH_MII_CR_RESET);
+
+ ixOsalSleep (IX_ETH_MII_RESET_DELAY_MS);
+
+ ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
+ IX_ETH_MII_CR_NORM_EN);
+ return IX_SUCCESS;
+ } /* end of if-else(ixEthMiiPhyId) */
+ } /* end of if(phyAddr) */
+ return IX_FAIL;
+}
+
+/*****************************************************************
+ *
+ * Link state query functions
+ */
+
+PUBLIC IX_STATUS
+ixEthMiiLinkStatus(UINT32 phyAddr,
+ BOOL *linkUp,
+ BOOL *speed100,
+ BOOL *fullDuplex,
+ BOOL *autoneg)
+{
+ UINT16 ctrlRegval, statRegval, regval, regval4, regval5;
+
+ /* check the parameters */
+ if ((linkUp == NULL) ||
+ (speed100 == NULL) ||
+ (fullDuplex == NULL) ||
+ (autoneg == NULL))
+ {
+ return IX_FAIL;
+ }
+
+ *linkUp = FALSE;
+ *speed100 = FALSE;
+ *fullDuplex = FALSE;
+ *autoneg = FALSE;
+
+ if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
+ (ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
+ {
+ if ((ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT971_PHY_ID) ||
+ (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT972_PHY_ID) ||
+ (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT9785_PHY_ID)
+ )
+ {
+ /* --------------------------------------------------*/
+ /* Retrieve information from PHY specific register */
+ /* --------------------------------------------------*/
+ if (ixEthAccMiiReadRtn(phyAddr,
+ IX_ETH_MII_STAT2_REG,
+ &regval) != IX_ETH_ACC_SUCCESS)
+ {
+ return IX_FAIL;
+ }
+ *linkUp = ((regval & IX_ETH_MII_SR2_LINK) != 0);
+ *speed100 = ((regval & IX_ETH_MII_SR2_100) != 0);
+ *fullDuplex = ((regval & IX_ETH_MII_SR2_FD) != 0);
+ *autoneg = ((regval & IX_ETH_MII_SR2_AUTO) != 0);
+ return IX_SUCCESS;
+ } /* end of if(ixEthMiiPhyId) */
+ else
+ {
+ /* ----------------------------------------------------*/
+ /* Retrieve information from status and ctrl registers */
+ /* ----------------------------------------------------*/
+ if (ixEthAccMiiReadRtn(phyAddr,
+ IX_ETH_MII_CTRL_REG,
+ &ctrlRegval) != IX_ETH_ACC_SUCCESS)
+ {
+ return IX_FAIL;
+ }
+ ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_STAT_REG, &statRegval);
+
+ *linkUp = ((statRegval & IX_ETH_MII_SR_LINK_STATUS) != 0);
+ if (*linkUp)
+ {
+ *autoneg = ((ctrlRegval & IX_ETH_MII_CR_AUTO_EN) != 0) &&
+ ((statRegval & IX_ETH_MII_SR_AUTO_SEL) != 0) &&
+ ((statRegval & IX_ETH_MII_SR_AUTO_NEG) != 0);
+
+ if (*autoneg)
+ {
+ /* mask the current stat values with the capabilities */
+ ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_ADS_REG, &regval4);
+ ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_PRTN_REG, &regval5);
+ /* merge the flags from the 3 registers */
+ regval = (statRegval & ((regval4 & regval5) << 6));
+ /* initialise from status register values */
+ if ((regval & IX_ETH_MII_SR_TX_FULL_DPX) != 0)
+ {
+ /* 100 Base X full dplx */
+ *speed100 = TRUE;
+ *fullDuplex = TRUE;
+ return IX_SUCCESS;
+ }
+ if ((regval & IX_ETH_MII_SR_TX_HALF_DPX) != 0)
+ {
+ /* 100 Base X half dplx */
+ *speed100 = TRUE;
+ return IX_SUCCESS;
+ }
+ if ((regval & IX_ETH_MII_SR_10T_FULL_DPX) != 0)
+ {
+ /* 10 mb full dplx */
+ *fullDuplex = TRUE;
+ return IX_SUCCESS;
+ }
+ if ((regval & IX_ETH_MII_SR_10T_HALF_DPX) != 0)
+ {
+ /* 10 mb half dplx */
+ return IX_SUCCESS;
+ }
+ } /* end of if(autoneg) */
+ else
+ {
+ /* autonegotiate not complete, return setup parameters */
+ *speed100 = ((ctrlRegval & IX_ETH_MII_CR_100) != 0);
+ *fullDuplex = ((ctrlRegval & IX_ETH_MII_CR_FDX) != 0);
+ }
+ } /* end of if(linkUp) */
+ } /* end of if-else(ixEthMiiPhyId) */
+ } /* end of if(phyAddr) */
+ else
+ {
+ return IX_FAIL;
+ } /* end of if-else(phyAddr) */
+ return IX_SUCCESS;
+}
+
+/*****************************************************************
+ *
+ * Link state display functions
+ */
+
+PUBLIC IX_STATUS
+ixEthMiiPhyShow (UINT32 phyAddr)
+{
+ BOOL linkUp, speed100, fullDuplex, autoneg;
+ UINT16 cregval;
+ UINT16 sregval;
+
+
+ ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_STAT_REG, &sregval);
+ ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_CTRL_REG, &cregval);
+
+ /* get link information */
+ if (ixEthMiiLinkStatus(phyAddr,
+ &linkUp,
+ &speed100,
+ &fullDuplex,
+ &autoneg) != IX_ETH_ACC_SUCCESS)
+ {
+ printf("PHY Status unknown\n");
+ return IX_FAIL;
+ }
+
+ printf("PHY ID [phyAddr]: %8.8x\n",ixEthMiiPhyId[phyAddr]);
+ printf( " Status reg: %4.4x\n",sregval);
+ printf( " control reg: %4.4x\n",cregval);
+ /* display link information */
+ printf("PHY Status:\n");
+ printf(" Link is %s\n",
+ (linkUp ? "Up" : "Down"));
+ if((sregval & IX_ETH_MII_SR_REMOTE_FAULT) != 0)
+ {
+ printf(" Remote fault detected\n");
+ }
+ printf(" Auto Negotiation %s\n",
+ (autoneg ? "Completed" : "Not Completed"));
+
+ printf("PHY Configuration:\n");
+ printf(" Speed %sMb/s\n",
+ (speed100 ? "100" : "10"));
+ printf(" %s Duplex\n",
+ (fullDuplex ? "Full" : "Half"));
+ printf(" Auto Negotiation %s\n",
+ (autoneg ? "Enabled" : "Disabled"));
+ return IX_SUCCESS;
+}
+
diff --git a/cpu/ixp/npe/IxFeatureCtrl.c b/cpu/ixp/npe/IxFeatureCtrl.c
new file mode 100644
index 0000000..e02aabf
--- /dev/null
+++ b/cpu/ixp/npe/IxFeatureCtrl.c
@@ -0,0 +1,422 @@
+/**
+ * @file IxFeatureCtrl.c
+ *
+ * @author Intel Corporation
+ * @date 29-Jan-2003
+ *
+ * @brief Feature Control Public API Implementation
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+#include "IxOsal.h"
+#include "IxVersionId.h"
+#include "IxFeatureCtrl.h"
+
+/* Macro to read from the Feature Control Register */
+#define IX_FEATURE_CTRL_READ(result) \
+do { \
+ixFeatureCtrlExpMap(); \
+(result) = IX_OSAL_READ_LONG(ixFeatureCtrlRegister); \
+} while (0)
+
+/* Macro to write to the Feature Control Register */
+#define IX_FEATURE_CTRL_WRITE(value) \
+do { \
+ixFeatureCtrlExpMap(); \
+IX_OSAL_WRITE_LONG(ixFeatureCtrlRegister, (value)); \
+} while (0)
+
+/*
+ * This is the offset of the feature register relative to the base of the
+ * Expansion Bus Controller MMR.
+ */
+#define IX_FEATURE_CTRL_REG_OFFSET (0x00000028)
+
+
+/* Boolean to mark the fact that the EXP_CONFIG address space was mapped */
+PRIVATE BOOL ixFeatureCtrlExpCfgRegionMapped = FALSE;
+
+/* Pointer holding the virtual address of the Feature Control Register */
+PRIVATE VUINT32 *ixFeatureCtrlRegister = NULL;
+
+/* Place holder to store the software configuration */
+PRIVATE BOOL swConfiguration[IX_FEATURECTRL_SWCONFIG_MAX];
+
+/* Flag to control swConfiguration[] is initialized once */
+PRIVATE BOOL swConfigurationFlag = FALSE ;
+
+/* Array containing component mask values */
+#ifdef __ixp42X
+UINT32 componentMask[IX_FEATURECTRL_MAX_COMPONENTS] = {
+ (0x1<<IX_FEATURECTRL_RCOMP),
+ (0x1<<IX_FEATURECTRL_USB),
+ (0x1<<IX_FEATURECTRL_HASH),
+ (0x1<<IX_FEATURECTRL_AES),
+ (0x1<<IX_FEATURECTRL_DES),
+ (0x1<<IX_FEATURECTRL_HDLC),
+ (0x1<<IX_FEATURECTRL_AAL),
+ (0x1<<IX_FEATURECTRL_HSS),
+ (0x1<<IX_FEATURECTRL_UTOPIA),
+ (0x1<<IX_FEATURECTRL_ETH0),
+ (0x1<<IX_FEATURECTRL_ETH1),
+ (0x1<<IX_FEATURECTRL_NPEA),
+ (0x1<<IX_FEATURECTRL_NPEB),
+ (0x1<<IX_FEATURECTRL_NPEC),
+ (0x1<<IX_FEATURECTRL_PCI),
+ IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
+ (0x3<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT),
+ (0x1<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT_BIT2),
+ IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
+ IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
+ IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
+ IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
+ IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE
+};
+#elif defined (__ixp46X)
+UINT32 componentMask[IX_FEATURECTRL_MAX_COMPONENTS] = {
+ (0x1<<IX_FEATURECTRL_RCOMP),
+ (0x1<<IX_FEATURECTRL_USB),
+ (0x1<<IX_FEATURECTRL_HASH),
+ (0x1<<IX_FEATURECTRL_AES),
+ (0x1<<IX_FEATURECTRL_DES),
+ (0x1<<IX_FEATURECTRL_HDLC),
+ IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE, /* AAL component is always on */
+ (0x1<<IX_FEATURECTRL_HSS),
+ (0x1<<IX_FEATURECTRL_UTOPIA),
+ (0x1<<IX_FEATURECTRL_ETH0),
+ (0x1<<IX_FEATURECTRL_ETH1),
+ (0x1<<IX_FEATURECTRL_NPEA),
+ (0x1<<IX_FEATURECTRL_NPEB),
+ (0x1<<IX_FEATURECTRL_NPEC),
+ (0x1<<IX_FEATURECTRL_PCI),
+ (0x1<<IX_FEATURECTRL_ECC_TIMESYNC),
+ (0x3<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT),
+ (0x1<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT_BIT2), /* NOT TO BE USED */
+ (0x1<<IX_FEATURECTRL_USB_HOST_CONTROLLER),
+ (0x1<<IX_FEATURECTRL_NPEA_ETH),
+ (0x1<<IX_FEATURECTRL_NPEB_ETH),
+ (0x1<<IX_FEATURECTRL_RSA),
+ (0x3<<IX_FEATURECTRL_XSCALE_MAX_FREQ),
+ (0x1<<IX_FEATURECTRL_XSCALE_MAX_FREQ_BIT2)
+};
+#endif /* __ixp42X */
+
+/**
+ * Forward declaration
+ */
+PRIVATE
+void ixFeatureCtrlExpMap(void);
+
+PRIVATE
+void ixFeatureCtrlSwConfigurationInit(void);
+
+/**
+ * Function to map EXP_CONFIG space
+ */
+PRIVATE
+void ixFeatureCtrlExpMap(void)
+{
+ UINT32 expCfgBaseAddress = 0;
+
+ /* If the EXP Configuration space has already been mapped then
+ * return */
+ if (ixFeatureCtrlExpCfgRegionMapped == TRUE)
+ {
+ return;
+ }
+
+ /* Map (get virtual address) for the EXP_CONFIG space */
+ expCfgBaseAddress = (UINT32)
+ (IX_OSAL_MEM_MAP(IX_OSAL_IXP400_EXP_BUS_REGS_PHYS_BASE,
+ IX_OSAL_IXP400_EXP_REG_MAP_SIZE));
+
+ /* Assert that the mapping operation succeeded */
+ IX_OSAL_ASSERT(expCfgBaseAddress);
+
+ /* Set the address of the Feature register */
+ ixFeatureCtrlRegister =
+ (VUINT32 *) (expCfgBaseAddress + IX_FEATURE_CTRL_REG_OFFSET);
+
+ /* Mark the fact that the EXP_CONFIG space has already been mapped */
+ ixFeatureCtrlExpCfgRegionMapped = TRUE;
+}
+
+/**
+ * Function definition: ixFeatureCtrlSwConfigurationInit
+ * This function will only initialize software configuration once.
+ */
+PRIVATE void ixFeatureCtrlSwConfigurationInit(void)
+{
+ UINT32 i;
+ if (FALSE == swConfigurationFlag)
+ {
+ for (i=0; i<IX_FEATURECTRL_SWCONFIG_MAX ; i++)
+ {
+ /* By default, all software configuration are enabled */
+ swConfiguration[i]= TRUE ;
+ }
+ /*Make sure this function only initializes swConfiguration[] once*/
+ swConfigurationFlag = TRUE ;
+ }
+}
+
+/**
+ * Function definition: ixFeatureCtrlRead
+ */
+IxFeatureCtrlReg
+ixFeatureCtrlRead (void)
+{
+ IxFeatureCtrlReg result;
+
+#if CPU!=SIMSPARCSOLARIS
+ /* Read the feature control register */
+ IX_FEATURE_CTRL_READ(result);
+ return result;
+#else
+ /* Return an invalid value for VxWorks simulation */
+ result = 0xFFFFFFFF;
+ return result;
+#endif
+}
+
+/**
+ * Function definition: ixFeatureCtrlWrite
+ */
+void
+ixFeatureCtrlWrite (IxFeatureCtrlReg expUnitReg)
+{
+#if CPU!=SIMSPARCSOLARIS
+ /* Write value to feature control register */
+ IX_FEATURE_CTRL_WRITE(expUnitReg);
+#endif
+}
+
+
+/**
+ * Function definition: ixFeatureCtrlHwCapabilityRead
+ */
+IxFeatureCtrlReg
+ixFeatureCtrlHwCapabilityRead (void)
+{
+ IxFeatureCtrlReg currentReg, hwCapability;
+
+ /* Capture a copy of feature control register */
+ currentReg = ixFeatureCtrlRead();
+
+ /* Try to enable all hardware components.
+ * Only software disable hardware can be enabled again */
+ ixFeatureCtrlWrite(0);
+
+ /* Read feature control register to know the hardware capability. */
+ hwCapability = ixFeatureCtrlRead();
+
+ /* Restore initial feature control value */
+ ixFeatureCtrlWrite(currentReg);
+
+ /* return Hardware Capability */
+ return hwCapability;
+}
+
+
+/**
+ * Function definition: ixFeatureCtrlComponentCheck
+ */
+IX_STATUS
+ixFeatureCtrlComponentCheck (IxFeatureCtrlComponentType componentType)
+{
+ IxFeatureCtrlReg expUnitReg;
+ UINT32 mask = 0;
+
+ /* Lookup mask of component */
+ mask=componentMask[componentType];
+
+ /* Check if mask is available or not */
+ if(IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE == mask)
+ {
+ return IX_FEATURE_CTRL_COMPONENT_DISABLED;
+ }
+
+ if(IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE == mask)
+ {
+ return IX_FEATURE_CTRL_COMPONENT_ENABLED;
+ }
+
+ /* Read feature control register to know current hardware capability. */
+ expUnitReg = ixFeatureCtrlRead();
+
+ /* For example: To check for Hashing Coprocessor (bit-2)
+ * expUniteg = 0x0010
+ * ~expUnitReg = 0x1101
+ * componentType = 0x0100
+ * ~expUnitReg & componentType = 0x0100 (Not zero)
+ */
+
+ /*
+ * Inverse the bit value because available component is 0 in value
+ */
+ expUnitReg = ~expUnitReg ;
+
+ if (expUnitReg & mask)
+ {
+ return (IX_FEATURE_CTRL_COMPONENT_ENABLED);
+ }
+ else
+ {
+ return (IX_FEATURE_CTRL_COMPONENT_DISABLED);
+ }
+}
+
+
+/**
+ * Function definition: ixFeatureCtrlProductIdRead
+ */
+IxFeatureCtrlProductId
+ixFeatureCtrlProductIdRead ()
+{
+#if CPU!=SIMSPARCSOLARIS
+ IxFeatureCtrlProductId pdId = 0 ;
+
+ /* Use ARM instruction to move register0 from coprocessor to ARM register */
+
+#ifndef __wince
+ __asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(pdId) :);
+#else
+
+#ifndef IN_KERNEL
+ BOOL mode;
+#endif
+ extern IxFeatureCtrlProductId AsmixFeatureCtrlProductIdRead();
+
+#ifndef IN_KERNEL
+ mode = SetKMode(TRUE);
+#endif
+ pdId = AsmixFeatureCtrlProductIdRead();
+#ifndef IN_KERNEL
+ SetKMode(mode);
+#endif
+
+#endif
+ return (pdId);
+#else
+ /* Return an invalid value for VxWorks simulation */
+ return 0xffffffff;
+#endif
+}
+
+/**
+ * Function definition: ixFeatureCtrlDeviceRead
+ */
+IxFeatureCtrlDeviceId
+ixFeatureCtrlDeviceRead ()
+{
+ return ((ixFeatureCtrlProductIdRead() >> IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET)
+ & IX_FEATURE_CTRL_DEVICE_TYPE_MASK);
+} /* End function ixFeatureCtrlDeviceRead */
+
+
+/**
+ * Function definition: ixFeatureCtrlSwConfigurationCheck
+ */
+IX_STATUS
+ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType)
+{
+ if (swConfigType >= IX_FEATURECTRL_SWCONFIG_MAX)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_WARNING,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "FeatureCtrl: Invalid software configuraiton input.\n",
+ 0, 0, 0, 0, 0, 0);
+
+ return IX_FEATURE_CTRL_SWCONFIG_DISABLED;
+ }
+
+ /* The function will only initialize once. */
+ ixFeatureCtrlSwConfigurationInit();
+
+ /* Check and return software configuration */
+ return ((swConfiguration[(UINT32)swConfigType] == TRUE) ? IX_FEATURE_CTRL_SWCONFIG_ENABLED: IX_FEATURE_CTRL_SWCONFIG_DISABLED);
+}
+
+/**
+ * Function definition: ixFeatureCtrlSwConfigurationWrite
+ */
+void
+ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled)
+{
+ if (swConfigType >= IX_FEATURECTRL_SWCONFIG_MAX)
+ {
+ ixOsalLog(IX_OSAL_LOG_LVL_WARNING,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "FeatureCtrl: Invalid software configuraiton input.\n",
+ 0, 0, 0, 0, 0, 0);
+
+ return;
+ }
+
+ /* The function will only initialize once. */
+ ixFeatureCtrlSwConfigurationInit();
+
+ /* Write software configuration */
+ swConfiguration[(UINT32)swConfigType]=enabled ;
+}
+
+/**
+ * Function definition: ixFeatureCtrlIxp400SwVersionShow
+ */
+void
+ixFeatureCtrlIxp400SwVersionShow (void)
+{
+ printf ("\nIXP400 Software Release %s %s\n\n", IX_VERSION_ID, IX_VERSION_INTERNAL_ID);
+
+}
+
+/**
+ * Function definition: ixFeatureCtrlSoftwareBuildGet
+ */
+IxFeatureCtrlBuildDevice
+ixFeatureCtrlSoftwareBuildGet (void)
+{
+ #ifdef __ixp42X
+ return IX_FEATURE_CTRL_SW_BUILD_IXP42X;
+ #else
+ return IX_FEATURE_CTRL_SW_BUILD_IXP46X;
+ #endif
+}
diff --git a/cpu/ixp/npe/IxNpeDl.c b/cpu/ixp/npe/IxNpeDl.c
new file mode 100644
index 0000000..ffe355c
--- /dev/null
+++ b/cpu/ixp/npe/IxNpeDl.c
@@ -0,0 +1,972 @@
+/**
+ * @file IxNpeDl.c
+ *
+ * @author Intel Corporation
+ * @date 08 January 2002
+ *
+ * @brief This file contains the implementation of the public API for the
+ * IXP425 NPE Downloader component
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * Put the system defined include files required
+ */
+
+/*
+ * Put the user defined include files required
+ */
+#include "IxNpeDl.h"
+#include "IxNpeDlImageMgr_p.h"
+#include "IxNpeDlNpeMgr_p.h"
+#include "IxNpeDlMacros_p.h"
+#include "IxFeatureCtrl.h"
+#include "IxOsal.h"
+/*
+ * #defines used in this file
+ */
+ #define IMAGEID_MAJOR_NUMBER_DEFAULT 0
+ #define IMAGEID_MINOR_NUMBER_DEFAULT 0
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+typedef struct
+{
+ BOOL validImage;
+ IxNpeDlImageId imageId;
+} IxNpeDlNpeState;
+
+/* module statistics counters */
+typedef struct
+{
+ UINT32 attemptedDownloads;
+ UINT32 successfulDownloads;
+ UINT32 criticalFailDownloads;
+} IxNpeDlStats;
+
+/*
+ * Variable declarations global to this file only. Externs are followed
+ * by static variables.
+ */
+static IxNpeDlNpeState ixNpeDlNpeState[IX_NPEDL_NPEID_MAX] =
+{
+ {FALSE, {IX_NPEDL_NPEID_MAX, 0, 0, 0}},
+ {FALSE, {IX_NPEDL_NPEID_MAX, 0, 0, 0}},
+ {FALSE, {IX_NPEDL_NPEID_MAX, 0, 0, 0}}
+};
+
+static IxNpeDlStats ixNpeDlStats;
+
+/*
+ * Software guard to prevent NPE from being started multiple times.
+ */
+static BOOL ixNpeDlNpeStarted[IX_NPEDL_NPEID_MAX] ={FALSE, FALSE, FALSE} ;
+
+
+/*
+ * static function prototypes.
+ */
+PRIVATE IX_STATUS
+ixNpeDlNpeInitAndStartInternal (UINT32 *imageLibrary, UINT32 imageId);
+
+/*
+ * Function definition: ixNpeDlMicrocodeImageLibraryOverride
+ */
+PUBLIC IX_STATUS
+ixNpeDlMicrocodeImageLibraryOverride (UINT32 *clientImageLibrary)
+{
+ IX_STATUS status = IX_SUCCESS;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlMicrocodeImageLibraryOverride\n");
+
+ if (clientImageLibrary == NULL)
+ {
+ status = IX_NPEDL_PARAM_ERR;
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlMicrocodeImageLibraryOverride - "
+ "invalid parameter\n");
+ }
+ else
+ {
+ status = ixNpeDlImageMgrMicrocodeImageLibraryOverride (clientImageLibrary);
+ if (status != IX_SUCCESS)
+ {
+ status = IX_FAIL;
+ }
+ } /* end of if-else(clientImageLibrary) */
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlMicrocodeImageLibraryOverride : "
+ "status = %d\n", status);
+ return status;
+}
+
+/*
+ * Function definition: ixNpeDlImageDownload
+ */
+PUBLIC IX_STATUS
+ixNpeDlImageDownload (IxNpeDlImageId *imageIdPtr,
+ BOOL verify)
+{
+ UINT32 imageSize;
+ UINT32 *imageCodePtr = NULL;
+ IX_STATUS status;
+ IxNpeDlNpeId npeId = imageIdPtr->npeId;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlImageDownload\n");
+
+ ixNpeDlStats.attemptedDownloads++;
+
+ /* Check input parameters */
+ if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
+ {
+ status = IX_NPEDL_PARAM_ERR;
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlImageDownload - invalid parameter\n");
+ }
+ else
+ {
+ /* Ensure initialisation has been completed */
+ ixNpeDlNpeMgrInit();
+
+ /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
+ if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+ (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+ || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+ {
+ if (npeId == IX_NPEDL_NPEID_NPEA)
+ {
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED)
+ {
+ IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
+ " not exist\n");
+ return IX_SUCCESS;
+ }
+ } /* end of if(npeId) */
+ else if (npeId == IX_NPEDL_NPEID_NPEB)
+ {
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED)
+ {
+ IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified"
+ " does not exist\n");
+ return IX_SUCCESS;
+ }
+ } /* end of elseif(npeId) */
+ else if (npeId == IX_NPEDL_NPEID_NPEC)
+ {
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED)
+ {
+ IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified"
+ " does not exist\n");
+ return IX_SUCCESS;
+ }
+ } /* end of elseif(npeId) */
+ } /* end of if(IX_FEATURE_CTRL_SILICON_TYPE_B0) */ /*End of Silicon Type Check*/
+
+ /* stop and reset the NPE */
+ if (IX_SUCCESS != ixNpeDlNpeStopAndReset (npeId))
+ {
+ IX_NPEDL_ERROR_REPORT ("Failed to stop and reset NPE\n");
+ return IX_FAIL;
+ }
+
+ /* Locate image */
+ status = ixNpeDlImageMgrImageLocate (imageIdPtr, &imageCodePtr,
+ &imageSize);
+ if (IX_SUCCESS == status)
+ {
+ /*
+ * If download was successful, store image Id in list of
+ * currently loaded images. If a critical error occured
+ * during download, record that the NPE has an invalid image
+ */
+ status = ixNpeDlNpeMgrImageLoad (npeId, imageCodePtr,
+ verify);
+ if (IX_SUCCESS == status)
+ {
+ ixNpeDlNpeState[npeId].imageId = *imageIdPtr;
+ ixNpeDlNpeState[npeId].validImage = TRUE;
+ ixNpeDlStats.successfulDownloads++;
+
+ status = ixNpeDlNpeExecutionStart (npeId);
+ }
+ else if ((status == IX_NPEDL_CRITICAL_NPE_ERR) ||
+ (status == IX_NPEDL_CRITICAL_MICROCODE_ERR))
+ {
+ ixNpeDlNpeState[npeId].imageId = *imageIdPtr;
+ ixNpeDlNpeState[npeId].validImage = FALSE;
+ ixNpeDlStats.criticalFailDownloads++;
+ }
+ } /* end of if(IX_SUCCESS) */ /* condition: image located successfully in microcode image */
+ } /* end of if-else(npeId) */ /* condition: parameter checks ok */
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlImageDownload : status = %d\n", status);
+ return status;
+}
+
+/*
+ * Function definition: ixNpeDlAvailableImagesCountGet
+ */
+PUBLIC IX_STATUS
+ixNpeDlAvailableImagesCountGet (UINT32 *numImagesPtr)
+{
+ IX_STATUS status;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlAvailableImagesCountGet\n");
+
+ /* Check input parameters */
+ if (numImagesPtr == NULL)
+ {
+ status = IX_NPEDL_PARAM_ERR;
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlAvailableImagesCountGet - "
+ "invalid parameter\n");
+ }
+ else
+ {
+ /*
+ * Use ImageMgr module to get no. of images listed in Image Library Header.
+ * If NULL is passed as imageListPtr parameter to following function,
+ * it will only fill number of images into numImagesPtr
+ */
+ status = ixNpeDlImageMgrImageListExtract (NULL, numImagesPtr);
+ } /* end of if-else(numImagesPtr) */
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlAvailableImagesCountGet : "
+ "status = %d\n", status);
+ return status;
+}
+
+/*
+ * Function definition: ixNpeDlAvailableImagesListGet
+ */
+PUBLIC IX_STATUS
+ixNpeDlAvailableImagesListGet (IxNpeDlImageId *imageIdListPtr,
+ UINT32 *listSizePtr)
+{
+ IX_STATUS status;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlAvailableImagesListGet\n");
+
+ /* Check input parameters */
+ if ((imageIdListPtr == NULL) || (listSizePtr == NULL))
+ {
+ status = IX_NPEDL_PARAM_ERR;
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlAvailableImagesListGet - "
+ "invalid parameter\n");
+ }
+ else
+ {
+ /* Call ImageMgr to get list of images listed in Image Library Header */
+ status = ixNpeDlImageMgrImageListExtract (imageIdListPtr,
+ listSizePtr);
+ } /* end of if-else(imageIdListPtr) */
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlAvailableImagesListGet : status = %d\n",
+ status);
+ return status;
+}
+
+/*
+ * Function definition: ixNpeDlLoadedImageGet
+ */
+PUBLIC IX_STATUS
+ixNpeDlLoadedImageGet (IxNpeDlNpeId npeId,
+ IxNpeDlImageId *imageIdPtr)
+{
+ IX_STATUS status = IX_SUCCESS;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlLoadedImageGet\n");
+
+ /* Check input parameters */
+ if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0) || (imageIdPtr == NULL))
+ {
+ status = IX_NPEDL_PARAM_ERR;
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageGet - invalid parameter\n");
+ }
+ else
+ {
+
+ /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
+ if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+ (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+ || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+ {
+ if (npeId == IX_NPEDL_NPEID_NPEA &&
+ (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED))
+ {
+ IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
+ " not exist\n");
+ return IX_SUCCESS;
+ } /* end of if(npeId) */
+
+ if (npeId == IX_NPEDL_NPEID_NPEB &&
+ (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) ==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED))
+ {
+ IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified does"
+ " not exist\n");
+ return IX_SUCCESS;
+ } /* end of if(npeId) */
+
+ if (npeId == IX_NPEDL_NPEID_NPEC &&
+ (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) ==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED))
+ {
+ IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified does"
+ " not exist\n");
+ return IX_SUCCESS;
+ } /* end of if(npeId) */
+ } /* end of if not IXP42x-A0 silicon */
+
+ if (ixNpeDlNpeState[npeId].validImage)
+ {
+ /* use npeId to get imageId from list of currently loaded
+ images */
+ *imageIdPtr = ixNpeDlNpeState[npeId].imageId;
+ }
+ else
+ {
+ status = IX_FAIL;
+ } /* end of if-else(ixNpeDlNpeState) */
+ } /* end of if-else(npeId) */
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlLoadedImageGet : status = %d\n",
+ status);
+ return status;
+}
+
+/*
+ * Function definition: ixNpeDlLatestImageGet
+ */
+PUBLIC IX_STATUS
+ixNpeDlLatestImageGet (
+ IxNpeDlNpeId npeId,
+ IxNpeDlFunctionalityId functionalityId,
+ IxNpeDlImageId *imageIdPtr)
+{
+ IX_STATUS status;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlLatestImageGet\n");
+
+ /* Check input parameters */
+ if ((npeId >= IX_NPEDL_NPEID_MAX) ||
+ (npeId < 0) ||
+ (imageIdPtr == NULL))
+ {
+ status = IX_NPEDL_PARAM_ERR;
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlLatestImageGet - "
+ "invalid parameter\n");
+ } /* end of if(npeId) */
+ else
+ {
+
+ /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
+ if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+ (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+ || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+ {
+ if (npeId == IX_NPEDL_NPEID_NPEA &&
+ (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED))
+ {
+ IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
+ " not exist\n");
+ return IX_SUCCESS;
+ } /* end of if(npeId) */
+
+ if (npeId == IX_NPEDL_NPEID_NPEB &&
+ (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) ==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED))
+ {
+ IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified does"
+ " not exist\n");
+ return IX_SUCCESS;
+ } /* end of if(npeId) */
+
+ if (npeId == IX_NPEDL_NPEID_NPEC &&
+ (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) ==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED))
+ {
+ IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified does"
+ " not exist\n");
+ return IX_SUCCESS;
+ } /* end of if(npeId) */
+ } /* end of if not IXP42x-A0 silicon */
+
+ imageIdPtr->npeId = npeId;
+ imageIdPtr->functionalityId = functionalityId;
+ imageIdPtr->major = IMAGEID_MAJOR_NUMBER_DEFAULT;
+ imageIdPtr->minor = IMAGEID_MINOR_NUMBER_DEFAULT;
+ /* Call ImageMgr to get list of images listed in Image Library Header */
+ status = ixNpeDlImageMgrLatestImageExtract(imageIdPtr);
+ } /* end of if-else(npeId) */
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlLatestImageGet : status = %d\n",
+ status);
+
+ return status;
+}
+
+/*
+ * Function definition: ixNpeDlNpeStopAndReset
+ */
+PUBLIC IX_STATUS
+ixNpeDlNpeStopAndReset (IxNpeDlNpeId npeId)
+{
+ IX_STATUS status = IX_SUCCESS;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlNpeStopAndReset\n");
+
+ /* Ensure initialisation has been completed */
+ ixNpeDlNpeMgrInit();
+
+ /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
+ if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+ (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+ || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+ {
+ /*
+ * Check whether NPE is present
+ */
+ if (IX_NPEDL_NPEID_NPEA == npeId)
+ {
+ /* Check whether NPE A is present */
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED)
+ {
+ /* NPE A does not present */
+ IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEA does not present.\n");
+ return IX_SUCCESS;
+ }
+ } /* end of if(IX_NPEDL_NPEID_NPEA) */
+ else if (IX_NPEDL_NPEID_NPEB == npeId)
+ {
+ /* Check whether NPE B is present */
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED)
+ {
+ /* NPE B does not present */
+ IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEB does not present.\n");
+ return IX_SUCCESS;
+ }
+ } /* end of elseif(IX_NPEDL_NPEID_NPEB) */
+ else if (IX_NPEDL_NPEID_NPEC == npeId)
+ {
+ /* Check whether NPE C is present */
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED)
+ {
+ /* NPE C does not present */
+ IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEC does not present.\n");
+ return IX_SUCCESS;
+ }
+ } /* end of elseif(IX_NPEDL_NPEID_NPEC) */
+ else
+ {
+ /* Invalid NPE ID */
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeStopAndReset - invalid Npe ID\n");
+ status = IX_NPEDL_PARAM_ERR;
+ } /* end of if-else(IX_NPEDL_NPEID_NPEC) */
+ } /* end of if not IXP42x-A0 Silicon */
+
+ if (status == IX_SUCCESS)
+ {
+ /* call NpeMgr function to stop the NPE */
+ status = ixNpeDlNpeMgrNpeStop (npeId);
+ if (status == IX_SUCCESS)
+ {
+ /* call NpeMgr function to reset the NPE */
+ status = ixNpeDlNpeMgrNpeReset (npeId);
+ }
+ } /* end of if(status) */
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlNpeStopAndReset : status = %d\n", status);
+
+ if (IX_SUCCESS == status)
+ {
+ /* Indicate NPE has been stopped */
+ ixNpeDlNpeStarted[npeId] = FALSE ;
+ }
+
+ return status;
+}
+
+/*
+ * Function definition: ixNpeDlNpeExecutionStart
+ */
+PUBLIC IX_STATUS
+ixNpeDlNpeExecutionStart (IxNpeDlNpeId npeId)
+{
+ IX_STATUS status = IX_SUCCESS;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlNpeExecutionStart\n");
+
+ /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
+ if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+ (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+ || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+ {
+ /*
+ * Check whether NPE is present
+ */
+ if (IX_NPEDL_NPEID_NPEA == npeId)
+ {
+ /* Check whether NPE A is present */
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED)
+ {
+ /* NPE A does not present */
+ IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEA does not present.\n");
+ return IX_SUCCESS;
+ }
+ } /* end of if(IX_NPEDL_NPEID_NPEA) */
+ else if (IX_NPEDL_NPEID_NPEB == npeId)
+ {
+ /* Check whether NPE B is present */
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED)
+ {
+ /* NPE B does not present */
+ IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEB does not present.\n");
+ return IX_SUCCESS;
+ }
+ } /* end of elseif(IX_NPEDL_NPEID_NPEB) */
+ else if (IX_NPEDL_NPEID_NPEC == npeId)
+ {
+ /* Check whether NPE C is present */
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED)
+ {
+ /* NPE C does not present */
+ IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEC does not present.\n");
+ return IX_SUCCESS;
+ }
+ } /* end of elseif(IX_NPEDL_NPEID_NPEC) */
+ else
+ {
+ /* Invalid NPE ID */
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeExecutionStart - invalid Npe ID\n");
+ return IX_NPEDL_PARAM_ERR;
+ } /* end of if-else(IX_NPEDL_NPEID_NPEC) */
+ } /* end of if not IXP42x-A0 Silicon */
+
+ if (TRUE == ixNpeDlNpeStarted[npeId])
+ {
+ /* NPE has been started. */
+ return IX_SUCCESS ;
+ }
+
+ /* Ensure initialisation has been completed */
+ ixNpeDlNpeMgrInit();
+
+ /* call NpeMgr function to start the NPE */
+ status = ixNpeDlNpeMgrNpeStart (npeId);
+
+ if (IX_SUCCESS == status)
+ {
+ /* Indicate NPE has started */
+ ixNpeDlNpeStarted[npeId] = TRUE ;
+ }
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlNpeExecutionStart : status = %d\n",
+ status);
+
+ return status;
+}
+
+/*
+ * Function definition: ixNpeDlNpeExecutionStop
+ */
+PUBLIC IX_STATUS
+ixNpeDlNpeExecutionStop (IxNpeDlNpeId npeId)
+{
+ IX_STATUS status = IX_SUCCESS;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlNpeExecutionStop\n");
+
+ /* Ensure initialisation has been completed */
+ ixNpeDlNpeMgrInit();
+
+ /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
+ if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+ (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+ || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+ {
+ /*
+ * Check whether NPE is present
+ */
+ if (IX_NPEDL_NPEID_NPEA == npeId)
+ {
+ /* Check whether NPE A is present */
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED)
+ {
+ /* NPE A does not present */
+ IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEA does not present.\n");
+ return IX_SUCCESS;
+ }
+ } /* end of if(IX_NPEDL_NPEID_NPEA) */
+ else if (IX_NPEDL_NPEID_NPEB == npeId)
+ {
+ /* Check whether NPE B is present */
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED)
+ {
+ /* NPE B does not present */
+ IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEB does not present.\n");
+ return IX_SUCCESS;
+ }
+ } /* end of elseif(IX_NPEDL_NPEID_NPEB) */
+ else if (IX_NPEDL_NPEID_NPEC == npeId)
+ {
+ /* Check whether NPE C is present */
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED)
+ {
+ /* NPE C does not present */
+ IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEC does not present.\n");
+ return IX_SUCCESS;
+ }
+ } /* end of elseif(IX_NPEDL_NPEID_NPEC) */
+ else
+ {
+ /* Invalid NPE ID */
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeExecutionStop - invalid Npe ID\n");
+ status = IX_NPEDL_PARAM_ERR;
+ } /* end of if-else(IX_NPEDL_NPEID_NPEC) */
+ } /* end of if not IXP42X-AO Silicon */
+
+ if (status == IX_SUCCESS)
+ {
+ /* call NpeMgr function to stop the NPE */
+ status = ixNpeDlNpeMgrNpeStop (npeId);
+ }
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlNpeExecutionStop : status = %d\n",
+ status);
+
+ if (IX_SUCCESS == status)
+ {
+ /* Indicate NPE has been stopped */
+ ixNpeDlNpeStarted[npeId] = FALSE ;
+ }
+
+ return status;
+}
+
+/*
+ * Function definition: ixNpeDlUnload
+ */
+PUBLIC IX_STATUS
+ixNpeDlUnload (void)
+{
+ IX_STATUS status;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlUnload\n");
+
+ status = ixNpeDlNpeMgrUninit();
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlUnload : status = %d\n",
+ status);
+ return status;
+}
+
+/*
+ * Function definition: ixNpeDlStatsShow
+ */
+PUBLIC void
+ixNpeDlStatsShow (void)
+{
+ ixOsalLog (IX_OSAL_LOG_LVL_USER,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "\nixNpeDlStatsShow:\n"
+ "\tDownloads Attempted by user: %u\n"
+ "\tSuccessful Downloads: %u\n"
+ "\tFailed Downloads (due to Critical Error): %u\n\n",
+ ixNpeDlStats.attemptedDownloads,
+ ixNpeDlStats.successfulDownloads,
+ ixNpeDlStats.criticalFailDownloads,
+ 0,0,0);
+
+ ixNpeDlImageMgrStatsShow ();
+ ixNpeDlNpeMgrStatsShow ();
+}
+
+/*
+ * Function definition: ixNpeDlStatsReset
+ */
+PUBLIC void
+ixNpeDlStatsReset (void)
+{
+ ixNpeDlStats.attemptedDownloads = 0;
+ ixNpeDlStats.successfulDownloads = 0;
+ ixNpeDlStats.criticalFailDownloads = 0;
+
+ ixNpeDlImageMgrStatsReset ();
+ ixNpeDlNpeMgrStatsReset ();
+}
+
+/*
+ * Function definition: ixNpeDlNpeInitAndStartInternal
+ */
+PRIVATE IX_STATUS
+ixNpeDlNpeInitAndStartInternal (UINT32 *imageLibrary,
+ UINT32 imageId)
+{
+ UINT32 imageSize;
+ UINT32 *imageCodePtr = NULL;
+ IX_STATUS status;
+ IxNpeDlNpeId npeId = IX_NPEDL_NPEID_FROM_IMAGEID_GET(imageId);
+ IxFeatureCtrlDeviceId deviceId = IX_NPEDL_DEVICEID_FROM_IMAGEID_GET(imageId);
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlNpeInitAndStartInternal\n");
+
+ ixNpeDlStats.attemptedDownloads++;
+
+ /* Check input parameter device correctness */
+ if ((deviceId >= IX_FEATURE_CTRL_DEVICE_TYPE_MAX) ||
+ (deviceId < IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X))
+ {
+ status = IX_NPEDL_PARAM_ERR;
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
+ "invalid parameter\n");
+ } /* End valid device id checking */
+
+ /* Check input parameters */
+ else if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
+ {
+ status = IX_NPEDL_PARAM_ERR;
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
+ "invalid parameter\n");
+ }
+
+ else
+ {
+ /* Ensure initialisation has been completed */
+ ixNpeDlNpeMgrInit();
+
+ /* Checking if image being loaded is meant for device that is running.
+ * Image is forward compatible. i.e Image built for IXP42X should run
+ * on IXP46X but not vice versa.*/
+ if (deviceId > (ixFeatureCtrlDeviceRead() & IX_FEATURE_CTRL_DEVICE_TYPE_MASK))
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
+ "Device type mismatch. NPE Image not "
+ "meant for device in use \n");
+ return IX_NPEDL_DEVICE_ERR;
+ }/* if statement - matching image device and current device */
+
+ /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
+ if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+ (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+ || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+ {
+ if (npeId == IX_NPEDL_NPEID_NPEA)
+ {
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED)
+ {
+ IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
+ " not exist\n");
+ return IX_SUCCESS;
+ }
+ } /* end of if(npeId) */
+ else if (npeId == IX_NPEDL_NPEID_NPEB)
+ {
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED)
+ {
+ IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified"
+ " does not exist\n");
+ return IX_SUCCESS;
+ }
+ } /* end of elseif(npeId) */
+ else if (npeId == IX_NPEDL_NPEID_NPEC)
+ {
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
+ IX_FEATURE_CTRL_COMPONENT_DISABLED)
+ {
+ IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified"
+ " does not exist\n");
+ return IX_SUCCESS;
+ }
+ } /* end of elseif(npeId) */
+ } /* end of if not IXP42X-A0 Silicon */
+
+ /* stop and reset the NPE */
+ status = ixNpeDlNpeStopAndReset (npeId);
+ if (IX_SUCCESS != status)
+ {
+ IX_NPEDL_ERROR_REPORT ("Failed to stop and reset NPE\n");
+ return status;
+ }
+
+ /* Locate image */
+ status = ixNpeDlImageMgrImageFind (imageLibrary, imageId,
+ &imageCodePtr, &imageSize);
+ if (IX_SUCCESS == status)
+ {
+ /*
+ * If download was successful, store image Id in list of
+ * currently loaded images. If a critical error occured
+ * during download, record that the NPE has an invalid image
+ */
+ status = ixNpeDlNpeMgrImageLoad (npeId, imageCodePtr, TRUE);
+ if (IX_SUCCESS == status)
+ {
+ ixNpeDlNpeState[npeId].validImage = TRUE;
+ ixNpeDlStats.successfulDownloads++;
+
+ status = ixNpeDlNpeExecutionStart (npeId);
+ }
+ else if ((status == IX_NPEDL_CRITICAL_NPE_ERR) ||
+ (status == IX_NPEDL_CRITICAL_MICROCODE_ERR))
+ {
+ ixNpeDlNpeState[npeId].validImage = FALSE;
+ ixNpeDlStats.criticalFailDownloads++;
+ }
+
+ /* NOTE - The following section of code is here to support
+ * a deprecated function ixNpeDlLoadedImageGet(). When that
+ * function is removed from the API, this code should be revised.
+ */
+ ixNpeDlNpeState[npeId].imageId.npeId = npeId;
+ ixNpeDlNpeState[npeId].imageId.functionalityId =
+ IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId);
+ ixNpeDlNpeState[npeId].imageId.major =
+ IX_NPEDL_MAJOR_FROM_IMAGEID_GET(imageId);
+ ixNpeDlNpeState[npeId].imageId.minor =
+ IX_NPEDL_MINOR_FROM_IMAGEID_GET(imageId);
+ } /* end of if(IX_SUCCESS) */ /* condition: image located successfully in microcode image */
+ } /* end of if-else(npeId-deviceId) */ /* condition: parameter checks ok */
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlNpeInitAndStartInternal : "
+ "status = %d\n", status);
+ return status;
+}
+
+/*
+ * Function definition: ixNpeDlCustomImageNpeInitAndStart
+ */
+PUBLIC IX_STATUS
+ixNpeDlCustomImageNpeInitAndStart (UINT32 *imageLibrary,
+ UINT32 imageId)
+{
+ IX_STATUS status;
+
+ if (imageLibrary == NULL)
+ {
+ status = IX_NPEDL_PARAM_ERR;
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlCustomImageNpeInitAndStart "
+ "- invalid parameter\n");
+ }
+ else
+ {
+ status = ixNpeDlNpeInitAndStartInternal (imageLibrary, imageId);
+ } /* end of if-else(imageLibrary) */
+
+ return status;
+}
+
+/*
+ * Function definition: ixNpeDlNpeInitAndStart
+ */
+PUBLIC IX_STATUS
+ixNpeDlNpeInitAndStart (UINT32 imageId)
+{
+ return ixNpeDlNpeInitAndStartInternal (NULL, imageId);
+}
+
+/*
+ * Function definition: ixNpeDlLoadedImageFunctionalityGet
+ */
+PUBLIC IX_STATUS
+ixNpeDlLoadedImageFunctionalityGet (IxNpeDlNpeId npeId,
+ UINT8 *functionalityId)
+{
+ /* Check input parameters */
+ if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageFunctionalityGet "
+ "- invalid parameter\n");
+ return IX_NPEDL_PARAM_ERR;
+ }
+ if (functionalityId == NULL)
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageFunctionalityGet "
+ "- invalid parameter\n");
+ return IX_NPEDL_PARAM_ERR;
+ }
+
+ if (ixNpeDlNpeState[npeId].validImage)
+ {
+ *functionalityId = ixNpeDlNpeState[npeId].imageId.functionalityId;
+ return IX_SUCCESS;
+ }
+ else
+ {
+ return IX_FAIL;
+ }
+}
diff --git a/cpu/ixp/npe/IxNpeDlImageMgr.c b/cpu/ixp/npe/IxNpeDlImageMgr.c
new file mode 100644
index 0000000..e05c228
--- /dev/null
+++ b/cpu/ixp/npe/IxNpeDlImageMgr.c
@@ -0,0 +1,675 @@
+/**
+ * @file IxNpeDlImageMgr.c
+ *
+ * @author Intel Corporation
+ * @date 09 January 2002
+ *
+ * @brief This file contains the implementation of the private API for the
+ * IXP425 NPE Downloader ImageMgr module
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+
+/*
+ * Put the system defined include files required.
+ */
+#include "IxOsal.h"
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxNpeDlImageMgr_p.h"
+#include "IxNpeDlMacros_p.h"
+
+/*
+ * define the flag which toggles the firmare inclusion
+ */
+#define IX_NPE_MICROCODE_FIRMWARE_INCLUDED 1
+#include "IxNpeMicrocode.h"
+
+/*
+ * Indicates the start of an NPE Image, in new NPE Image Library format.
+ * 2 consecutive occurances indicates the end of the NPE Image Library
+ */
+#define NPE_IMAGE_MARKER 0xfeedf00d
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/*
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+typedef struct
+{
+ UINT32 size;
+ UINT32 offset;
+ UINT32 id;
+} IxNpeDlImageMgrImageEntry;
+
+/*
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+typedef union
+{
+ IxNpeDlImageMgrImageEntry image;
+ UINT32 eohMarker;
+} IxNpeDlImageMgrHeaderEntry;
+
+/*
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+typedef struct
+{
+ UINT32 signature;
+ /* 1st entry in the header (there may be more than one) */
+ IxNpeDlImageMgrHeaderEntry entry[1];
+} IxNpeDlImageMgrImageLibraryHeader;
+
+
+/*
+ * NPE Image Header definition, used in new NPE Image Library format
+ */
+typedef struct
+{
+ UINT32 marker;
+ UINT32 id;
+ UINT32 size;
+} IxNpeDlImageMgrImageHeader;
+
+/* module statistics counters */
+typedef struct
+{
+ UINT32 invalidSignature;
+ UINT32 imageIdListOverflow;
+ UINT32 imageIdNotFound;
+} IxNpeDlImageMgrStats;
+
+
+/*
+ * Variable declarations global to this file only. Externs are followed by
+ * static variables.
+ */
+static IxNpeDlImageMgrStats ixNpeDlImageMgrStats;
+
+/* default image */
+#ifdef IX_NPEDL_READ_MICROCODE_FROM_FILE
+static UINT32 *IxNpeMicroCodeImageLibrary = NULL; /* Gets set to proper value at runtime */
+#else
+static UINT32 *IxNpeMicroCodeImageLibrary = (UINT32 *)IxNpeMicrocode_array;
+#endif
+
+
+/*
+ * static function prototypes.
+ */
+PRIVATE BOOL
+ixNpeDlImageMgrSignatureCheck (UINT32 *microCodeImageLibrary);
+
+PRIVATE void
+ixNpeDlImageMgrImageIdFormat (UINT32 rawImageId, IxNpeDlImageId *imageId);
+
+PRIVATE BOOL
+ixNpeDlImageMgrImageIdCompare (IxNpeDlImageId *imageIdA,
+ IxNpeDlImageId *imageIdB);
+
+PRIVATE BOOL
+ixNpeDlImageMgrNpeFunctionIdCompare (IxNpeDlImageId *imageIdA,
+ IxNpeDlImageId *imageIdB);
+
+PRIVATE IX_STATUS
+ixNpeDlImageMgrImageFind_legacy (UINT32 *imageLibrary,
+ UINT32 imageId,
+ UINT32 **imagePtr,
+ UINT32 *imageSize);
+
+/*
+ * Function definition: ixNpeDlImageMgrMicrocodeImageLibraryOverride
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+IX_STATUS
+ixNpeDlImageMgrMicrocodeImageLibraryOverride (
+ UINT32 *clientImageLibrary)
+{
+ IX_STATUS status = IX_SUCCESS;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlImageMgrMicrocodeImageLibraryOverride\n");
+
+ if (ixNpeDlImageMgrSignatureCheck (clientImageLibrary))
+ {
+ IxNpeMicroCodeImageLibrary = clientImageLibrary;
+ }
+ else
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrMicrocodeImageLibraryOverride: "
+ "Client-supplied image has invalid signature\n");
+ status = IX_FAIL;
+ }
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlImageMgrMicrocodeImageLibraryOverride: status = %d\n",
+ status);
+ return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageListExtract
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+IX_STATUS
+ixNpeDlImageMgrImageListExtract (
+ IxNpeDlImageId *imageListPtr,
+ UINT32 *numImages)
+{
+ UINT32 rawImageId;
+ IxNpeDlImageId formattedImageId;
+ IX_STATUS status = IX_SUCCESS;
+ UINT32 imageCount = 0;
+ IxNpeDlImageMgrImageLibraryHeader *header;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlImageMgrImageListExtract\n");
+
+ header = (IxNpeDlImageMgrImageLibraryHeader *) IxNpeMicroCodeImageLibrary;
+
+ if (ixNpeDlImageMgrSignatureCheck (IxNpeMicroCodeImageLibrary))
+ {
+ /* for each image entry in the image header ... */
+ while (header->entry[imageCount].eohMarker !=
+ IX_NPEDL_IMAGEMGR_END_OF_HEADER)
+ {
+ /*
+ * if the image list container from calling function has capacity,
+ * add the image id to the list
+ */
+ if ((imageListPtr != NULL) && (imageCount < *numImages))
+ {
+ rawImageId = header->entry[imageCount].image.id;
+ ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
+ imageListPtr[imageCount] = formattedImageId;
+ }
+ /* imageCount reflects no. of image entries in image library header */
+ imageCount++;
+ }
+
+ /*
+ * if image list container from calling function was too small to
+ * contain all image ids in the header, set return status to FAIL
+ */
+ if ((imageListPtr != NULL) && (imageCount > *numImages))
+ {
+ status = IX_FAIL;
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageListExtract: "
+ "number of Ids found exceeds list capacity\n");
+ ixNpeDlImageMgrStats.imageIdListOverflow++;
+ }
+ /* return number of image ids found in image library header */
+ *numImages = imageCount;
+ }
+ else
+ {
+ status = IX_FAIL;
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageListExtract: "
+ "invalid signature in image\n");
+ }
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlImageMgrImageListExtract: status = %d\n",
+ status);
+ return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageLocate
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+IX_STATUS
+ixNpeDlImageMgrImageLocate (
+ IxNpeDlImageId *imageId,
+ UINT32 **imagePtr,
+ UINT32 *imageSize)
+{
+ UINT32 imageOffset;
+ UINT32 rawImageId;
+ IxNpeDlImageId formattedImageId;
+ /* used to index image entries in image library header */
+ UINT32 imageCount = 0;
+ IX_STATUS status = IX_FAIL;
+ IxNpeDlImageMgrImageLibraryHeader *header;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlImageMgrImageLocate\n");
+
+ header = (IxNpeDlImageMgrImageLibraryHeader *) IxNpeMicroCodeImageLibrary;
+
+ if (ixNpeDlImageMgrSignatureCheck (IxNpeMicroCodeImageLibrary))
+ {
+ /* for each image entry in the image library header ... */
+ while (header->entry[imageCount].eohMarker !=
+ IX_NPEDL_IMAGEMGR_END_OF_HEADER)
+ {
+ rawImageId = header->entry[imageCount].image.id;
+ ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
+ /* if a match for imageId is found in the image library header... */
+ if (ixNpeDlImageMgrImageIdCompare (imageId, &formattedImageId))
+ {
+ /*
+ * get pointer to the image in the image library using offset from
+ * 1st word in image library
+ */
+ imageOffset = header->entry[imageCount].image.offset;
+ *imagePtr = &IxNpeMicroCodeImageLibrary[imageOffset];
+ /* get the image size */
+ *imageSize = header->entry[imageCount].image.size;
+ status = IX_SUCCESS;
+ break;
+ }
+ imageCount++;
+ }
+ if (status != IX_SUCCESS)
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageLocate: "
+ "imageId not found in image library header\n");
+ ixNpeDlImageMgrStats.imageIdNotFound++;
+ }
+ }
+ else
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageLocate: "
+ "invalid signature in image library\n");
+ }
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlImageMgrImageLocate: status = %d\n", status);
+ return status;
+}
+
+/*
+ * Function definition: ixNpeDlImageMgrLatestImageExtract
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+IX_STATUS
+ixNpeDlImageMgrLatestImageExtract (IxNpeDlImageId *imageId)
+{
+ UINT32 imageCount = 0;
+ UINT32 rawImageId;
+ IxNpeDlImageId formattedImageId;
+ IX_STATUS status = IX_FAIL;
+ IxNpeDlImageMgrImageLibraryHeader *header;
+
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlImageMgrLatestImageExtract\n");
+
+ header = (IxNpeDlImageMgrImageLibraryHeader *) IxNpeMicroCodeImageLibrary;
+
+ if (ixNpeDlImageMgrSignatureCheck (IxNpeMicroCodeImageLibrary))
+ {
+ /* for each image entry in the image library header ... */
+ while (header->entry[imageCount].eohMarker !=
+ IX_NPEDL_IMAGEMGR_END_OF_HEADER)
+ {
+ rawImageId = header->entry[imageCount].image.id;
+ ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
+ /*
+ * if a match for the npe Id and functionality Id of the imageId is
+ * found in the image library header...
+ */
+ if(ixNpeDlImageMgrNpeFunctionIdCompare(imageId, &formattedImageId))
+ {
+ if(imageId->major <= formattedImageId.major)
+ {
+ if(imageId->minor < formattedImageId.minor)
+ {
+ imageId->minor = formattedImageId.minor;
+ }
+ imageId->major = formattedImageId.major;
+ }
+ status = IX_SUCCESS;
+ }
+ imageCount++;
+ }
+ if (status != IX_SUCCESS)
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrLatestImageExtract: "
+ "imageId not found in image library header\n");
+ ixNpeDlImageMgrStats.imageIdNotFound++;
+ }
+ }
+ else
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrLatestImageGet: "
+ "invalid signature in image library\n");
+ }
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlImageMgrLatestImageGet: status = %d\n", status);
+ return status;
+}
+
+/*
+ * Function definition: ixNpeDlImageMgrSignatureCheck
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE BOOL
+ixNpeDlImageMgrSignatureCheck (UINT32 *microCodeImageLibrary)
+{
+ IxNpeDlImageMgrImageLibraryHeader *header =
+ (IxNpeDlImageMgrImageLibraryHeader *) microCodeImageLibrary;
+ BOOL result = TRUE;
+
+ if (header->signature != IX_NPEDL_IMAGEMGR_SIGNATURE)
+ {
+ result = FALSE;
+ ixNpeDlImageMgrStats.invalidSignature++;
+ }
+
+ return result;
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageIdFormat
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE void
+ixNpeDlImageMgrImageIdFormat (
+ UINT32 rawImageId,
+ IxNpeDlImageId *imageId)
+{
+ imageId->npeId = (rawImageId >>
+ IX_NPEDL_IMAGEID_NPEID_OFFSET) &
+ IX_NPEDL_NPEIMAGE_FIELD_MASK;
+ imageId->functionalityId = (rawImageId >>
+ IX_NPEDL_IMAGEID_FUNCTIONID_OFFSET) &
+ IX_NPEDL_NPEIMAGE_FIELD_MASK;
+ imageId->major = (rawImageId >>
+ IX_NPEDL_IMAGEID_MAJOR_OFFSET) &
+ IX_NPEDL_NPEIMAGE_FIELD_MASK;
+ imageId->minor = (rawImageId >>
+ IX_NPEDL_IMAGEID_MINOR_OFFSET) &
+ IX_NPEDL_NPEIMAGE_FIELD_MASK;
+
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageIdCompare
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE BOOL
+ixNpeDlImageMgrImageIdCompare (
+ IxNpeDlImageId *imageIdA,
+ IxNpeDlImageId *imageIdB)
+{
+ if ((imageIdA->npeId == imageIdB->npeId) &&
+ (imageIdA->functionalityId == imageIdB->functionalityId) &&
+ (imageIdA->major == imageIdB->major) &&
+ (imageIdA->minor == imageIdB->minor))
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+/*
+ * Function definition: ixNpeDlImageMgrNpeFunctionIdCompare
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE BOOL
+ixNpeDlImageMgrNpeFunctionIdCompare (
+ IxNpeDlImageId *imageIdA,
+ IxNpeDlImageId *imageIdB)
+{
+ if ((imageIdA->npeId == imageIdB->npeId) &&
+ (imageIdA->functionalityId == imageIdB->functionalityId))
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrStatsShow
+ */
+void
+ixNpeDlImageMgrStatsShow (void)
+{
+ ixOsalLog (IX_OSAL_LOG_LVL_USER,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "\nixNpeDlImageMgrStatsShow:\n"
+ "\tInvalid Image Signatures: %u\n"
+ "\tImage Id List capacity too small: %u\n"
+ "\tImage Id not found: %u\n\n",
+ ixNpeDlImageMgrStats.invalidSignature,
+ ixNpeDlImageMgrStats.imageIdListOverflow,
+ ixNpeDlImageMgrStats.imageIdNotFound,
+ 0,0,0);
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrStatsReset
+ */
+void
+ixNpeDlImageMgrStatsReset (void)
+{
+ ixNpeDlImageMgrStats.invalidSignature = 0;
+ ixNpeDlImageMgrStats.imageIdListOverflow = 0;
+ ixNpeDlImageMgrStats.imageIdNotFound = 0;
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageFind_legacy
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE IX_STATUS
+ixNpeDlImageMgrImageFind_legacy (
+ UINT32 *imageLibrary,
+ UINT32 imageId,
+ UINT32 **imagePtr,
+ UINT32 *imageSize)
+{
+ UINT32 imageOffset;
+ /* used to index image entries in image library header */
+ UINT32 imageCount = 0;
+ IX_STATUS status = IX_FAIL;
+ IxNpeDlImageMgrImageLibraryHeader *header;
+ BOOL imageFound = FALSE;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlImageMgrImageFind\n");
+
+
+ /* If user didn't specify a library to use, use the default
+ * one from IxNpeMicrocode.h
+ */
+ if (imageLibrary == NULL)
+ {
+ imageLibrary = IxNpeMicroCodeImageLibrary;
+ }
+
+ if (ixNpeDlImageMgrSignatureCheck (imageLibrary))
+ {
+ header = (IxNpeDlImageMgrImageLibraryHeader *) imageLibrary;
+
+ /* for each image entry in the image library header ... */
+ while ((header->entry[imageCount].eohMarker !=
+ IX_NPEDL_IMAGEMGR_END_OF_HEADER) && !(imageFound))
+ {
+ /* if a match for imageId is found in the image library header... */
+ if (imageId == header->entry[imageCount].image.id)
+ {
+ /*
+ * get pointer to the image in the image library using offset from
+ * 1st word in image library
+ */
+ imageOffset = header->entry[imageCount].image.offset;
+ *imagePtr = &imageLibrary[imageOffset];
+ /* get the image size */
+ *imageSize = header->entry[imageCount].image.size;
+ status = IX_SUCCESS;
+ imageFound = TRUE;
+ }
+ imageCount++;
+ }
+ if (status != IX_SUCCESS)
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
+ "imageId not found in image library header\n");
+ ixNpeDlImageMgrStats.imageIdNotFound++;
+ }
+ }
+ else
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
+ "invalid signature in image library\n");
+ }
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlImageMgrImageFind: status = %d\n", status);
+ return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageFind
+ */
+IX_STATUS
+ixNpeDlImageMgrImageFind (
+ UINT32 *imageLibrary,
+ UINT32 imageId,
+ UINT32 **imagePtr,
+ UINT32 *imageSize)
+{
+ IxNpeDlImageMgrImageHeader *image;
+ UINT32 offset = 0;
+
+ /* If user didn't specify a library to use, use the default
+ * one from IxNpeMicrocode.h
+ */
+ if (imageLibrary == NULL)
+ {
+#ifdef IX_NPEDL_READ_MICROCODE_FROM_FILE
+ if (ixNpeMicrocode_binaryArray == NULL)
+ {
+ printk (KERN_ERR "ixp400.o: ERROR, no Microcode found in memory\n");
+ return IX_FAIL;
+ }
+ else
+ {
+ imageLibrary = ixNpeMicrocode_binaryArray;
+ }
+#else
+ imageLibrary = IxNpeMicroCodeImageLibrary;
+#endif /* IX_NPEDL_READ_MICROCODE_FROM_FILE */
+ }
+
+ /* For backward's compatibility with previous image format */
+ if (ixNpeDlImageMgrSignatureCheck(imageLibrary))
+ {
+ return ixNpeDlImageMgrImageFind_legacy(imageLibrary,
+ imageId,
+ imagePtr,
+ imageSize);
+ }
+
+ while (*(imageLibrary+offset) == NPE_IMAGE_MARKER)
+ {
+ image = (IxNpeDlImageMgrImageHeader *)(imageLibrary+offset);
+ offset += sizeof(IxNpeDlImageMgrImageHeader)/sizeof(UINT32);
+
+ if (image->id == imageId)
+ {
+ *imagePtr = imageLibrary + offset;
+ *imageSize = image->size;
+ return IX_SUCCESS;
+ }
+ /* 2 consecutive NPE_IMAGE_MARKER's indicates end of library */
+ else if (image->id == NPE_IMAGE_MARKER)
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
+ "imageId not found in image library header\n");
+ ixNpeDlImageMgrStats.imageIdNotFound++;
+ /* reached end of library, image not found */
+ return IX_FAIL;
+ }
+ offset += image->size;
+ }
+
+ /* If we get here, our image library may be corrupted */
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
+ "image library format may be invalid or corrupted\n");
+ return IX_FAIL;
+}
+
diff --git a/cpu/ixp/npe/IxNpeDlNpeMgr.c b/cpu/ixp/npe/IxNpeDlNpeMgr.c
new file mode 100644
index 0000000..f5a4c5f
--- /dev/null
+++ b/cpu/ixp/npe/IxNpeDlNpeMgr.c
@@ -0,0 +1,936 @@
+/**
+ * @file IxNpeDlNpeMgr.c
+ *
+ * @author Intel Corporation
+ * @date 09 January 2002
+ *
+ * @brief This file contains the implementation of the private API for the
+ * IXP425 NPE Downloader NpeMgr module
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+
+/*
+ * Put the user defined include files required.
+ */
+
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxOsal.h"
+#include "IxNpeDl.h"
+#include "IxNpeDlNpeMgr_p.h"
+#include "IxNpeDlNpeMgrUtils_p.h"
+#include "IxNpeDlNpeMgrEcRegisters_p.h"
+#include "IxNpeDlMacros_p.h"
+#include "IxFeatureCtrl.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+#define IX_NPEDL_BYTES_PER_WORD 4
+
+/* used to read download map from version in microcode image */
+#define IX_NPEDL_BLOCK_TYPE_INSTRUCTION 0x00000000
+#define IX_NPEDL_BLOCK_TYPE_DATA 0x00000001
+#define IX_NPEDL_BLOCK_TYPE_STATE 0x00000002
+#define IX_NPEDL_END_OF_DOWNLOAD_MAP 0x0000000F
+
+/*
+ * masks used to extract address info from State information context
+ * register addresses as read from microcode image
+ */
+#define IX_NPEDL_MASK_STATE_ADDR_CTXT_REG 0x0000000F
+#define IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM 0x000000F0
+
+/* LSB offset of Context Number field in State-Info Context Address */
+#define IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM 4
+
+/* size (in words) of single State Information entry (ctxt reg address|data) */
+#define IX_NPEDL_STATE_INFO_ENTRY_SIZE 2
+
+
+ #define IX_NPEDL_RESET_NPE_PARITY 0x0800
+ #define IX_NPEDL_PARITY_BIT_MASK 0x3F00FFFF
+ #define IX_NPEDL_CONFIG_CTRL_REG_MASK 0x3F3FFFFF
+
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+typedef struct
+{
+ UINT32 type;
+ UINT32 offset;
+} IxNpeDlNpeMgrDownloadMapBlockEntry;
+
+typedef union
+{
+ IxNpeDlNpeMgrDownloadMapBlockEntry block;
+ UINT32 eodmMarker;
+} IxNpeDlNpeMgrDownloadMapEntry;
+
+typedef struct
+{
+ /* 1st entry in the download map (there may be more than one) */
+ IxNpeDlNpeMgrDownloadMapEntry entry[1];
+} IxNpeDlNpeMgrDownloadMap;
+
+
+/* used to access an instruction or data block in a microcode image */
+typedef struct
+{
+ UINT32 npeMemAddress;
+ UINT32 size;
+ UINT32 data[1];
+} IxNpeDlNpeMgrCodeBlock;
+
+/* used to access each Context Reg entry state-information block */
+typedef struct
+{
+ UINT32 addressInfo;
+ UINT32 value;
+} IxNpeDlNpeMgrStateInfoCtxtRegEntry;
+
+/* used to access a state-information block in a microcode image */
+typedef struct
+{
+ UINT32 size;
+ IxNpeDlNpeMgrStateInfoCtxtRegEntry ctxtRegEntry[1];
+} IxNpeDlNpeMgrStateInfoBlock;
+
+/* used to store some useful NPE information for easy access */
+typedef struct
+{
+ UINT32 baseAddress;
+ UINT32 insMemSize;
+ UINT32 dataMemSize;
+} IxNpeDlNpeInfo;
+
+/* used to distinguish instruction and data memory operations */
+typedef enum
+{
+ IX_NPEDL_MEM_TYPE_INSTRUCTION = 0,
+ IX_NPEDL_MEM_TYPE_DATA
+} IxNpeDlNpeMemType;
+
+/* used to hold a reset value for a particular ECS register */
+typedef struct
+{
+ UINT32 regAddr;
+ UINT32 regResetVal;
+} IxNpeDlEcsRegResetValue;
+
+/* prototype of function to write either Instruction or Data memory */
+typedef IX_STATUS (*IxNpeDlNpeMgrMemWrite) (UINT32 npeBaseAddress,
+ UINT32 npeMemAddress,
+ UINT32 npeMemData,
+ BOOL verify);
+
+/* module statistics counters */
+typedef struct
+{
+ UINT32 instructionBlocksLoaded;
+ UINT32 dataBlocksLoaded;
+ UINT32 stateInfoBlocksLoaded;
+ UINT32 criticalNpeErrors;
+ UINT32 criticalMicrocodeErrors;
+ UINT32 npeStarts;
+ UINT32 npeStops;
+ UINT32 npeResets;
+} IxNpeDlNpeMgrStats;
+
+
+/*
+ * Variable declarations global to this file only. Externs are followed by
+ * static variables.
+ */
+static IxNpeDlNpeInfo ixNpeDlNpeInfo[] =
+{
+ {
+ 0,
+ IX_NPEDL_INS_MEMSIZE_WORDS_NPEA,
+ IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA
+ },
+ {
+ 0,
+ IX_NPEDL_INS_MEMSIZE_WORDS_NPEB,
+ IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB
+ },
+ {
+ 0,
+ IX_NPEDL_INS_MEMSIZE_WORDS_NPEC,
+ IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC
+ }
+};
+
+/* contains Reset values for Context Store Registers */
+static UINT32 ixNpeDlCtxtRegResetValues[] =
+{
+ IX_NPEDL_CTXT_REG_RESET_STEVT,
+ IX_NPEDL_CTXT_REG_RESET_STARTPC,
+ IX_NPEDL_CTXT_REG_RESET_REGMAP,
+ IX_NPEDL_CTXT_REG_RESET_CINDEX,
+};
+
+/* contains Reset values for Context Store Registers */
+static IxNpeDlEcsRegResetValue ixNpeDlEcsRegResetValues[] =
+{
+ {IX_NPEDL_ECS_BG_CTXT_REG_0, IX_NPEDL_ECS_BG_CTXT_REG_0_RESET},
+ {IX_NPEDL_ECS_BG_CTXT_REG_1, IX_NPEDL_ECS_BG_CTXT_REG_1_RESET},
+ {IX_NPEDL_ECS_BG_CTXT_REG_2, IX_NPEDL_ECS_BG_CTXT_REG_2_RESET},
+ {IX_NPEDL_ECS_PRI_1_CTXT_REG_0, IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET},
+ {IX_NPEDL_ECS_PRI_1_CTXT_REG_1, IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET},
+ {IX_NPEDL_ECS_PRI_1_CTXT_REG_2, IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET},
+ {IX_NPEDL_ECS_PRI_2_CTXT_REG_0, IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET},
+ {IX_NPEDL_ECS_PRI_2_CTXT_REG_1, IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET},
+ {IX_NPEDL_ECS_PRI_2_CTXT_REG_2, IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET},
+ {IX_NPEDL_ECS_DBG_CTXT_REG_0, IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET},
+ {IX_NPEDL_ECS_DBG_CTXT_REG_1, IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET},
+ {IX_NPEDL_ECS_DBG_CTXT_REG_2, IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET},
+ {IX_NPEDL_ECS_INSTRUCT_REG, IX_NPEDL_ECS_INSTRUCT_REG_RESET}
+};
+
+static IxNpeDlNpeMgrStats ixNpeDlNpeMgrStats;
+
+/* Set when NPE register memory has been mapped */
+static BOOL ixNpeDlMemInitialised = FALSE;
+
+
+/*
+ * static function prototypes.
+ */
+PRIVATE IX_STATUS
+ixNpeDlNpeMgrMemLoad (IxNpeDlNpeId npeId, UINT32 npeBaseAddress,
+ IxNpeDlNpeMgrCodeBlock *codeBlockPtr,
+ BOOL verify, IxNpeDlNpeMemType npeMemType);
+PRIVATE IX_STATUS
+ixNpeDlNpeMgrStateInfoLoad (UINT32 npeBaseAddress,
+ IxNpeDlNpeMgrStateInfoBlock *codeBlockPtr,
+ BOOL verify);
+PRIVATE BOOL
+ixNpeDlNpeMgrBitsSetCheck (UINT32 npeBaseAddress, UINT32 regOffset,
+ UINT32 expectedBitsSet);
+
+PRIVATE UINT32
+ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId);
+
+/*
+ * Function definition: ixNpeDlNpeMgrBaseAddressGet
+ */
+PRIVATE UINT32
+ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId)
+{
+ IX_OSAL_ASSERT (ixNpeDlMemInitialised);
+ return ixNpeDlNpeInfo[npeId].baseAddress;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrInit
+ */
+void
+ixNpeDlNpeMgrInit (void)
+{
+ /* Only map the memory once */
+ if (!ixNpeDlMemInitialised)
+ {
+ UINT32 virtAddr;
+
+ /* map the register memory for NPE-A */
+ virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEA,
+ IX_OSAL_IXP400_NPEA_MAP_SIZE);
+ IX_OSAL_ASSERT(virtAddr);
+ ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = virtAddr;
+
+ /* map the register memory for NPE-B */
+ virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEB,
+ IX_OSAL_IXP400_NPEB_MAP_SIZE);
+ IX_OSAL_ASSERT(virtAddr);
+ ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = virtAddr;
+
+ /* map the register memory for NPE-C */
+ virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEC,
+ IX_OSAL_IXP400_NPEC_MAP_SIZE);
+ IX_OSAL_ASSERT(virtAddr);
+ ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = virtAddr;
+
+ ixNpeDlMemInitialised = TRUE;
+ }
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrUninit
+ */
+IX_STATUS
+ixNpeDlNpeMgrUninit (void)
+{
+ if (!ixNpeDlMemInitialised)
+ {
+ return IX_FAIL;
+ }
+
+ IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress);
+ IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress);
+ IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress);
+
+ ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = 0;
+ ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = 0;
+ ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = 0;
+
+ ixNpeDlMemInitialised = FALSE;
+
+ return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeDlNpeMgrImageLoad
+ */
+IX_STATUS
+ixNpeDlNpeMgrImageLoad (
+ IxNpeDlNpeId npeId,
+ UINT32 *imageCodePtr,
+ BOOL verify)
+{
+ UINT32 npeBaseAddress;
+ IxNpeDlNpeMgrDownloadMap *downloadMap;
+ UINT32 *blockPtr;
+ UINT32 mapIndex = 0;
+ IX_STATUS status = IX_SUCCESS;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlNpeMgrImageLoad\n");
+
+ /* get base memory address of NPE from npeId */
+ npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
+
+ /* check execution status of NPE to verify NPE Stop was successful */
+ if (!ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL,
+ IX_NPEDL_EXCTL_STATUS_STOP))
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageDownload - "
+ "NPE was not stopped before download\n");
+ status = IX_FAIL;
+ }
+ else
+ {
+ /*
+ * Read Download Map, checking each block type and calling
+ * appropriate function to perform download
+ */
+ downloadMap = (IxNpeDlNpeMgrDownloadMap *) imageCodePtr;
+ while ((downloadMap->entry[mapIndex].eodmMarker !=
+ IX_NPEDL_END_OF_DOWNLOAD_MAP)
+ && (status == IX_SUCCESS))
+ {
+ /* calculate pointer to block to be downloaded */
+ blockPtr = imageCodePtr +
+ downloadMap->entry[mapIndex].block.offset;
+
+ switch (downloadMap->entry[mapIndex].block.type)
+ {
+ case IX_NPEDL_BLOCK_TYPE_INSTRUCTION:
+ status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress,
+ (IxNpeDlNpeMgrCodeBlock *)blockPtr,
+ verify,
+ IX_NPEDL_MEM_TYPE_INSTRUCTION);
+ break;
+ case IX_NPEDL_BLOCK_TYPE_DATA:
+ status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress,
+ (IxNpeDlNpeMgrCodeBlock *)blockPtr,
+ verify, IX_NPEDL_MEM_TYPE_DATA);
+ break;
+ case IX_NPEDL_BLOCK_TYPE_STATE:
+ status = ixNpeDlNpeMgrStateInfoLoad (npeBaseAddress,
+ (IxNpeDlNpeMgrStateInfoBlock *) blockPtr,
+ verify);
+ break;
+ default:
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageLoad: "
+ "unknown block type in download map\n");
+ status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
+ ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
+ break;
+ }
+ mapIndex++;
+ }/* loop: for each entry in download map, while status == SUCCESS */
+ }/* condition: NPE stopped before attempting download */
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlNpeMgrImageLoad : status = %d\n",
+ status);
+ return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrMemLoad
+ */
+PRIVATE IX_STATUS
+ixNpeDlNpeMgrMemLoad (
+ IxNpeDlNpeId npeId,
+ UINT32 npeBaseAddress,
+ IxNpeDlNpeMgrCodeBlock *blockPtr,
+ BOOL verify,
+ IxNpeDlNpeMemType npeMemType)
+{
+ UINT32 npeMemAddress;
+ UINT32 blockSize;
+ UINT32 memSize = 0;
+ IxNpeDlNpeMgrMemWrite memWriteFunc = NULL;
+ UINT32 localIndex = 0;
+ IX_STATUS status = IX_SUCCESS;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlNpeMgrMemLoad\n");
+
+ /*
+ * select NPE EXCTL reg read/write commands depending on memory
+ * type (instruction/data) to be accessed
+ */
+ if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION)
+ {
+ memSize = ixNpeDlNpeInfo[npeId].insMemSize;
+ memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrInsMemWrite;
+ }
+ else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA)
+ {
+ memSize = ixNpeDlNpeInfo[npeId].dataMemSize;
+ memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrDataMemWrite;
+ }
+
+ /*
+ * NPE memory is loaded contiguously from each block, so only address
+ * of 1st word in block is needed
+ */
+ npeMemAddress = blockPtr->npeMemAddress;
+ /* number of words of instruction/data microcode in block to download */
+ blockSize = blockPtr->size;
+ if ((npeMemAddress + blockSize) > memSize)
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: "
+ "Block size too big for NPE memory\n");
+ status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
+ ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
+ }
+ else
+ {
+ for (localIndex = 0; localIndex < blockSize; localIndex++)
+ {
+ status = memWriteFunc (npeBaseAddress, npeMemAddress,
+ blockPtr->data[localIndex], verify);
+
+ if (status != IX_SUCCESS)
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: "
+ "write to NPE memory failed\n");
+ status = IX_NPEDL_CRITICAL_NPE_ERR;
+ ixNpeDlNpeMgrStats.criticalNpeErrors++;
+ break; /* abort download */
+ }
+ /* increment target (word)address in NPE memory */
+ npeMemAddress++;
+ }
+ }/* condition: block size will fit in NPE memory */
+
+ if (status == IX_SUCCESS)
+ {
+ if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION)
+ {
+ ixNpeDlNpeMgrStats.instructionBlocksLoaded++;
+ }
+ else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA)
+ {
+ ixNpeDlNpeMgrStats.dataBlocksLoaded++;
+ }
+ }
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlNpeMgrMemLoad : status = %d\n", status);
+ return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrStateInfoLoad
+ */
+PRIVATE IX_STATUS
+ixNpeDlNpeMgrStateInfoLoad (
+ UINT32 npeBaseAddress,
+ IxNpeDlNpeMgrStateInfoBlock *blockPtr,
+ BOOL verify)
+{
+ UINT32 blockSize;
+ UINT32 ctxtRegAddrInfo;
+ UINT32 ctxtRegVal;
+ IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */
+ UINT32 ctxtNum; /* identifies Context number (0-16) */
+ UINT32 i;
+ IX_STATUS status = IX_SUCCESS;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlNpeMgrStateInfoLoad\n");
+
+ /* block size contains number of words of state-info in block */
+ blockSize = blockPtr->size;
+
+ ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress);
+
+ /* for each state-info context register entry in block */
+ for (i = 0; i < (blockSize/IX_NPEDL_STATE_INFO_ENTRY_SIZE); i++)
+ {
+ /* each state-info entry is 2 words (address, value) in length */
+ ctxtRegAddrInfo = (blockPtr->ctxtRegEntry[i]).addressInfo;
+ ctxtRegVal = (blockPtr->ctxtRegEntry[i]).value;
+
+ ctxtReg = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_REG);
+ ctxtNum = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM) >>
+ IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM;
+
+ /* error-check Context Register No. and Context Number values */
+ /* NOTE that there is no STEVT register for Context 0 */
+ if ((ctxtReg < 0) ||
+ (ctxtReg >= IX_NPEDL_CTXT_REG_MAX) ||
+ (ctxtNum > IX_NPEDL_CTXT_NUM_MAX) ||
+ ((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT)))
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: "
+ "invalid Context Register Address\n");
+ status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
+ ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
+ break; /* abort download */
+ }
+
+ status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum, ctxtReg,
+ ctxtRegVal, verify);
+ if (status != IX_SUCCESS)
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: "
+ "write of state-info to NPE failed\n");
+ status = IX_NPEDL_CRITICAL_NPE_ERR;
+ ixNpeDlNpeMgrStats.criticalNpeErrors++;
+ break; /* abort download */
+ }
+ }/* loop: for each context reg entry in State Info block */
+
+ ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress);
+
+ if (status == IX_SUCCESS)
+ {
+ ixNpeDlNpeMgrStats.stateInfoBlocksLoaded++;
+ }
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlNpeMgrStateInfoLoad : status = %d\n",
+ status);
+ return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrNpeReset
+ */
+IX_STATUS
+ixNpeDlNpeMgrNpeReset (
+ IxNpeDlNpeId npeId)
+{
+ UINT32 npeBaseAddress;
+ IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */
+ UINT32 ctxtNum; /* identifies Context number (0-16) */
+ UINT32 regAddr;
+ UINT32 regVal;
+ UINT32 localIndex;
+ UINT32 indexMax;
+ IX_STATUS status = IX_SUCCESS;
+ IxFeatureCtrlReg unitFuseReg;
+ UINT32 ixNpeConfigCtrlRegVal;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlNpeMgrNpeReset\n");
+
+ /* get base memory address of NPE from npeId */
+ npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
+
+ /* pre-store the NPE Config Control Register Value */
+ IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, &ixNpeConfigCtrlRegVal);
+
+ ixNpeConfigCtrlRegVal |= 0x3F000000;
+
+ /* disable the parity interrupt */
+ IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, (ixNpeConfigCtrlRegVal & IX_NPEDL_PARITY_BIT_MASK));
+
+ ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress);
+
+ /*
+ * clear the FIFOs
+ */
+ while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
+ IX_NPEDL_REG_OFFSET_WFIFO,
+ IX_NPEDL_MASK_WFIFO_VALID))
+ {
+ /* read from the Watch-point FIFO until empty */
+ IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WFIFO,
+ &regVal);
+ }
+
+ while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
+ IX_NPEDL_REG_OFFSET_STAT,
+ IX_NPEDL_MASK_STAT_OFNE))
+ {
+ /* read from the outFIFO until empty */
+ IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_FIFO,
+ &regVal);
+ }
+
+ while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
+ IX_NPEDL_REG_OFFSET_STAT,
+ IX_NPEDL_MASK_STAT_IFNE))
+ {
+ /*
+ * step execution of the NPE intruction to read inFIFO using
+ * the Debug Executing Context stack
+ */
+ status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress,
+ IX_NPEDL_INSTR_RD_FIFO, 0, 0);
+
+ if (IX_SUCCESS != status)
+ {
+ return status;
+ }
+
+ }
+
+ /*
+ * Reset the mailbox reg
+ */
+ /* ...from XScale side */
+ IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_MBST,
+ IX_NPEDL_REG_RESET_MBST);
+ /* ...from NPE side */
+ status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress,
+ IX_NPEDL_INSTR_RESET_MBOX, 0, 0);
+
+ if (IX_SUCCESS != status)
+ {
+ return status;
+ }
+
+ /*
+ * Reset the physical registers in the NPE register file:
+ * Note: no need to save/restore REGMAP for Context 0 here
+ * since all Context Store regs are reset in subsequent code
+ */
+ for (regAddr = 0;
+ (regAddr < IX_NPEDL_TOTAL_NUM_PHYS_REG) && (status != IX_FAIL);
+ regAddr++)
+ {
+ /* for each physical register in the NPE reg file, write 0 : */
+ status = ixNpeDlNpeMgrPhysicalRegWrite (npeBaseAddress, regAddr,
+ 0, TRUE);
+ if (status != IX_SUCCESS)
+ {
+ return status; /* abort reset */
+ }
+ }
+
+
+ /*
+ * Reset the context store:
+ */
+ for (ctxtNum = IX_NPEDL_CTXT_NUM_MIN;
+ ctxtNum <= IX_NPEDL_CTXT_NUM_MAX; ctxtNum++)
+ {
+ /* set each context's Context Store registers to reset values: */
+ for (ctxtReg = 0; ctxtReg < IX_NPEDL_CTXT_REG_MAX; ctxtReg++)
+ {
+ /* NOTE that there is no STEVT register for Context 0 */
+ if (!((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT)))
+ {
+ regVal = ixNpeDlCtxtRegResetValues[ctxtReg];
+ status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum,
+ ctxtReg, regVal, TRUE);
+ if (status != IX_SUCCESS)
+ {
+ return status; /* abort reset */
+ }
+ }
+ }
+ }
+
+ ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress);
+
+ /* write Reset values to Execution Context Stack registers */
+ indexMax = sizeof (ixNpeDlEcsRegResetValues) /
+ sizeof (IxNpeDlEcsRegResetValue);
+ for (localIndex = 0; localIndex < indexMax; localIndex++)
+ {
+ regAddr = ixNpeDlEcsRegResetValues[localIndex].regAddr;
+ regVal = ixNpeDlEcsRegResetValues[localIndex].regResetVal;
+ ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, regAddr, regVal);
+ }
+
+ /* clear the profile counter */
+ ixNpeDlNpeMgrCommandIssue (npeBaseAddress,
+ IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT);
+
+ /* clear registers EXCT, AP0, AP1, AP2 and AP3 */
+ for (regAddr = IX_NPEDL_REG_OFFSET_EXCT;
+ regAddr <= IX_NPEDL_REG_OFFSET_AP3;
+ regAddr += IX_NPEDL_BYTES_PER_WORD)
+ {
+ IX_NPEDL_REG_WRITE (npeBaseAddress, regAddr, 0);
+ }
+
+ /* Reset the Watch-count register */
+ IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, 0);
+
+ /*
+ * WR IXA00055043 - Remove IMEM Parity Introduced by NPE Reset Operation
+ */
+
+ /*
+ * Call the feature control API to fused out and reset the NPE and its
+ * coprocessor - to reset internal states and remove parity error
+ */
+ unitFuseReg = ixFeatureCtrlRead ();
+ unitFuseReg |= (IX_NPEDL_RESET_NPE_PARITY << npeId);
+ ixFeatureCtrlWrite (unitFuseReg);
+
+ /* call the feature control API to un-fused and un-reset the NPE & COP */
+ unitFuseReg &= (~(IX_NPEDL_RESET_NPE_PARITY << npeId));
+ ixFeatureCtrlWrite (unitFuseReg);
+
+ /*
+ * Call NpeMgr function to stop the NPE again after the Feature Control
+ * has unfused and Un-Reset the NPE and its associated Coprocessors
+ */
+ status = ixNpeDlNpeMgrNpeStop (npeId);
+
+ /* restore NPE configuration bus Control Register - Parity Settings */
+ IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL,
+ (ixNpeConfigCtrlRegVal & IX_NPEDL_CONFIG_CTRL_REG_MASK));
+
+ ixNpeDlNpeMgrStats.npeResets++;
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlNpeMgrNpeReset : status = %d\n", status);
+ return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrNpeStart
+ */
+IX_STATUS
+ixNpeDlNpeMgrNpeStart (
+ IxNpeDlNpeId npeId)
+{
+ UINT32 npeBaseAddress;
+ UINT32 ecsRegVal;
+ BOOL npeRunning;
+ IX_STATUS status = IX_SUCCESS;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlNpeMgrNpeStart\n");
+
+ /* get base memory address of NPE from npeId */
+ npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
+
+ /*
+ * ensure only Background Context Stack Level is Active by turning off
+ * the Active bit in each of the other Executing Context Stack levels
+ */
+ ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
+ IX_NPEDL_ECS_PRI_1_CTXT_REG_0);
+ ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
+ ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_1_CTXT_REG_0,
+ ecsRegVal);
+
+ ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
+ IX_NPEDL_ECS_PRI_2_CTXT_REG_0);
+ ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
+ ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_2_CTXT_REG_0,
+ ecsRegVal);
+
+ ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
+ IX_NPEDL_ECS_DBG_CTXT_REG_0);
+ ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
+ ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
+ ecsRegVal);
+
+ /* clear the pipeline */
+ ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
+
+ /* start NPE execution by issuing command through EXCTL register on NPE */
+ ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_START);
+
+ /*
+ * check execution status of NPE to verify NPE Start operation was
+ * successful
+ */
+ npeRunning = ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
+ IX_NPEDL_REG_OFFSET_EXCTL,
+ IX_NPEDL_EXCTL_STATUS_RUN);
+ if (npeRunning)
+ {
+ ixNpeDlNpeMgrStats.npeStarts++;
+ }
+ else
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStart: "
+ "failed to start NPE execution\n");
+ status = IX_FAIL;
+ }
+
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlNpeMgrNpeStart : status = %d\n", status);
+ return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrNpeStop
+ */
+IX_STATUS
+ixNpeDlNpeMgrNpeStop (
+ IxNpeDlNpeId npeId)
+{
+ UINT32 npeBaseAddress;
+ IX_STATUS status = IX_SUCCESS;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlNpeMgrNpeStop\n");
+
+ /* get base memory address of NPE from npeId */
+ npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
+
+ /* stop NPE execution by issuing command through EXCTL register on NPE */
+ ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_STOP);
+
+ /* verify that NPE Stop was successful */
+ if (! ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL,
+ IX_NPEDL_EXCTL_STATUS_STOP))
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStop: "
+ "failed to stop NPE execution\n");
+ status = IX_FAIL;
+ }
+
+ ixNpeDlNpeMgrStats.npeStops++;
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlNpeMgrNpeStop : status = %d\n", status);
+ return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrBitsSetCheck
+ */
+PRIVATE BOOL
+ixNpeDlNpeMgrBitsSetCheck (
+ UINT32 npeBaseAddress,
+ UINT32 regOffset,
+ UINT32 expectedBitsSet)
+{
+ UINT32 regVal;
+ IX_NPEDL_REG_READ (npeBaseAddress, regOffset, &regVal);
+
+ return expectedBitsSet == (expectedBitsSet & regVal);
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrStatsShow
+ */
+void
+ixNpeDlNpeMgrStatsShow (void)
+{
+ ixOsalLog (IX_OSAL_LOG_LVL_USER,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "\nixNpeDlNpeMgrStatsShow:\n"
+ "\tInstruction Blocks loaded: %u\n"
+ "\tData Blocks loaded: %u\n"
+ "\tState Information Blocks loaded: %u\n"
+ "\tCritical NPE errors: %u\n"
+ "\tCritical Microcode errors: %u\n",
+ ixNpeDlNpeMgrStats.instructionBlocksLoaded,
+ ixNpeDlNpeMgrStats.dataBlocksLoaded,
+ ixNpeDlNpeMgrStats.stateInfoBlocksLoaded,
+ ixNpeDlNpeMgrStats.criticalNpeErrors,
+ ixNpeDlNpeMgrStats.criticalMicrocodeErrors,
+ 0);
+
+ ixOsalLog (IX_OSAL_LOG_LVL_USER,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "\tSuccessful NPE Starts: %u\n"
+ "\tSuccessful NPE Stops: %u\n"
+ "\tSuccessful NPE Resets: %u\n\n",
+ ixNpeDlNpeMgrStats.npeStarts,
+ ixNpeDlNpeMgrStats.npeStops,
+ ixNpeDlNpeMgrStats.npeResets,
+ 0,0,0);
+
+ ixNpeDlNpeMgrUtilsStatsShow ();
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrStatsReset
+ */
+void
+ixNpeDlNpeMgrStatsReset (void)
+{
+ ixNpeDlNpeMgrStats.instructionBlocksLoaded = 0;
+ ixNpeDlNpeMgrStats.dataBlocksLoaded = 0;
+ ixNpeDlNpeMgrStats.stateInfoBlocksLoaded = 0;
+ ixNpeDlNpeMgrStats.criticalNpeErrors = 0;
+ ixNpeDlNpeMgrStats.criticalMicrocodeErrors = 0;
+ ixNpeDlNpeMgrStats.npeStarts = 0;
+ ixNpeDlNpeMgrStats.npeStops = 0;
+ ixNpeDlNpeMgrStats.npeResets = 0;
+
+ ixNpeDlNpeMgrUtilsStatsReset ();
+}
diff --git a/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c b/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c
new file mode 100644
index 0000000..9dcf3c1
--- /dev/null
+++ b/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c
@@ -0,0 +1,806 @@
+/**
+ * @file IxNpeDlNpeMgrUtils.c
+ *
+ * @author Intel Corporation
+ * @date 18 February 2002
+ *
+ * @brief This file contains the implementation of the private API for the
+ * IXP425 NPE Downloader NpeMgr Utils module
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+
+/*
+ * Put the system defined include files required.
+ */
+#define IX_NPE_DL_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of
+ * retries before
+ * timeout
+ */
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxOsal.h"
+#include "IxNpeDl.h"
+#include "IxNpeDlNpeMgrUtils_p.h"
+#include "IxNpeDlNpeMgrEcRegisters_p.h"
+#include "IxNpeDlMacros_p.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/* used to bit-mask a number of bytes */
+#define IX_NPEDL_MASK_LOWER_BYTE_OF_WORD 0x000000FF
+#define IX_NPEDL_MASK_LOWER_SHORT_OF_WORD 0x0000FFFF
+#define IX_NPEDL_MASK_FULL_WORD 0xFFFFFFFF
+
+#define IX_NPEDL_BYTES_PER_WORD 4
+#define IX_NPEDL_BYTES_PER_SHORT 2
+
+#define IX_NPEDL_REG_SIZE_BYTE 8
+#define IX_NPEDL_REG_SIZE_SHORT 16
+#define IX_NPEDL_REG_SIZE_WORD 32
+
+/*
+ * Introduce extra read cycles after issuing read command to NPE
+ * so that we read the register after the NPE has updated it
+ * This is to overcome race condition between XScale and NPE
+ */
+#define IX_NPEDL_DELAY_READ_CYCLES 2
+/*
+ * To mask top three MSBs of 32bit word to download into NPE IMEM
+ */
+#define IX_NPEDL_MASK_UNUSED_IMEM_BITS 0x1FFFFFFF;
+
+
+/*
+ * typedefs
+ */
+typedef struct
+{
+ UINT32 regAddress;
+ UINT32 regSize;
+} IxNpeDlCtxtRegAccessInfo;
+
+/* module statistics counters */
+typedef struct
+{
+ UINT32 insMemWrites;
+ UINT32 insMemWriteFails;
+ UINT32 dataMemWrites;
+ UINT32 dataMemWriteFails;
+ UINT32 ecsRegWrites;
+ UINT32 ecsRegReads;
+ UINT32 dbgInstructionExecs;
+ UINT32 contextRegWrites;
+ UINT32 physicalRegWrites;
+ UINT32 nextPcWrites;
+} IxNpeDlNpeMgrUtilsStats;
+
+
+/*
+ * Variable declarations global to this file only. Externs are followed by
+ * static variables.
+ */
+
+/*
+ * contains useful address and function pointers to read/write Context Regs,
+ * eliminating some switch or if-else statements in places
+ */
+static IxNpeDlCtxtRegAccessInfo ixNpeDlCtxtRegAccInfo[IX_NPEDL_CTXT_REG_MAX] =
+{
+ {
+ IX_NPEDL_CTXT_REG_ADDR_STEVT,
+ IX_NPEDL_REG_SIZE_BYTE
+ },
+ {
+ IX_NPEDL_CTXT_REG_ADDR_STARTPC,
+ IX_NPEDL_REG_SIZE_SHORT
+ },
+ {
+ IX_NPEDL_CTXT_REG_ADDR_REGMAP,
+ IX_NPEDL_REG_SIZE_SHORT
+ },
+ {
+ IX_NPEDL_CTXT_REG_ADDR_CINDEX,
+ IX_NPEDL_REG_SIZE_BYTE
+ }
+};
+
+static UINT32 ixNpeDlSavedExecCount = 0;
+static UINT32 ixNpeDlSavedEcsDbgCtxtReg2 = 0;
+
+static IxNpeDlNpeMgrUtilsStats ixNpeDlNpeMgrUtilsStats;
+
+
+/*
+ * static function prototypes.
+ */
+PRIVATE __inline__ void
+ixNpeDlNpeMgrWriteCommandIssue (UINT32 npeBaseAddress, UINT32 cmd,
+ UINT32 addr, UINT32 data);
+
+PRIVATE __inline__ UINT32
+ixNpeDlNpeMgrReadCommandIssue (UINT32 npeBaseAddress, UINT32 cmd, UINT32 addr);
+
+PRIVATE IX_STATUS
+ixNpeDlNpeMgrLogicalRegRead (UINT32 npeBaseAddress, UINT32 regAddr,
+ UINT32 regSize, UINT32 ctxtNum, UINT32 *regVal);
+
+PRIVATE IX_STATUS
+ixNpeDlNpeMgrLogicalRegWrite (UINT32 npeBaseAddress, UINT32 regAddr,
+ UINT32 regVal, UINT32 regSize,
+ UINT32 ctxtNum, BOOL verify);
+
+/*
+ * Function definition: ixNpeDlNpeMgrWriteCommandIssue
+ */
+PRIVATE __inline__ void
+ixNpeDlNpeMgrWriteCommandIssue (
+ UINT32 npeBaseAddress,
+ UINT32 cmd,
+ UINT32 addr,
+ UINT32 data)
+{
+ IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, data);
+ IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXAD, addr);
+ IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, cmd);
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrReadCommandIssue
+ */
+PRIVATE __inline__ UINT32
+ixNpeDlNpeMgrReadCommandIssue (
+ UINT32 npeBaseAddress,
+ UINT32 cmd,
+ UINT32 addr)
+{
+ UINT32 data = 0;
+ int i;
+
+ IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXAD, addr);
+ IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, cmd);
+ for (i = 0; i <= IX_NPEDL_DELAY_READ_CYCLES; i++)
+ {
+ IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, &data);
+ }
+
+ return data;
+}
+
+/*
+ * Function definition: ixNpeDlNpeMgrInsMemWrite
+ */
+IX_STATUS
+ixNpeDlNpeMgrInsMemWrite (
+ UINT32 npeBaseAddress,
+ UINT32 insMemAddress,
+ UINT32 insMemData,
+ BOOL verify)
+{
+ UINT32 insMemDataRtn;
+
+ ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
+ IX_NPEDL_EXCTL_CMD_WR_INS_MEM,
+ insMemAddress, insMemData);
+ if (verify)
+ {
+ /* write invalid data to this reg, so we can see if we're reading
+ the EXDATA register too early */
+ IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA,
+ ~insMemData);
+
+ /*Disabled since top 3 MSB are not used for Azusa hardware Refer WR:IXA00053900*/
+ insMemData&=IX_NPEDL_MASK_UNUSED_IMEM_BITS;
+
+ insMemDataRtn=ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
+ IX_NPEDL_EXCTL_CMD_RD_INS_MEM,
+ insMemAddress);
+
+ insMemDataRtn&=IX_NPEDL_MASK_UNUSED_IMEM_BITS;
+
+ if (insMemData != insMemDataRtn)
+ {
+ ixNpeDlNpeMgrUtilsStats.insMemWriteFails++;
+ return IX_FAIL;
+ }
+ }
+
+ ixNpeDlNpeMgrUtilsStats.insMemWrites++;
+ return IX_SUCCESS;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrDataMemWrite
+ */
+IX_STATUS
+ixNpeDlNpeMgrDataMemWrite (
+ UINT32 npeBaseAddress,
+ UINT32 dataMemAddress,
+ UINT32 dataMemData,
+ BOOL verify)
+{
+ ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
+ IX_NPEDL_EXCTL_CMD_WR_DATA_MEM,
+ dataMemAddress, dataMemData);
+ if (verify)
+ {
+ /* write invalid data to this reg, so we can see if we're reading
+ the EXDATA register too early */
+ IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, ~dataMemData);
+
+ if (dataMemData !=
+ ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
+ IX_NPEDL_EXCTL_CMD_RD_DATA_MEM,
+ dataMemAddress))
+ {
+ ixNpeDlNpeMgrUtilsStats.dataMemWriteFails++;
+ return IX_FAIL;
+ }
+ }
+
+ ixNpeDlNpeMgrUtilsStats.dataMemWrites++;
+ return IX_SUCCESS;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrExecAccRegWrite
+ */
+void
+ixNpeDlNpeMgrExecAccRegWrite (
+ UINT32 npeBaseAddress,
+ UINT32 regAddress,
+ UINT32 regData)
+{
+ ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
+ IX_NPEDL_EXCTL_CMD_WR_ECS_REG,
+ regAddress, regData);
+ ixNpeDlNpeMgrUtilsStats.ecsRegWrites++;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrExecAccRegRead
+ */
+UINT32
+ixNpeDlNpeMgrExecAccRegRead (
+ UINT32 npeBaseAddress,
+ UINT32 regAddress)
+{
+ ixNpeDlNpeMgrUtilsStats.ecsRegReads++;
+ return ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
+ IX_NPEDL_EXCTL_CMD_RD_ECS_REG,
+ regAddress);
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrCommandIssue
+ */
+void
+ixNpeDlNpeMgrCommandIssue (
+ UINT32 npeBaseAddress,
+ UINT32 command)
+{
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlNpeMgrCommandIssue\n");
+
+ IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, command);
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlNpeMgrCommandIssue\n");
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrDebugInstructionPreExec
+ */
+void
+ixNpeDlNpeMgrDebugInstructionPreExec(
+ UINT32 npeBaseAddress)
+{
+ /* turn off the halt bit by clearing Execution Count register. */
+ /* save reg contents 1st and restore later */
+ IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT,
+ &ixNpeDlSavedExecCount);
+ IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT, 0);
+
+ /* ensure that IF and IE are on (temporarily), so that we don't end up
+ * stepping forever */
+ ixNpeDlSavedEcsDbgCtxtReg2 = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
+ IX_NPEDL_ECS_DBG_CTXT_REG_2);
+
+ ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_2,
+ (ixNpeDlSavedEcsDbgCtxtReg2 |
+ IX_NPEDL_MASK_ECS_DBG_REG_2_IF |
+ IX_NPEDL_MASK_ECS_DBG_REG_2_IE));
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrDebugInstructionExec
+ */
+IX_STATUS
+ixNpeDlNpeMgrDebugInstructionExec(
+ UINT32 npeBaseAddress,
+ UINT32 npeInstruction,
+ UINT32 ctxtNum,
+ UINT32 ldur)
+{
+ UINT32 ecsDbgRegVal;
+ UINT32 oldWatchcount, newWatchcount;
+ UINT32 retriesCount = 0;
+ IX_STATUS status = IX_SUCCESS;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlNpeMgrDebugInstructionExec\n");
+
+ /* set the Active bit, and the LDUR, in the debug level */
+ ecsDbgRegVal = IX_NPEDL_MASK_ECS_REG_0_ACTIVE |
+ (ldur << IX_NPEDL_OFFSET_ECS_REG_0_LDUR);
+
+ ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
+ ecsDbgRegVal);
+
+ /*
+ * set CCTXT at ECS DEBUG L3 to specify in which context to execute the
+ * instruction, and set SELCTXT at ECS DEBUG Level to specify which context
+ * store to access.
+ * Debug ECS Level Reg 1 has form 0x000n000n, where n = context number
+ */
+ ecsDbgRegVal = (ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_CCTXT) |
+ (ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT);
+
+ ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_1,
+ ecsDbgRegVal);
+
+ /* clear the pipeline */
+ ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
+
+ /* load NPE instruction into the instruction register */
+ ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_INSTRUCT_REG,
+ npeInstruction);
+
+ /* we need this value later to wait for completion of NPE execution step */
+ IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, &oldWatchcount);
+
+ /* issue a Step One command via the Execution Control register */
+ ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_STEP);
+
+ /* Watch Count register increments when NPE completes an instruction */
+ IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC,
+ &newWatchcount);
+
+ /*
+ * force the XScale to wait until the NPE has finished execution step
+ * NOTE that this delay will be very small, just long enough to allow a
+ * single NPE instruction to complete execution; if instruction execution
+ * is not completed before timeout retries, exit the while loop
+ */
+ while ((IX_NPE_DL_MAX_NUM_OF_RETRIES > retriesCount)
+ && (newWatchcount == oldWatchcount))
+ {
+ /* Watch Count register increments when NPE completes an instruction */
+ IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC,
+ &newWatchcount);
+
+ retriesCount++;
+ }
+
+ if (IX_NPE_DL_MAX_NUM_OF_RETRIES > retriesCount)
+ {
+ ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs++;
+ }
+ else
+ {
+ /* Return timeout status as the instruction has not been executed
+ * after maximum retries */
+ status = IX_NPEDL_CRITICAL_NPE_ERR;
+ }
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlNpeMgrDebugInstructionExec\n");
+
+ return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrDebugInstructionPostExec
+ */
+void
+ixNpeDlNpeMgrDebugInstructionPostExec(
+ UINT32 npeBaseAddress)
+{
+ /* clear active bit in debug level */
+ ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
+ 0);
+
+ /* clear the pipeline */
+ ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
+
+ /* restore Execution Count register contents. */
+ IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT,
+ ixNpeDlSavedExecCount);
+
+ /* restore IF and IE bits to original values */
+ ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_2,
+ ixNpeDlSavedEcsDbgCtxtReg2);
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrLogicalRegRead
+ */
+PRIVATE IX_STATUS
+ixNpeDlNpeMgrLogicalRegRead (
+ UINT32 npeBaseAddress,
+ UINT32 regAddr,
+ UINT32 regSize,
+ UINT32 ctxtNum,
+ UINT32 *regVal)
+{
+ IX_STATUS status = IX_SUCCESS;
+ UINT32 npeInstruction = 0;
+ UINT32 mask = 0;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlNpeMgrLogicalRegRead\n");
+
+ switch (regSize)
+ {
+ case IX_NPEDL_REG_SIZE_BYTE:
+ npeInstruction = IX_NPEDL_INSTR_RD_REG_BYTE;
+ mask = IX_NPEDL_MASK_LOWER_BYTE_OF_WORD; break;
+ case IX_NPEDL_REG_SIZE_SHORT:
+ npeInstruction = IX_NPEDL_INSTR_RD_REG_SHORT;
+ mask = IX_NPEDL_MASK_LOWER_SHORT_OF_WORD; break;
+ case IX_NPEDL_REG_SIZE_WORD:
+ npeInstruction = IX_NPEDL_INSTR_RD_REG_WORD;
+ mask = IX_NPEDL_MASK_FULL_WORD; break;
+ }
+
+ /* make regAddr be the SRC and DEST operands (e.g. movX d0, d0) */
+ npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_SRC) |
+ (regAddr << IX_NPEDL_OFFSET_INSTR_DEST);
+
+ /* step execution of NPE intruction using Debug Executing Context stack */
+ status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress, npeInstruction,
+ ctxtNum, IX_NPEDL_RD_INSTR_LDUR);
+
+ if (IX_SUCCESS != status)
+ {
+ return status;
+ }
+
+ /* read value of register from Execution Data register */
+ IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, regVal);
+
+ /* align value from left to right */
+ *regVal = (*regVal >> (IX_NPEDL_REG_SIZE_WORD - regSize)) & mask;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlNpeMgrLogicalRegRead\n");
+
+ return IX_SUCCESS;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrLogicalRegWrite
+ */
+PRIVATE IX_STATUS
+ixNpeDlNpeMgrLogicalRegWrite (
+ UINT32 npeBaseAddress,
+ UINT32 regAddr,
+ UINT32 regVal,
+ UINT32 regSize,
+ UINT32 ctxtNum,
+ BOOL verify)
+{
+ UINT32 npeInstruction = 0;
+ UINT32 mask = 0;
+ IX_STATUS status = IX_SUCCESS;
+ UINT32 retRegVal;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlNpeMgrLogicalRegWrite\n");
+
+ if (regSize == IX_NPEDL_REG_SIZE_WORD)
+ {
+ /* NPE register addressing is left-to-right: e.g. |d0|d1|d2|d3| */
+ /* Write upper half-word (short) to |d0|d1| */
+ status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, regAddr,
+ regVal >> IX_NPEDL_REG_SIZE_SHORT,
+ IX_NPEDL_REG_SIZE_SHORT,
+ ctxtNum, verify);
+
+ if (IX_SUCCESS != status)
+ {
+ return status;
+ }
+
+ /* Write lower half-word (short) to |d2|d3| */
+ status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress,
+ regAddr + IX_NPEDL_BYTES_PER_SHORT,
+ regVal & IX_NPEDL_MASK_LOWER_SHORT_OF_WORD,
+ IX_NPEDL_REG_SIZE_SHORT,
+ ctxtNum, verify);
+
+ if (IX_SUCCESS != status)
+ {
+ return status;
+ }
+ }
+ else
+ {
+ switch (regSize)
+ {
+ case IX_NPEDL_REG_SIZE_BYTE:
+ npeInstruction = IX_NPEDL_INSTR_WR_REG_BYTE;
+ mask = IX_NPEDL_MASK_LOWER_BYTE_OF_WORD; break;
+ case IX_NPEDL_REG_SIZE_SHORT:
+ npeInstruction = IX_NPEDL_INSTR_WR_REG_SHORT;
+ mask = IX_NPEDL_MASK_LOWER_SHORT_OF_WORD; break;
+ }
+ /* mask out any redundant bits, so verify will work later */
+ regVal &= mask;
+
+ /* fill dest operand field of instruction with destination reg addr */
+ npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_DEST);
+
+ /* fill src operand field of instruction with least-sig 5 bits of val*/
+ npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA) <<
+ IX_NPEDL_OFFSET_INSTR_SRC);
+
+ /* fill coprocessor field of instruction with most-sig 11 bits of val*/
+ npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA) <<
+ IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA);
+
+ /* step execution of NPE intruction using Debug ECS */
+ status = ixNpeDlNpeMgrDebugInstructionExec(npeBaseAddress, npeInstruction,
+ ctxtNum, IX_NPEDL_WR_INSTR_LDUR);
+
+ if (IX_SUCCESS != status)
+ {
+ return status;
+ }
+ }/* condition: if reg to be written is 8-bit or 16-bit (not 32-bit) */
+
+ if (verify)
+ {
+ status = ixNpeDlNpeMgrLogicalRegRead (npeBaseAddress, regAddr,
+ regSize, ctxtNum, &retRegVal);
+
+ if (IX_SUCCESS == status)
+ {
+ if (regVal != retRegVal)
+ {
+ status = IX_FAIL;
+ }
+ }
+ }
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlNpeMgrLogicalRegWrite : status = %d\n",
+ status);
+
+ return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrPhysicalRegWrite
+ */
+IX_STATUS
+ixNpeDlNpeMgrPhysicalRegWrite (
+ UINT32 npeBaseAddress,
+ UINT32 regAddr,
+ UINT32 regValue,
+ BOOL verify)
+{
+ IX_STATUS status;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlNpeMgrPhysicalRegWrite\n");
+
+/*
+ * There are 32 physical registers used in an NPE. These are
+ * treated as 16 pairs of 32-bit registers. To write one of the pair,
+ * write the pair number (0-16) to the REGMAP for Context 0. Then write
+ * the value to register 0 or 4 in the regfile, depending on which
+ * register of the pair is to be written
+ */
+
+ /*
+ * set REGMAP for context 0 to (regAddr >> 1) to choose which pair (0-16)
+ * of physical registers to write
+ */
+ status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress,
+ IX_NPEDL_CTXT_REG_ADDR_REGMAP,
+ (regAddr >>
+ IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP),
+ IX_NPEDL_REG_SIZE_SHORT, 0, verify);
+ if (status == IX_SUCCESS)
+ {
+ /* regAddr = 0 or 4 */
+ regAddr = (regAddr & IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR) *
+ IX_NPEDL_BYTES_PER_WORD;
+
+ status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, regAddr, regValue,
+ IX_NPEDL_REG_SIZE_WORD, 0, verify);
+ }
+
+ if (status != IX_SUCCESS)
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrPhysicalRegWrite: "
+ "error writing to physical register\n");
+ }
+
+ ixNpeDlNpeMgrUtilsStats.physicalRegWrites++;
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlNpeMgrPhysicalRegWrite : status = %d\n",
+ status);
+ return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrCtxtRegWrite
+ */
+IX_STATUS
+ixNpeDlNpeMgrCtxtRegWrite (
+ UINT32 npeBaseAddress,
+ UINT32 ctxtNum,
+ IxNpeDlCtxtRegNum ctxtReg,
+ UINT32 ctxtRegVal,
+ BOOL verify)
+{
+ UINT32 tempRegVal;
+ UINT32 ctxtRegAddr;
+ UINT32 ctxtRegSize;
+ IX_STATUS status = IX_SUCCESS;
+
+ IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Entering ixNpeDlNpeMgrCtxtRegWrite\n");
+
+ /*
+ * Context 0 has no STARTPC. Instead, this value is used to set
+ * NextPC for Background ECS, to set where NPE starts executing code
+ */
+ if ((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STARTPC))
+ {
+ /* read BG_CTXT_REG_0, update NEXTPC bits, and write back to reg */
+ tempRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
+ IX_NPEDL_ECS_BG_CTXT_REG_0);
+ tempRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_NEXTPC;
+ tempRegVal |= (ctxtRegVal << IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC) &
+ IX_NPEDL_MASK_ECS_REG_0_NEXTPC;
+
+ ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress,
+ IX_NPEDL_ECS_BG_CTXT_REG_0, tempRegVal);
+
+ ixNpeDlNpeMgrUtilsStats.nextPcWrites++;
+ }
+ else
+ {
+ ctxtRegAddr = ixNpeDlCtxtRegAccInfo[ctxtReg].regAddress;
+ ctxtRegSize = ixNpeDlCtxtRegAccInfo[ctxtReg].regSize;
+ status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, ctxtRegAddr,
+ ctxtRegVal, ctxtRegSize,
+ ctxtNum, verify);
+ if (status != IX_SUCCESS)
+ {
+ IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrCtxtRegWrite: "
+ "error writing to context store register\n");
+ }
+
+ ixNpeDlNpeMgrUtilsStats.contextRegWrites++;
+ }
+
+ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+ "Exiting ixNpeDlNpeMgrCtxtRegWrite : status = %d\n",
+ status);
+
+ return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrUtilsStatsShow
+ */
+void
+ixNpeDlNpeMgrUtilsStatsShow (void)
+{
+ ixOsalLog (IX_OSAL_LOG_LVL_USER,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "\nixNpeDlNpeMgrUtilsStatsShow:\n"
+ "\tInstruction Memory writes: %u\n"
+ "\tInstruction Memory writes failed: %u\n"
+ "\tData Memory writes: %u\n"
+ "\tData Memory writes failed: %u\n",
+ ixNpeDlNpeMgrUtilsStats.insMemWrites,
+ ixNpeDlNpeMgrUtilsStats.insMemWriteFails,
+ ixNpeDlNpeMgrUtilsStats.dataMemWrites,
+ ixNpeDlNpeMgrUtilsStats.dataMemWriteFails,
+ 0,0);
+
+ ixOsalLog (IX_OSAL_LOG_LVL_USER,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "\tExecuting Context Stack Register writes: %u\n"
+ "\tExecuting Context Stack Register reads: %u\n"
+ "\tPhysical Register writes: %u\n"
+ "\tContext Store Register writes: %u\n"
+ "\tExecution Backgound Context NextPC writes: %u\n"
+ "\tDebug Instructions Executed: %u\n\n",
+ ixNpeDlNpeMgrUtilsStats.ecsRegWrites,
+ ixNpeDlNpeMgrUtilsStats.ecsRegReads,
+ ixNpeDlNpeMgrUtilsStats.physicalRegWrites,
+ ixNpeDlNpeMgrUtilsStats.contextRegWrites,
+ ixNpeDlNpeMgrUtilsStats.nextPcWrites,
+ ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs);
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrUtilsStatsReset
+ */
+void
+ixNpeDlNpeMgrUtilsStatsReset (void)
+{
+ ixNpeDlNpeMgrUtilsStats.insMemWrites = 0;
+ ixNpeDlNpeMgrUtilsStats.insMemWriteFails = 0;
+ ixNpeDlNpeMgrUtilsStats.dataMemWrites = 0;
+ ixNpeDlNpeMgrUtilsStats.dataMemWriteFails = 0;
+ ixNpeDlNpeMgrUtilsStats.ecsRegWrites = 0;
+ ixNpeDlNpeMgrUtilsStats.ecsRegReads = 0;
+ ixNpeDlNpeMgrUtilsStats.physicalRegWrites = 0;
+ ixNpeDlNpeMgrUtilsStats.contextRegWrites = 0;
+ ixNpeDlNpeMgrUtilsStats.nextPcWrites = 0;
+ ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs = 0;
+}
diff --git a/cpu/ixp/npe/IxNpeMh.c b/cpu/ixp/npe/IxNpeMh.c
new file mode 100644
index 0000000..8703def
--- /dev/null
+++ b/cpu/ixp/npe/IxNpeMh.c
@@ -0,0 +1,582 @@
+/**
+ * @file IxNpeMh.c
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the implementation of the public API for the
+ * IXP425 NPE Message Handler component.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * Put the system defined include files required.
+ */
+
+/*
+ * Put the user defined include files required.
+ */
+
+#include "IxOsal.h"
+#include "IxNpeMhMacros_p.h"
+
+#include "IxNpeMh.h"
+
+#include "IxNpeMhConfig_p.h"
+#include "IxNpeMhReceive_p.h"
+#include "IxNpeMhSend_p.h"
+#include "IxNpeMhSolicitedCbMgr_p.h"
+#include "IxNpeMhUnsolicitedCbMgr_p.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/*
+ * Variable declarations global to this file only. Externs are followed by
+ * static variables.
+ */
+
+PRIVATE BOOL ixNpeMhInitialized = FALSE;
+
+/*
+ * Extern function prototypes.
+ */
+
+/*
+ * Static function prototypes.
+ */
+
+/*
+ * Function definition: ixNpeMhInitialize
+ */
+
+PUBLIC IX_STATUS ixNpeMhInitialize (
+ IxNpeMhNpeInterrupts npeInterrupts)
+{
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhInitialize\n");
+
+ /* check the npeInterrupts parameter */
+ if ((npeInterrupts != IX_NPEMH_NPEINTERRUPTS_NO) &&
+ (npeInterrupts != IX_NPEMH_NPEINTERRUPTS_YES))
+ {
+ IX_NPEMH_ERROR_REPORT ("Illegal npeInterrupts parameter value\n");
+ return IX_FAIL;
+ }
+
+ /* parameters are ok ... */
+
+ /* initialize the Receive module */
+ ixNpeMhReceiveInitialize ();
+
+ /* initialize the Solicited Callback Manager module */
+ ixNpeMhSolicitedCbMgrInitialize ();
+
+ /* initialize the Unsolicited Callback Manager module */
+ ixNpeMhUnsolicitedCbMgrInitialize ();
+
+ /* initialize the Configuration module
+ *
+ * NOTE: This module was originally configured before the
+ * others, but the sequence was changed so that interrupts
+ * would only be enabled after the handler functions were
+ * set up. The above modules need to be initialised to
+ * handle the NPE interrupts. See SCR #2231.
+ */
+ ixNpeMhConfigInitialize (npeInterrupts);
+
+ ixNpeMhInitialized = TRUE;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhInitialize\n");
+
+ return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeMhUnload
+ */
+
+PUBLIC IX_STATUS ixNpeMhUnload (void)
+{
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhUnload\n");
+
+ if (!ixNpeMhInitialized)
+ {
+ return IX_FAIL;
+ }
+
+ /* Uninitialize the Configuration module */
+ ixNpeMhConfigUninit ();
+
+ ixNpeMhInitialized = FALSE;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhUnload\n");
+
+ return IX_SUCCESS;
+}
+
+
+/*
+ * Function definition: ixNpeMhUnsolicitedCallbackRegister
+ */
+
+PUBLIC IX_STATUS ixNpeMhUnsolicitedCallbackRegister (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId messageId,
+ IxNpeMhCallback unsolicitedCallback)
+{
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhUnsolicitedCallbackRegister\n");
+
+ /* check that we are initialized */
+ if (!ixNpeMhInitialized)
+ {
+ IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
+ return IX_FAIL;
+ }
+
+ /* check the npeId parameter */
+ if (!ixNpeMhConfigNpeIdIsValid (npeId))
+ {
+ IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
+ return IX_FAIL;
+ }
+
+ /* check the messageId parameter */
+ if ((messageId < IX_NPEMH_MIN_MESSAGE_ID)
+ || (messageId > IX_NPEMH_MAX_MESSAGE_ID))
+ {
+ IX_NPEMH_ERROR_REPORT ("Message ID is out of range\n");
+ return IX_FAIL;
+ }
+
+ /* the unsolicitedCallback parameter is allowed to be NULL */
+
+ /* parameters are ok ... */
+
+ /* get the lock to prevent other clients from entering */
+ ixNpeMhConfigLockGet (npeId);
+
+ /* save the unsolicited callback for the message ID */
+ ixNpeMhUnsolicitedCbMgrCallbackSave (
+ npeId, messageId, unsolicitedCallback);
+
+ /* release the lock to allow other clients back in */
+ ixNpeMhConfigLockRelease (npeId);
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhUnsolicitedCallbackRegister\n");
+
+ return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeMhUnsolicitedCallbackForRangeRegister
+ */
+
+PUBLIC IX_STATUS ixNpeMhUnsolicitedCallbackForRangeRegister (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId minMessageId,
+ IxNpeMhMessageId maxMessageId,
+ IxNpeMhCallback unsolicitedCallback)
+{
+ IxNpeMhMessageId messageId;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhUnsolicitedCallbackForRangeRegister\n");
+
+ /* check that we are initialized */
+ if (!ixNpeMhInitialized)
+ {
+ IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
+ return IX_FAIL;
+ }
+
+ /* check the npeId parameter */
+ if (!ixNpeMhConfigNpeIdIsValid (npeId))
+ {
+ IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
+ return IX_FAIL;
+ }
+
+ /* check the minMessageId parameter */
+ if ((minMessageId < IX_NPEMH_MIN_MESSAGE_ID)
+ || (minMessageId > IX_NPEMH_MAX_MESSAGE_ID))
+ {
+ IX_NPEMH_ERROR_REPORT ("Min message ID is out of range\n");
+ return IX_FAIL;
+ }
+
+ /* check the maxMessageId parameter */
+ if ((maxMessageId < IX_NPEMH_MIN_MESSAGE_ID)
+ || (maxMessageId > IX_NPEMH_MAX_MESSAGE_ID))
+ {
+ IX_NPEMH_ERROR_REPORT ("Max message ID is out of range\n");
+ return IX_FAIL;
+ }
+
+ /* check the semantics of the message range parameters */
+ if (minMessageId > maxMessageId)
+ {
+ IX_NPEMH_ERROR_REPORT ("Min message ID greater than max message "
+ "ID\n");
+ return IX_FAIL;
+ }
+
+ /* the unsolicitedCallback parameter is allowed to be NULL */
+
+ /* parameters are ok ... */
+
+ /* get the lock to prevent other clients from entering */
+ ixNpeMhConfigLockGet (npeId);
+
+ /* for each message ID in the range ... */
+ for (messageId = minMessageId; messageId <= maxMessageId; messageId++)
+ {
+ /* save the unsolicited callback for the message ID */
+ ixNpeMhUnsolicitedCbMgrCallbackSave (
+ npeId, messageId, unsolicitedCallback);
+ }
+
+ /* release the lock to allow other clients back in */
+ ixNpeMhConfigLockRelease (npeId);
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhUnsolicitedCallbackForRangeRegister\n");
+
+ return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeMhMessageSend
+ */
+
+PUBLIC IX_STATUS ixNpeMhMessageSend (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage message,
+ UINT32 maxSendRetries)
+{
+ IX_STATUS status = IX_SUCCESS;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhMessageSend\n");
+
+ /* check that we are initialized */
+ if (!ixNpeMhInitialized)
+ {
+ IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
+ return IX_FAIL;
+ }
+
+ /* check the npeId parameter */
+ if (!ixNpeMhConfigNpeIdIsValid (npeId))
+ {
+ IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
+ return IX_FAIL;
+ }
+
+ /* parameters are ok ... */
+
+ /* get the lock to prevent other clients from entering */
+ ixNpeMhConfigLockGet (npeId);
+
+ /* send the message */
+ status = ixNpeMhSendMessageSend (npeId, message, maxSendRetries);
+ if (status != IX_SUCCESS)
+ {
+ IX_NPEMH_ERROR_REPORT ("Failed to send message\n");
+ }
+
+ /* release the lock to allow other clients back in */
+ ixNpeMhConfigLockRelease (npeId);
+
+ IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhMessageSend"
+ " : status = %d\n", status);
+
+ return status;
+}
+
+/*
+ * Function definition: ixNpeMhMessageWithResponseSend
+ */
+
+PUBLIC IX_STATUS ixNpeMhMessageWithResponseSend (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage message,
+ IxNpeMhMessageId solicitedMessageId,
+ IxNpeMhCallback solicitedCallback,
+ UINT32 maxSendRetries)
+{
+ IX_STATUS status = IX_SUCCESS;
+ IxNpeMhCallback unsolicitedCallback = NULL;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhMessageWithResponseSend\n");
+
+ /* check that we are initialized */
+ if (!ixNpeMhInitialized)
+ {
+ IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
+ return IX_FAIL;
+ }
+
+ /* the solicitecCallback parameter is allowed to be NULL. this */
+ /* signifies the client is not interested in the response message */
+
+ /* check the npeId parameter */
+ if (!ixNpeMhConfigNpeIdIsValid (npeId))
+ {
+ IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
+ return IX_FAIL;
+ }
+
+ /* check the solicitedMessageId parameter */
+ if ((solicitedMessageId < IX_NPEMH_MIN_MESSAGE_ID)
+ || (solicitedMessageId > IX_NPEMH_MAX_MESSAGE_ID))
+ {
+ IX_NPEMH_ERROR_REPORT ("Solicited message ID is out of range\n");
+ return IX_FAIL;
+ }
+
+ /* check the solicitedMessageId parameter. if an unsolicited */
+ /* callback has been registered for the specified message ID then */
+ /* report an error and return failure */
+ ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
+ npeId, solicitedMessageId, &unsolicitedCallback);
+ if (unsolicitedCallback != NULL)
+ {
+ IX_NPEMH_ERROR_REPORT ("Solicited message ID conflicts with "
+ "unsolicited message ID\n");
+ return IX_FAIL;
+ }
+
+ /* parameters are ok ... */
+
+ /* get the lock to prevent other clients from entering */
+ ixNpeMhConfigLockGet (npeId);
+
+ /* send the message */
+ status = ixNpeMhSendMessageWithResponseSend (
+ npeId, message, solicitedMessageId, solicitedCallback,
+ maxSendRetries);
+ if (status != IX_SUCCESS)
+ {
+ IX_NPEMH_ERROR_REPORT ("Failed to send message\n");
+ }
+
+ /* release the lock to allow other clients back in */
+ ixNpeMhConfigLockRelease (npeId);
+
+ IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhMessageWithResponseSend"
+ " : status = %d\n", status);
+
+ return status;
+}
+
+/*
+ * Function definition: ixNpeMhMessagesReceive
+ */
+
+PUBLIC IX_STATUS ixNpeMhMessagesReceive (
+ IxNpeMhNpeId npeId)
+{
+ IX_STATUS status = IX_SUCCESS;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhMessagesReceive\n");
+
+ /* check that we are initialized */
+ if (!ixNpeMhInitialized)
+ {
+ IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
+ return IX_FAIL;
+ }
+
+ /* check the npeId parameter */
+ if (!ixNpeMhConfigNpeIdIsValid (npeId))
+ {
+ IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
+ return IX_FAIL;
+ }
+
+ /* parameters are ok ... */
+
+ /* get the lock to prevent other clients from entering */
+ ixNpeMhConfigLockGet (npeId);
+
+ /* receive messages from the NPE */
+ status = ixNpeMhReceiveMessagesReceive (npeId);
+
+ if (status != IX_SUCCESS)
+ {
+ IX_NPEMH_ERROR_REPORT ("Failed to receive message\n");
+ }
+
+ /* release the lock to allow other clients back in */
+ ixNpeMhConfigLockRelease (npeId);
+
+ IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhMessagesReceive"
+ " : status = %d\n", status);
+
+ return status;
+}
+
+/*
+ * Function definition: ixNpeMhShow
+ */
+
+PUBLIC IX_STATUS ixNpeMhShow (
+ IxNpeMhNpeId npeId)
+{
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhShow\n");
+
+ /* check that we are initialized */
+ if (!ixNpeMhInitialized)
+ {
+ IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
+ return IX_FAIL;
+ }
+
+ /* check the npeId parameter */
+ if (!ixNpeMhConfigNpeIdIsValid (npeId))
+ {
+ IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
+ return IX_FAIL;
+ }
+
+ /* parameters are ok ... */
+
+ /* note we don't get the lock here as printing the statistics */
+ /* to a console may take some time and we don't want to impact */
+ /* system performance. this means that the statistics displayed */
+ /* may be in a state of flux and make not represent a consistent */
+ /* snapshot. */
+
+ /* display a header */
+ ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
+ "Current state of NPE ID %d:\n\n", npeId, 0, 0, 0, 0, 0);
+
+ /* show the current state of each module */
+
+ /* show the current state of the Configuration module */
+ ixNpeMhConfigShow (npeId);
+
+ /* show the current state of the Receive module */
+ ixNpeMhReceiveShow (npeId);
+
+ /* show the current state of the Send module */
+ ixNpeMhSendShow (npeId);
+
+ /* show the current state of the Solicited Callback Manager module */
+ ixNpeMhSolicitedCbMgrShow (npeId);
+
+ /* show the current state of the Unsolicited Callback Manager module */
+ ixNpeMhUnsolicitedCbMgrShow (npeId);
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhShow\n");
+
+ return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeMhShowReset
+ */
+
+PUBLIC IX_STATUS ixNpeMhShowReset (
+ IxNpeMhNpeId npeId)
+{
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhShowReset\n");
+
+ /* check that we are initialized */
+ if (!ixNpeMhInitialized)
+ {
+ IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
+ return IX_FAIL;
+ }
+
+ /* check the npeId parameter */
+ if (!ixNpeMhConfigNpeIdIsValid (npeId))
+ {
+ IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
+ return IX_FAIL;
+ }
+
+ /* parameters are ok ... */
+
+ /* note we don't get the lock here as resetting the statistics */
+ /* shouldn't impact system performance. */
+
+ /* reset the current state of each module */
+
+ /* reset the current state of the Configuration module */
+ ixNpeMhConfigShowReset (npeId);
+
+ /* reset the current state of the Receive module */
+ ixNpeMhReceiveShowReset (npeId);
+
+ /* reset the current state of the Send module */
+ ixNpeMhSendShowReset (npeId);
+
+ /* reset the current state of the Solicited Callback Manager module */
+ ixNpeMhSolicitedCbMgrShowReset (npeId);
+
+ /* reset the current state of the Unsolicited Callback Manager module */
+ ixNpeMhUnsolicitedCbMgrShowReset (npeId);
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhShowReset\n");
+
+ return IX_SUCCESS;
+}
diff --git a/cpu/ixp/npe/IxNpeMhConfig.c b/cpu/ixp/npe/IxNpeMhConfig.c
new file mode 100644
index 0000000..50c8f21
--- /dev/null
+++ b/cpu/ixp/npe/IxNpeMhConfig.c
@@ -0,0 +1,608 @@
+/**
+ * @file IxNpeMhConfig.c
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the implementation of the private API for the
+ * Configuration module.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * Put the system defined include files required.
+ */
+
+
+/*
+ * Put the user defined include files required.
+ */
+
+#include "IxOsal.h"
+
+#include "IxNpeMhMacros_p.h"
+
+#include "IxNpeMhConfig_p.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+#define IX_NPE_MH_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of
+ * retries before
+ * timeout
+ */
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/**
+ * @struct IxNpeMhConfigStats
+ *
+ * @brief This structure is used to maintain statistics for the
+ * Configuration module.
+ */
+
+typedef struct
+{
+ UINT32 outFifoReads; /**< outFifo reads */
+ UINT32 inFifoWrites; /**< inFifo writes */
+ UINT32 maxInFifoFullRetries; /**< max retries if inFIFO full */
+ UINT32 maxOutFifoEmptyRetries; /**< max retries if outFIFO empty */
+} IxNpeMhConfigStats;
+
+/*
+ * Variable declarations global to this file only. Externs are followed by
+ * static variables.
+ */
+
+IxNpeMhConfigNpeInfo ixNpeMhConfigNpeInfo[IX_NPEMH_NUM_NPES] =
+{
+ {
+ 0,
+ IX_NPEMH_NPEA_INT,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ FALSE
+ },
+ {
+ 0,
+ IX_NPEMH_NPEB_INT,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ FALSE
+ },
+ {
+ 0,
+ IX_NPEMH_NPEC_INT,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ FALSE
+ }
+};
+
+PRIVATE IxNpeMhConfigStats ixNpeMhConfigStats[IX_NPEMH_NUM_NPES];
+
+/*
+ * Extern function prototypes.
+ */
+
+/*
+ * Static function prototypes.
+ */
+PRIVATE
+void ixNpeMhConfigIsr (void *parameter);
+
+/*
+ * Function definition: ixNpeMhConfigIsr
+ */
+
+PRIVATE
+void ixNpeMhConfigIsr (void *parameter)
+{
+ IxNpeMhNpeId npeId = (IxNpeMhNpeId)parameter;
+ UINT32 ofint;
+ volatile UINT32 *statusReg =
+ (UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhConfigIsr\n");
+
+ /* get the OFINT (OutFifo interrupt) bit of the status register */
+ IX_NPEMH_REGISTER_READ_BITS (statusReg, &ofint, IX_NPEMH_NPE_STAT_OFINT);
+
+ /* if the OFINT status bit is set */
+ if (ofint)
+ {
+ /* if there is an ISR registered for this NPE */
+ if (ixNpeMhConfigNpeInfo[npeId].isr != NULL)
+ {
+ /* invoke the ISR routine */
+ ixNpeMhConfigNpeInfo[npeId].isr (npeId);
+ }
+ else
+ {
+ /* if we don't service the interrupt the NPE will continue */
+ /* to trigger the interrupt indefinitely */
+ IX_NPEMH_ERROR_REPORT ("No ISR registered to service "
+ "interrupt\n");
+ }
+ }
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhConfigIsr\n");
+}
+
+/*
+ * Function definition: ixNpeMhConfigInitialize
+ */
+
+void ixNpeMhConfigInitialize (
+ IxNpeMhNpeInterrupts npeInterrupts)
+{
+ IxNpeMhNpeId npeId;
+ UINT32 virtualAddr[IX_NPEMH_NUM_NPES];
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhConfigInitialize\n");
+
+ /* Request a mapping for the NPE-A config register address space */
+ virtualAddr[IX_NPEMH_NPEID_NPEA] =
+ (UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEA_BASE,
+ IX_OSAL_IXP400_NPEA_MAP_SIZE);
+ IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEA]);
+
+ /* Request a mapping for the NPE-B config register address space */
+ virtualAddr[IX_NPEMH_NPEID_NPEB] =
+ (UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEB_BASE,
+ IX_OSAL_IXP400_NPEB_MAP_SIZE);
+ IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEB]);
+
+ /* Request a mapping for the NPE-C config register address space */
+ virtualAddr[IX_NPEMH_NPEID_NPEC] =
+ (UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEC_BASE,
+ IX_OSAL_IXP400_NPEC_MAP_SIZE);
+ IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEC]);
+
+ /* for each NPE ... */
+ for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
+ {
+ /* declare a convenience pointer */
+ IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId];
+
+ /* store the virtual addresses of the NPE registers for later use */
+ npeInfo->virtualRegisterBase = virtualAddr[npeId];
+ npeInfo->statusRegister = virtualAddr[npeId] + IX_NPEMH_NPESTAT_OFFSET;
+ npeInfo->controlRegister = virtualAddr[npeId] + IX_NPEMH_NPECTL_OFFSET;
+ npeInfo->inFifoRegister = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET;
+ npeInfo->outFifoRegister = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET;
+
+ /* for test purposes - to verify the register addresses */
+ IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d status register = "
+ "0x%08X\n", npeId, npeInfo->statusRegister);
+ IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d control register = "
+ "0x%08X\n", npeId, npeInfo->controlRegister);
+ IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d inFifo register = "
+ "0x%08X\n", npeId, npeInfo->inFifoRegister);
+ IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d outFifo register = "
+ "0x%08X\n", npeId, npeInfo->outFifoRegister);
+
+ /* connect our ISR to the NPE interrupt */
+ (void) ixOsalIrqBind (
+ npeInfo->interruptId, ixNpeMhConfigIsr, (void *)npeId);
+
+ /* initialise a mutex for this NPE */
+ (void) ixOsalMutexInit (&npeInfo->mutex);
+
+ /* if we should service the NPE's "outFIFO not empty" interrupt */
+ if (npeInterrupts == IX_NPEMH_NPEINTERRUPTS_YES)
+ {
+ /* enable the NPE's "outFIFO not empty" interrupt */
+ ixNpeMhConfigNpeInterruptEnable (npeId);
+ }
+ else
+ {
+ /* disable the NPE's "outFIFO not empty" interrupt */
+ ixNpeMhConfigNpeInterruptDisable (npeId);
+ }
+ }
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhConfigInitialize\n");
+}
+
+/*
+ * Function definition: ixNpeMhConfigUninit
+ */
+
+void ixNpeMhConfigUninit (void)
+{
+ IxNpeMhNpeId npeId;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhConfigUninit\n");
+
+ /* for each NPE ... */
+ for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
+ {
+ /* declare a convenience pointer */
+ IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId];
+
+ /* disconnect ISR */
+ ixOsalIrqUnbind(npeInfo->interruptId);
+
+ /* destroy mutex associated with this NPE */
+ ixOsalMutexDestroy(&npeInfo->mutex);
+
+ IX_OSAL_MEM_UNMAP (npeInfo->virtualRegisterBase);
+
+ npeInfo->virtualRegisterBase = 0;
+ npeInfo->statusRegister = 0;
+ npeInfo->controlRegister = 0;
+ npeInfo->inFifoRegister = 0;
+ npeInfo->outFifoRegister = 0;
+ }
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhConfigUninit\n");
+}
+
+/*
+ * Function definition: ixNpeMhConfigIsrRegister
+ */
+
+void ixNpeMhConfigIsrRegister (
+ IxNpeMhNpeId npeId,
+ IxNpeMhConfigIsr isr)
+{
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhConfigIsrRegister\n");
+
+ /* check if there is already an ISR registered for this NPE */
+ if (ixNpeMhConfigNpeInfo[npeId].isr != NULL)
+ {
+ IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG, "Over-writing registered NPE ISR\n");
+ }
+
+ /* save the ISR routine with the NPE info */
+ ixNpeMhConfigNpeInfo[npeId].isr = isr;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhConfigIsrRegister\n");
+}
+
+/*
+ * Function definition: ixNpeMhConfigNpeInterruptEnable
+ */
+
+BOOL ixNpeMhConfigNpeInterruptEnable (
+ IxNpeMhNpeId npeId)
+{
+ UINT32 ofe;
+ volatile UINT32 *controlReg =
+ (UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister;
+
+ /* get the OFE (OutFifoEnable) bit of the control register */
+ IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE);
+
+ /* if the interrupt is disabled then we must enable it */
+ if (!ofe)
+ {
+ /* set the OFE (OutFifoEnable) bit of the control register */
+ /* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */
+ /* time for the write to have effect */
+ IX_NPEMH_REGISTER_WRITE_BITS (controlReg,
+ (IX_NPEMH_NPE_CTL_OFE |
+ IX_NPEMH_NPE_CTL_OFEWE),
+ (IX_NPEMH_NPE_CTL_OFE |
+ IX_NPEMH_NPE_CTL_OFEWE));
+ }
+
+ /* return the previous state of the interrupt */
+ return (ofe != 0);
+}
+
+/*
+ * Function definition: ixNpeMhConfigNpeInterruptDisable
+ */
+
+BOOL ixNpeMhConfigNpeInterruptDisable (
+ IxNpeMhNpeId npeId)
+{
+ UINT32 ofe;
+ volatile UINT32 *controlReg =
+ (UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister;
+
+ /* get the OFE (OutFifoEnable) bit of the control register */
+ IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE);
+
+ /* if the interrupt is enabled then we must disable it */
+ if (ofe)
+ {
+ /* unset the OFE (OutFifoEnable) bit of the control register */
+ /* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */
+ /* time for the write to have effect */
+ IX_NPEMH_REGISTER_WRITE_BITS (controlReg,
+ (0 |
+ IX_NPEMH_NPE_CTL_OFEWE),
+ (IX_NPEMH_NPE_CTL_OFE |
+ IX_NPEMH_NPE_CTL_OFEWE));
+ }
+
+ /* return the previous state of the interrupt */
+ return (ofe != 0);
+}
+
+/*
+ * Function definition: ixNpeMhConfigMessageIdGet
+ */
+
+IxNpeMhMessageId ixNpeMhConfigMessageIdGet (
+ IxNpeMhMessage message)
+{
+ /* return the most-significant byte of the first word of the */
+ /* message */
+ return ((IxNpeMhMessageId) ((message.data[0] >> 24) & 0xFF));
+}
+
+/*
+ * Function definition: ixNpeMhConfigNpeIdIsValid
+ */
+
+BOOL ixNpeMhConfigNpeIdIsValid (
+ IxNpeMhNpeId npeId)
+{
+ /* check that the npeId parameter is within the range of valid IDs */
+ return (npeId >= 0 && npeId < IX_NPEMH_NUM_NPES);
+}
+
+/*
+ * Function definition: ixNpeMhConfigLockGet
+ */
+
+void ixNpeMhConfigLockGet (
+ IxNpeMhNpeId npeId)
+{
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhConfigLockGet\n");
+
+ /* lock the mutex for this NPE */
+ (void) ixOsalMutexLock (&ixNpeMhConfigNpeInfo[npeId].mutex,
+ IX_OSAL_WAIT_FOREVER);
+
+ /* disable the NPE's "outFIFO not empty" interrupt */
+ ixNpeMhConfigNpeInfo[npeId].oldInterruptState =
+ ixNpeMhConfigNpeInterruptDisable (npeId);
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhConfigLockGet\n");
+}
+
+/*
+ * Function definition: ixNpeMhConfigLockRelease
+ */
+
+void ixNpeMhConfigLockRelease (
+ IxNpeMhNpeId npeId)
+{
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhConfigLockRelease\n");
+
+ /* if the interrupt was previously enabled */
+ if (ixNpeMhConfigNpeInfo[npeId].oldInterruptState)
+ {
+ /* enable the NPE's "outFIFO not empty" interrupt */
+ ixNpeMhConfigNpeInfo[npeId].oldInterruptState =
+ ixNpeMhConfigNpeInterruptEnable (npeId);
+ }
+
+ /* unlock the mutex for this NPE */
+ (void) ixOsalMutexUnlock (&ixNpeMhConfigNpeInfo[npeId].mutex);
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhConfigLockRelease\n");
+}
+
+/*
+ * Function definition: ixNpeMhConfigInFifoWrite
+ */
+
+IX_STATUS ixNpeMhConfigInFifoWrite (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage message)
+{
+ volatile UINT32 *npeInFifo =
+ (UINT32 *)ixNpeMhConfigNpeInfo[npeId].inFifoRegister;
+ UINT32 retriesCount = 0;
+
+ /* write the first word of the message to the NPE's inFIFO */
+ IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[0]);
+
+ /* need to wait for room to write second word - see SCR #493,
+ poll for maximum number of retries, if exceed maximum
+ retries, exit from while loop */
+ while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount)
+ && ixNpeMhConfigInFifoIsFull (npeId))
+ {
+ retriesCount++;
+ }
+
+ /* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */
+ if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount)
+ {
+ return IX_NPEMH_CRITICAL_NPE_ERR;
+ }
+
+ /* write the second word of the message to the NPE's inFIFO */
+ IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[1]);
+
+ /* record in the stats the maximum number of retries needed */
+ if (ixNpeMhConfigStats[npeId].maxInFifoFullRetries < retriesCount)
+ {
+ ixNpeMhConfigStats[npeId].maxInFifoFullRetries = retriesCount;
+ }
+
+ /* update statistical info */
+ ixNpeMhConfigStats[npeId].inFifoWrites++;
+
+ return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeMhConfigOutFifoRead
+ */
+
+IX_STATUS ixNpeMhConfigOutFifoRead (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage *message)
+{
+ volatile UINT32 *npeOutFifo =
+ (UINT32 *)ixNpeMhConfigNpeInfo[npeId].outFifoRegister;
+ UINT32 retriesCount = 0;
+
+ /* read the first word of the message from the NPE's outFIFO */
+ IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[0]);
+
+ /* need to wait for NPE to write second word - see SCR #493
+ poll for maximum number of retries, if exceed maximum
+ retries, exit from while loop */
+ while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount)
+ && ixNpeMhConfigOutFifoIsEmpty (npeId))
+ {
+ retriesCount++;
+ }
+
+ /* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */
+ if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount)
+ {
+ return IX_NPEMH_CRITICAL_NPE_ERR;
+ }
+
+ /* read the second word of the message from the NPE's outFIFO */
+ IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[1]);
+
+ /* record in the stats the maximum number of retries needed */
+ if (ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries < retriesCount)
+ {
+ ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = retriesCount;
+ }
+
+ /* update statistical info */
+ ixNpeMhConfigStats[npeId].outFifoReads++;
+
+ return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeMhConfigShow
+ */
+
+void ixNpeMhConfigShow (
+ IxNpeMhNpeId npeId)
+{
+ /* show the message fifo read counter */
+ IX_NPEMH_SHOW ("Message FIFO reads",
+ ixNpeMhConfigStats[npeId].outFifoReads);
+
+ /* show the message fifo write counter */
+ IX_NPEMH_SHOW ("Message FIFO writes",
+ ixNpeMhConfigStats[npeId].inFifoWrites);
+
+ /* show the max retries performed when inFIFO full */
+ IX_NPEMH_SHOW ("Max inFIFO Full retries",
+ ixNpeMhConfigStats[npeId].maxInFifoFullRetries);
+
+ /* show the max retries performed when outFIFO empty */
+ IX_NPEMH_SHOW ("Max outFIFO Empty retries",
+ ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries);
+
+ /* show the current status of the inFifo */
+ ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
+ "InFifo is %s and %s\n",
+ (ixNpeMhConfigInFifoIsEmpty (npeId) ?
+ (int) "EMPTY" : (int) "NOT EMPTY"),
+ (ixNpeMhConfigInFifoIsFull (npeId) ?
+ (int) "FULL" : (int) "NOT FULL"),
+ 0, 0, 0, 0);
+
+ /* show the current status of the outFifo */
+ ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
+ "OutFifo is %s and %s\n",
+ (ixNpeMhConfigOutFifoIsEmpty (npeId) ?
+ (int) "EMPTY" : (int) "NOT EMPTY"),
+ (ixNpeMhConfigOutFifoIsFull (npeId) ?
+ (int) "FULL" : (int) "NOT FULL"),
+ 0, 0, 0, 0);
+}
+
+/*
+ * Function definition: ixNpeMhConfigShowReset
+ */
+
+void ixNpeMhConfigShowReset (
+ IxNpeMhNpeId npeId)
+{
+ /* reset the message fifo read counter */
+ ixNpeMhConfigStats[npeId].outFifoReads = 0;
+
+ /* reset the message fifo write counter */
+ ixNpeMhConfigStats[npeId].inFifoWrites = 0;
+
+ /* reset the max inFIFO Full retries counter */
+ ixNpeMhConfigStats[npeId].maxInFifoFullRetries = 0;
+
+ /* reset the max outFIFO empty retries counter */
+ ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = 0;
+}
+
+
diff --git a/cpu/ixp/npe/IxNpeMhReceive.c b/cpu/ixp/npe/IxNpeMhReceive.c
new file mode 100644
index 0000000..57c8be3
--- /dev/null
+++ b/cpu/ixp/npe/IxNpeMhReceive.c
@@ -0,0 +1,320 @@
+/**
+ * @file IxNpeMhReceive.c
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the implementation of the private API for the
+ * Receive module.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * Put the system defined include files required.
+ */
+
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxOsal.h"
+#include "IxNpeMhMacros_p.h"
+#include "IxNpeMhConfig_p.h"
+#include "IxNpeMhReceive_p.h"
+#include "IxNpeMhSolicitedCbMgr_p.h"
+#include "IxNpeMhUnsolicitedCbMgr_p.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/**
+ * @struct IxNpeMhReceiveStats
+ *
+ * @brief This structure is used to maintain statistics for the Receive
+ * module.
+ */
+
+typedef struct
+{
+ UINT32 isrs; /**< receive ISR invocations */
+ UINT32 receives; /**< receive messages invocations */
+ UINT32 messages; /**< messages received */
+ UINT32 solicited; /**< solicited messages received */
+ UINT32 unsolicited; /**< unsolicited messages received */
+ UINT32 callbacks; /**< callbacks invoked */
+} IxNpeMhReceiveStats;
+
+/*
+ * Variable declarations global to this file only. Externs are followed by
+ * static variables.
+ */
+
+PRIVATE IxNpeMhReceiveStats ixNpeMhReceiveStats[IX_NPEMH_NUM_NPES];
+
+/*
+ * Extern function prototypes.
+ */
+
+/*
+ * Static function prototypes.
+ */
+PRIVATE
+void ixNpeMhReceiveIsr (int npeId);
+
+PRIVATE
+void ixNpeMhReceiveIsr (int npeId)
+{
+ int lockKey;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhReceiveIsr\n");
+
+ lockKey = ixOsalIrqLock ();
+
+ /* invoke the message receive routine to get messages from the NPE */
+ ixNpeMhReceiveMessagesReceive (npeId);
+
+ /* update statistical info */
+ ixNpeMhReceiveStats[npeId].isrs++;
+
+ ixOsalIrqUnlock (lockKey);
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhReceiveIsr\n");
+}
+
+/*
+ * Function definition: ixNpeMhReceiveInitialize
+ */
+
+void ixNpeMhReceiveInitialize (void)
+{
+ IxNpeMhNpeId npeId = 0;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhReceiveInitialize\n");
+
+ /* for each NPE ... */
+ for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
+ {
+ /* register our internal ISR for the NPE to handle "outFIFO not */
+ /* empty" interrupts */
+ ixNpeMhConfigIsrRegister (npeId, ixNpeMhReceiveIsr);
+ }
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhReceiveInitialize\n");
+}
+
+/*
+ * Function definition: ixNpeMhReceiveMessagesReceive
+ */
+
+IX_STATUS ixNpeMhReceiveMessagesReceive (
+ IxNpeMhNpeId npeId)
+{
+ IxNpeMhMessage message = { { 0, 0 } };
+ IxNpeMhMessageId messageId = 0;
+ IxNpeMhCallback callback = NULL;
+ IX_STATUS status;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhReceiveMessagesReceive\n");
+
+ /* update statistical info */
+ ixNpeMhReceiveStats[npeId].receives++;
+
+ /* while the NPE has messages in its outFIFO */
+ while (!ixNpeMhConfigOutFifoIsEmpty (npeId))
+ {
+ /* read a message from the NPE's outFIFO */
+ status = ixNpeMhConfigOutFifoRead (npeId, &message);
+
+ if (IX_SUCCESS != status)
+ {
+ return status;
+ }
+
+ /* get the ID of the message */
+ messageId = ixNpeMhConfigMessageIdGet (message);
+
+ IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG,
+ "Received message from NPE %d with ID 0x%02X\n",
+ npeId, messageId);
+
+ /* update statistical info */
+ ixNpeMhReceiveStats[npeId].messages++;
+
+ /* try to find a matching unsolicited callback for this message. */
+
+ /* we assume the message is unsolicited. only if there is no */
+ /* unsolicited callback for this message type do we assume the */
+ /* message is solicited. it is much faster to check for an */
+ /* unsolicited callback, so doing this check first should result */
+ /* in better performance. */
+
+ ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
+ npeId, messageId, &callback);
+
+ if (callback != NULL)
+ {
+ IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG,
+ "Found matching unsolicited callback\n");
+
+ /* update statistical info */
+ ixNpeMhReceiveStats[npeId].unsolicited++;
+ }
+
+ /* if no unsolicited callback was found try to find a matching */
+ /* solicited callback for this message */
+ if (callback == NULL)
+ {
+ ixNpeMhSolicitedCbMgrCallbackRetrieve (
+ npeId, messageId, &callback);
+
+ if (callback != NULL)
+ {
+ IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG,
+ "Found matching solicited callback\n");
+
+ /* update statistical info */
+ ixNpeMhReceiveStats[npeId].solicited++;
+ }
+ }
+
+ /* if a callback (either unsolicited or solicited) was found */
+ if (callback != NULL)
+ {
+ /* invoke the callback to pass the message back to the client */
+ callback (npeId, message);
+
+ /* update statistical info */
+ ixNpeMhReceiveStats[npeId].callbacks++;
+ }
+ else /* no callback (neither unsolicited nor solicited) was found */
+ {
+ IX_NPEMH_TRACE2 (IX_NPEMH_WARNING,
+ "No matching callback for NPE %d"
+ " and ID 0x%02X, discarding message\n",
+ npeId, messageId);
+
+ /* the message will be discarded. this is normal behaviour */
+ /* if the client passes a NULL solicited callback when */
+ /* sending a message. this indicates that the client is not */
+ /* interested in receiving the response. alternatively a */
+ /* NULL callback here may signify an unsolicited message */
+ /* with no appropriate registered callback. */
+ }
+ }
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhReceiveMessagesReceive\n");
+
+ return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeMhReceiveShow
+ */
+
+void ixNpeMhReceiveShow (
+ IxNpeMhNpeId npeId)
+{
+ /* show the ISR invocation counter */
+ IX_NPEMH_SHOW ("Receive ISR invocations",
+ ixNpeMhReceiveStats[npeId].isrs);
+
+ /* show the receive message invocation counter */
+ IX_NPEMH_SHOW ("Receive messages invocations",
+ ixNpeMhReceiveStats[npeId].receives);
+
+ /* show the message received counter */
+ IX_NPEMH_SHOW ("Messages received",
+ ixNpeMhReceiveStats[npeId].messages);
+
+ /* show the solicited message counter */
+ IX_NPEMH_SHOW ("Solicited messages received",
+ ixNpeMhReceiveStats[npeId].solicited);
+
+ /* show the unsolicited message counter */
+ IX_NPEMH_SHOW ("Unsolicited messages received",
+ ixNpeMhReceiveStats[npeId].unsolicited);
+
+ /* show the callback invoked counter */
+ IX_NPEMH_SHOW ("Callbacks invoked",
+ ixNpeMhReceiveStats[npeId].callbacks);
+
+ /* show the message discarded counter */
+ IX_NPEMH_SHOW ("Received messages discarded",
+ (ixNpeMhReceiveStats[npeId].messages -
+ ixNpeMhReceiveStats[npeId].callbacks));
+}
+
+/*
+ * Function definition: ixNpeMhReceiveShowReset
+ */
+
+void ixNpeMhReceiveShowReset (
+ IxNpeMhNpeId npeId)
+{
+ /* reset the ISR invocation counter */
+ ixNpeMhReceiveStats[npeId].isrs = 0;
+
+ /* reset the receive message invocation counter */
+ ixNpeMhReceiveStats[npeId].receives = 0;
+
+ /* reset the message received counter */
+ ixNpeMhReceiveStats[npeId].messages = 0;
+
+ /* reset the solicited message counter */
+ ixNpeMhReceiveStats[npeId].solicited = 0;
+
+ /* reset the unsolicited message counter */
+ ixNpeMhReceiveStats[npeId].unsolicited = 0;
+
+ /* reset the callback invoked counter */
+ ixNpeMhReceiveStats[npeId].callbacks = 0;
+}
diff --git a/cpu/ixp/npe/IxNpeMhSend.c b/cpu/ixp/npe/IxNpeMhSend.c
new file mode 100644
index 0000000..318913a
--- /dev/null
+++ b/cpu/ixp/npe/IxNpeMhSend.c
@@ -0,0 +1,307 @@
+/**
+ * @file IxNpeMhSend.c
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the implementation of the private API for the
+ * Send module.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * Put the system defined include files required.
+ */
+
+
+/*
+ * Put the user defined include files required.
+ */
+
+#include "IxNpeMhMacros_p.h"
+
+#include "IxNpeMhConfig_p.h"
+#include "IxNpeMhSend_p.h"
+#include "IxNpeMhSolicitedCbMgr_p.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/**
+ * @def IX_NPEMH_INFIFO_RETRY_DELAY_US
+ *
+ * @brief Amount of time (uSecs) to delay between retries
+ * while inFIFO is Full when attempting to send a message
+ */
+#define IX_NPEMH_INFIFO_RETRY_DELAY_US (1)
+
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/**
+ * @struct IxNpeMhSendStats
+ *
+ * @brief This structure is used to maintain statistics for the Send
+ * module.
+ */
+
+typedef struct
+{
+ UINT32 sends; /**< send invocations */
+ UINT32 sendWithResponses; /**< send with response invocations */
+ UINT32 queueFulls; /**< fifo queue full occurrences */
+ UINT32 queueFullRetries; /**< fifo queue full retry occurrences */
+ UINT32 maxQueueFullRetries; /**< max fifo queue full retries */
+ UINT32 callbackFulls; /**< callback list full occurrences */
+} IxNpeMhSendStats;
+
+/*
+ * Variable declarations global to this file only. Externs are followed by
+ * static variables.
+ */
+
+PRIVATE IxNpeMhSendStats ixNpeMhSendStats[IX_NPEMH_NUM_NPES];
+
+/*
+ * Extern function prototypes.
+ */
+
+/*
+ * Static function prototypes.
+ */
+PRIVATE
+BOOL ixNpeMhSendInFifoIsFull(
+ IxNpeMhNpeId npeId,
+ UINT32 maxSendRetries);
+
+/*
+ * Function definition: ixNpeMhSendInFifoIsFull
+ */
+
+PRIVATE
+BOOL ixNpeMhSendInFifoIsFull(
+ IxNpeMhNpeId npeId,
+ UINT32 maxSendRetries)
+{
+ BOOL isFull = FALSE;
+ UINT32 numRetries = 0;
+
+ /* check the NPE's inFIFO */
+ isFull = ixNpeMhConfigInFifoIsFull (npeId);
+
+ /* we retry a few times, just to give the NPE a chance to read from */
+ /* the FIFO if the FIFO is currently full */
+ while (isFull && (numRetries++ < maxSendRetries))
+ {
+ if (numRetries >= IX_NPEMH_SEND_RETRIES_DEFAULT)
+ {
+ /* Delay here for as short a time as possible (1 us). */
+ /* Adding a delay here should ensure we are not hogging */
+ /* the AHB bus while we are retrying */
+ ixOsalBusySleep (IX_NPEMH_INFIFO_RETRY_DELAY_US);
+ }
+
+ /* re-check the NPE's inFIFO */
+ isFull = ixNpeMhConfigInFifoIsFull (npeId);
+
+ /* update statistical info */
+ ixNpeMhSendStats[npeId].queueFullRetries++;
+ }
+
+ /* record the highest number of retries that occurred */
+ if (ixNpeMhSendStats[npeId].maxQueueFullRetries < numRetries)
+ {
+ ixNpeMhSendStats[npeId].maxQueueFullRetries = numRetries;
+ }
+
+ if (isFull)
+ {
+ /* update statistical info */
+ ixNpeMhSendStats[npeId].queueFulls++;
+ }
+
+ return isFull;
+}
+
+/*
+ * Function definition: ixNpeMhSendMessageSend
+ */
+
+IX_STATUS ixNpeMhSendMessageSend (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage message,
+ UINT32 maxSendRetries)
+{
+ IX_STATUS status;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhSendMessageSend\n");
+
+ /* update statistical info */
+ ixNpeMhSendStats[npeId].sends++;
+
+ /* check if the NPE's inFIFO is full - if so return an error */
+ if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries))
+ {
+ IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n");
+ return IX_FAIL;
+ }
+
+ /* write the message to the NPE's inFIFO */
+ status = ixNpeMhConfigInFifoWrite (npeId, message);
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhSendMessageSend\n");
+
+ return status;
+}
+
+/*
+ * Function definition: ixNpeMhSendMessageWithResponseSend
+ */
+
+IX_STATUS ixNpeMhSendMessageWithResponseSend (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage message,
+ IxNpeMhMessageId solicitedMessageId,
+ IxNpeMhCallback solicitedCallback,
+ UINT32 maxSendRetries)
+{
+ IX_STATUS status = IX_SUCCESS;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhSendMessageWithResponseSend\n");
+
+ /* update statistical info */
+ ixNpeMhSendStats[npeId].sendWithResponses++;
+
+ /* sr: this sleep will call the receive routine (no interrupts used!!!) */
+ ixOsalSleep (IX_NPEMH_INFIFO_RETRY_DELAY_US);
+
+ /* check if the NPE's inFIFO is full - if so return an error */
+ if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries))
+ {
+ IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n");
+ return IX_FAIL;
+ }
+
+ /* save the solicited callback */
+ status = ixNpeMhSolicitedCbMgrCallbackSave (
+ npeId, solicitedMessageId, solicitedCallback);
+ if (status != IX_SUCCESS)
+ {
+ IX_NPEMH_ERROR_REPORT ("Failed to save solicited callback\n");
+
+ /* update statistical info */
+ ixNpeMhSendStats[npeId].callbackFulls++;
+
+ return status;
+ }
+
+ /* write the message to the NPE's inFIFO */
+ status = ixNpeMhConfigInFifoWrite (npeId, message);
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhSendMessageWithResponseSend\n");
+
+ return status;
+}
+
+/*
+ * Function definition: ixNpeMhSendShow
+ */
+
+void ixNpeMhSendShow (
+ IxNpeMhNpeId npeId)
+{
+ /* show the message send invocation counter */
+ IX_NPEMH_SHOW ("Send invocations",
+ ixNpeMhSendStats[npeId].sends);
+
+ /* show the message send with response invocation counter */
+ IX_NPEMH_SHOW ("Send with response invocations",
+ ixNpeMhSendStats[npeId].sendWithResponses);
+
+ /* show the fifo queue full occurrence counter */
+ IX_NPEMH_SHOW ("Fifo queue full occurrences",
+ ixNpeMhSendStats[npeId].queueFulls);
+
+ /* show the fifo queue full retry occurrence counter */
+ IX_NPEMH_SHOW ("Fifo queue full retry occurrences",
+ ixNpeMhSendStats[npeId].queueFullRetries);
+
+ /* show the fifo queue full maximum retries counter */
+ IX_NPEMH_SHOW ("Maximum fifo queue full retries",
+ ixNpeMhSendStats[npeId].maxQueueFullRetries);
+
+ /* show the callback list full occurrence counter */
+ IX_NPEMH_SHOW ("Solicited callback list full occurrences",
+ ixNpeMhSendStats[npeId].callbackFulls);
+}
+
+/*
+ * Function definition: ixNpeMhSendShowReset
+ */
+
+void ixNpeMhSendShowReset (
+ IxNpeMhNpeId npeId)
+{
+ /* reset the message send invocation counter */
+ ixNpeMhSendStats[npeId].sends = 0;
+
+ /* reset the message send with response invocation counter */
+ ixNpeMhSendStats[npeId].sendWithResponses = 0;
+
+ /* reset the fifo queue full occurrence counter */
+ ixNpeMhSendStats[npeId].queueFulls = 0;
+
+ /* reset the fifo queue full retry occurrence counter */
+ ixNpeMhSendStats[npeId].queueFullRetries = 0;
+
+ /* reset the max fifo queue full retries counter */
+ ixNpeMhSendStats[npeId].maxQueueFullRetries = 0;
+
+ /* reset the callback list full occurrence counter */
+ ixNpeMhSendStats[npeId].callbackFulls = 0;
+}
diff --git a/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c b/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c
new file mode 100644
index 0000000..8e083a6
--- /dev/null
+++ b/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c
@@ -0,0 +1,358 @@
+/**
+ * @file IxNpeMhSolicitedCbMgr.c
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the implementation of the private API for the
+ * Solicited Callback Manager module.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+#ifndef IXNPEMHCONFIG_P_H
+# define IXNPEMHSOLICITEDCBMGR_C
+#else
+# error "Error, IxNpeMhConfig_p.h should not be included before this definition."
+#endif
+
+/*
+ * Put the system defined include files required.
+ */
+
+
+/*
+ * Put the user defined include files required.
+ */
+
+#include "IxOsal.h"
+
+#include "IxNpeMhMacros_p.h"
+#include "IxNpeMhSolicitedCbMgr_p.h"
+#include "IxNpeMhConfig_p.h"
+/*
+ * #defines and macros used in this file.
+ */
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/**
+ * @struct IxNpeMhSolicitedCallbackListEntry
+ *
+ * @brief This structure is used to store the information associated with
+ * an entry in the callback list. This consists of the ID of the send
+ * message (which indicates the ID of the corresponding response message)
+ * and the callback function pointer itself.
+ *
+ */
+
+typedef struct IxNpeMhSolicitedCallbackListEntry
+{
+ /** message ID */
+ IxNpeMhMessageId messageId;
+
+ /** callback function pointer */
+ IxNpeMhCallback callback;
+
+ /** pointer to next entry in the list */
+ struct IxNpeMhSolicitedCallbackListEntry *next;
+} IxNpeMhSolicitedCallbackListEntry;
+
+/**
+ * @struct IxNpeMhSolicitedCallbackList
+ *
+ * @brief This structure is used to maintain the list of response
+ * callbacks. The number of entries in this list will be variable, and
+ * they will be stored in a linked list fashion for ease of addition and
+ * removal. The entries themselves are statically allocated, and are
+ * organised into a "free" list and a "callback" list. Adding an entry
+ * means taking an entry from the "free" list and adding it to the
+ * "callback" list. Removing an entry means removing it from the
+ * "callback" list and returning it to the "free" list.
+ */
+
+typedef struct
+{
+ /** pointer to the head of the free list */
+ IxNpeMhSolicitedCallbackListEntry *freeHead;
+
+ /** pointer to the head of the callback list */
+ IxNpeMhSolicitedCallbackListEntry *callbackHead;
+
+ /** pointer to the tail of the callback list */
+ IxNpeMhSolicitedCallbackListEntry *callbackTail;
+
+ /** array of entries - the first entry is used as a dummy entry to */
+ /* avoid the scenario of having an empty list, hence '+ 1' */
+ IxNpeMhSolicitedCallbackListEntry entries[IX_NPEMH_MAX_CALLBACKS + 1];
+} IxNpeMhSolicitedCallbackList;
+
+/**
+ * @struct IxNpeMhSolicitedCbMgrStats
+ *
+ * @brief This structure is used to maintain statistics for the Solicited
+ * Callback Manager module.
+ */
+
+typedef struct
+{
+ UINT32 saves; /**< callback list saves */
+ UINT32 retrieves; /**< callback list retrieves */
+} IxNpeMhSolicitedCbMgrStats;
+
+/*
+ * Variable declarations global to this file only. Externs are followed by
+ * static variables.
+ */
+
+PRIVATE IxNpeMhSolicitedCallbackList
+ixNpeMhSolicitedCbMgrCallbackLists[IX_NPEMH_NUM_NPES];
+
+PRIVATE IxNpeMhSolicitedCbMgrStats
+ixNpeMhSolicitedCbMgrStats[IX_NPEMH_NUM_NPES];
+
+/*
+ * Extern function prototypes.
+ */
+
+/*
+ * Static function prototypes.
+ */
+
+/*
+ * Function definition: ixNpeMhSolicitedCbMgrInitialize
+ */
+
+void ixNpeMhSolicitedCbMgrInitialize (void)
+{
+ IxNpeMhNpeId npeId;
+ UINT32 localIndex;
+ IxNpeMhSolicitedCallbackList *list = NULL;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhSolicitedCbMgrInitialize\n");
+
+ /* for each NPE ... */
+ for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
+ {
+ /* initialise a pointer to the list for convenience */
+ list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
+
+ /* for each entry in the list, after the dummy entry ... */
+ for (localIndex = 1; localIndex <= IX_NPEMH_MAX_CALLBACKS; localIndex++)
+ {
+ /* initialise the entry */
+ list->entries[localIndex].messageId = 0x00;
+ list->entries[localIndex].callback = NULL;
+
+ /* if this entry is before the last entry */
+ if (localIndex < IX_NPEMH_MAX_CALLBACKS)
+ {
+ /* chain this entry to the following entry */
+ list->entries[localIndex].next = &(list->entries[localIndex + 1]);
+ }
+ else /* this entry is the last entry */
+ {
+ /* the last entry isn't chained to anything */
+ list->entries[localIndex].next = NULL;
+ }
+ }
+
+ /* set the free list pointer to point to the first real entry */
+ /* (all real entries begin chained together on the free list) */
+ list->freeHead = &(list->entries[1]);
+
+ /* set the callback list pointers to point to the dummy entry */
+ /* (the callback list is initially empty) */
+ list->callbackHead = &(list->entries[0]);
+ list->callbackTail = &(list->entries[0]);
+ }
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhSolicitedCbMgrInitialize\n");
+}
+
+/*
+ * Function definition: ixNpeMhSolicitedCbMgrCallbackSave
+ */
+
+IX_STATUS ixNpeMhSolicitedCbMgrCallbackSave (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId solicitedMessageId,
+ IxNpeMhCallback solicitedCallback)
+{
+ IxNpeMhSolicitedCallbackList *list = NULL;
+ IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhSolicitedCbMgrCallbackSave\n");
+
+ /* initialise a pointer to the list for convenience */
+ list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
+
+ /* check to see if there are any entries in the free list */
+ if (list->freeHead == NULL)
+ {
+ IX_NPEMH_ERROR_REPORT ("Solicited callback list is full\n");
+ return IX_FAIL;
+ }
+
+ /* there is an entry in the free list we can use */
+
+ /* update statistical info */
+ ixNpeMhSolicitedCbMgrStats[npeId].saves++;
+
+ /* remove a callback entry from the start of the free list */
+ callbackEntry = list->freeHead;
+ list->freeHead = callbackEntry->next;
+
+ /* fill in the callback entry with the new data */
+ callbackEntry->messageId = solicitedMessageId;
+ callbackEntry->callback = solicitedCallback;
+
+ /* the new callback entry will be added to the tail of the callback */
+ /* list, so it isn't chained to anything */
+ callbackEntry->next = NULL;
+
+ /* chain new callback entry to the last entry of the callback list */
+ list->callbackTail->next = callbackEntry;
+ list->callbackTail = callbackEntry;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhSolicitedCbMgrCallbackSave\n");
+
+ return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeMhSolicitedCbMgrCallbackRetrieve
+ */
+
+void ixNpeMhSolicitedCbMgrCallbackRetrieve (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId solicitedMessageId,
+ IxNpeMhCallback *solicitedCallback)
+{
+ IxNpeMhSolicitedCallbackList *list = NULL;
+ IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL;
+ IxNpeMhSolicitedCallbackListEntry *previousEntry = NULL;
+
+ /* initialise a pointer to the list for convenience */
+ list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
+
+ /* initialise the callback entry to the first entry of the callback */
+ /* list - we must skip over the dummy entry, which is the previous */
+ callbackEntry = list->callbackHead->next;
+ previousEntry = list->callbackHead;
+
+ /* traverse the callback list looking for an entry with a matching */
+ /* message ID. note we also save the previous entry's pointer to */
+ /* allow us to unchain the matching entry from the callback list */
+ while ((callbackEntry != NULL) &&
+ (callbackEntry->messageId != solicitedMessageId))
+ {
+ previousEntry = callbackEntry;
+ callbackEntry = callbackEntry->next;
+ }
+
+ /* if we didn't find a matching callback entry */
+ if (callbackEntry == NULL)
+ {
+ /* return a NULL callback in the outgoing parameter */
+ *solicitedCallback = NULL;
+ }
+ else /* we found a matching callback entry */
+ {
+ /* update statistical info */
+ ixNpeMhSolicitedCbMgrStats[npeId].retrieves++;
+
+ /* return the callback in the outgoing parameter */
+ *solicitedCallback = callbackEntry->callback;
+
+ /* unchain callback entry by chaining previous entry to next */
+ previousEntry->next = callbackEntry->next;
+
+ /* if the callback entry is at the tail of the list */
+ if (list->callbackTail == callbackEntry)
+ {
+ /* update the tail of the callback list */
+ list->callbackTail = previousEntry;
+ }
+
+ /* re-initialise the callback entry */
+ callbackEntry->messageId = 0x00;
+ callbackEntry->callback = NULL;
+
+ /* add the callback entry to the start of the free list */
+ callbackEntry->next = list->freeHead;
+ list->freeHead = callbackEntry;
+ }
+}
+
+/*
+ * Function definition: ixNpeMhSolicitedCbMgrShow
+ */
+
+void ixNpeMhSolicitedCbMgrShow (
+ IxNpeMhNpeId npeId)
+{
+ /* show the solicited callback list save counter */
+ IX_NPEMH_SHOW ("Solicited callback list saves",
+ ixNpeMhSolicitedCbMgrStats[npeId].saves);
+
+ /* show the solicited callback list retrieve counter */
+ IX_NPEMH_SHOW ("Solicited callback list retrieves",
+ ixNpeMhSolicitedCbMgrStats[npeId].retrieves);
+}
+
+/*
+ * Function definition: ixNpeMhSolicitedCbMgrShowReset
+ */
+
+void ixNpeMhSolicitedCbMgrShowReset (
+ IxNpeMhNpeId npeId)
+{
+ /* reset the solicited callback list save counter */
+ ixNpeMhSolicitedCbMgrStats[npeId].saves = 0;
+
+ /* reset the solicited callback list retrieve counter */
+ ixNpeMhSolicitedCbMgrStats[npeId].retrieves = 0;
+}
diff --git a/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c b/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c
new file mode 100644
index 0000000..d37f9f9
--- /dev/null
+++ b/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c
@@ -0,0 +1,246 @@
+/**
+ * @file IxNpeMhUnsolicitedCbMgr.c
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the implementation of the private API for
+ * the Unsolicited Callback Manager module.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * Put the system defined include files required.
+ */
+
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxOsal.h"
+
+#include "IxNpeMhMacros_p.h"
+
+#include "IxNpeMhUnsolicitedCbMgr_p.h"
+
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/**
+ * @struct IxNpeMhUnsolicitedCallbackTable
+ *
+ * @brief This structure is used to maintain the list of registered
+ * callbacks. One entry exists for each message ID, and a NULL entry will
+ * signify that no callback has been registered for that ID.
+ */
+
+typedef struct
+{
+ /** array of entries */
+ IxNpeMhCallback entries[IX_NPEMH_MAX_MESSAGE_ID + 1];
+} IxNpeMhUnsolicitedCallbackTable;
+
+/**
+ * @struct IxNpeMhUnsolicitedCbMgrStats
+ *
+ * @brief This structure is used to maintain statistics for the Unsolicited
+ * Callback Manager module.
+ */
+
+typedef struct
+{
+ UINT32 saves; /**< callback table saves */
+ UINT32 overwrites; /**< callback table overwrites */
+} IxNpeMhUnsolicitedCbMgrStats;
+
+/*
+ * Variable declarations global to this file only. Externs are followed by
+ * static variables.
+ */
+
+PRIVATE IxNpeMhUnsolicitedCallbackTable
+ixNpeMhUnsolicitedCallbackTables[IX_NPEMH_NUM_NPES];
+
+PRIVATE IxNpeMhUnsolicitedCbMgrStats
+ixNpeMhUnsolicitedCbMgrStats[IX_NPEMH_NUM_NPES];
+
+/*
+ * Extern function prototypes.
+ */
+
+/*
+ * Static function prototypes.
+ */
+
+/*
+ * Function definition: ixNpeMhUnsolicitedCbMgrInitialize
+ */
+
+void ixNpeMhUnsolicitedCbMgrInitialize (void)
+{
+ IxNpeMhNpeId npeId = 0;
+ IxNpeMhUnsolicitedCallbackTable *table = NULL;
+ IxNpeMhMessageId messageId = 0;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhUnsolicitedCbMgrInitialize\n");
+
+ /* for each NPE ... */
+ for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
+ {
+ /* initialise a pointer to the table for convenience */
+ table = &ixNpeMhUnsolicitedCallbackTables[npeId];
+
+ /* for each message ID ... */
+ for (messageId = IX_NPEMH_MIN_MESSAGE_ID;
+ messageId <= IX_NPEMH_MAX_MESSAGE_ID; messageId++)
+ {
+ /* initialise the callback for this message ID to NULL */
+ table->entries[messageId] = NULL;
+ }
+ }
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhUnsolicitedCbMgrInitialize\n");
+}
+
+/*
+ * Function definition: ixNpeMhUnsolicitedCbMgrCallbackSave
+ */
+
+void ixNpeMhUnsolicitedCbMgrCallbackSave (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId unsolicitedMessageId,
+ IxNpeMhCallback unsolicitedCallback)
+{
+ IxNpeMhUnsolicitedCallbackTable *table = NULL;
+
+ /* initialise a pointer to the table for convenience */
+ table = &ixNpeMhUnsolicitedCallbackTables[npeId];
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+ "ixNpeMhUnsolicitedCbMgrCallbackSave\n");
+
+ /* update statistical info */
+ ixNpeMhUnsolicitedCbMgrStats[npeId].saves++;
+
+ /* check if there is a callback already registered for this NPE and */
+ /* message ID */
+ if (table->entries[unsolicitedMessageId] != NULL)
+ {
+ /* if we are overwriting an existing callback */
+ if (unsolicitedCallback != NULL)
+ {
+ IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "Unsolicited callback "
+ "overwriting existing callback for NPE ID %d "
+ "message ID 0x%02X\n", npeId, unsolicitedMessageId);
+ }
+ else /* if we are clearing an existing callback */
+ {
+ IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NULL unsolicited callback "
+ "clearing existing callback for NPE ID %d "
+ "message ID 0x%02X\n", npeId, unsolicitedMessageId);
+ }
+
+ /* update statistical info */
+ ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites++;
+ }
+
+ /* save the callback into the table */
+ table->entries[unsolicitedMessageId] = unsolicitedCallback;
+
+ IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+ "ixNpeMhUnsolicitedCbMgrCallbackSave\n");
+}
+
+/*
+ * Function definition: ixNpeMhUnsolicitedCbMgrCallbackRetrieve
+ */
+
+void ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId unsolicitedMessageId,
+ IxNpeMhCallback *unsolicitedCallback)
+{
+ IxNpeMhUnsolicitedCallbackTable *table = NULL;
+
+ /* initialise a pointer to the table for convenience */
+ table = &ixNpeMhUnsolicitedCallbackTables[npeId];
+
+ /* retrieve the callback from the table */
+ *unsolicitedCallback = table->entries[unsolicitedMessageId];
+}
+
+/*
+ * Function definition: ixNpeMhUnsolicitedCbMgrShow
+ */
+
+void ixNpeMhUnsolicitedCbMgrShow (
+ IxNpeMhNpeId npeId)
+{
+ /* show the unsolicited callback table save counter */
+ IX_NPEMH_SHOW ("Unsolicited callback table saves",
+ ixNpeMhUnsolicitedCbMgrStats[npeId].saves);
+
+ /* show the unsolicited callback table overwrite counter */
+ IX_NPEMH_SHOW ("Unsolicited callback table overwrites",
+ ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites);
+}
+
+/*
+ * Function definition: ixNpeMhUnsolicitedCbMgrShowReset
+ */
+
+void ixNpeMhUnsolicitedCbMgrShowReset (
+ IxNpeMhNpeId npeId)
+{
+ /* reset the unsolicited callback table save counter */
+ ixNpeMhUnsolicitedCbMgrStats[npeId].saves = 0;
+
+ /* reset the unsolicited callback table overwrite counter */
+ ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites = 0;
+}
diff --git a/cpu/ixp/npe/IxOsalBufferMgt.c b/cpu/ixp/npe/IxOsalBufferMgt.c
new file mode 100644
index 0000000..fa8db47
--- /dev/null
+++ b/cpu/ixp/npe/IxOsalBufferMgt.c
@@ -0,0 +1,800 @@
+/**
+ * @file IxOsalBufferMgt.c
+ *
+ * @brief Default buffer pool management and buffer management
+ * Implementation.
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/*
+ * OS may choose to use default bufferMgt by defining
+ * IX_OSAL_USE_DEFAULT_BUFFER_MGT in IxOsalOsBufferMgt.h
+ */
+
+#include "IxOsal.h"
+
+#define IX_OSAL_BUFFER_FREE_PROTECTION /* Define this to enable Illegal MBuf Freed Protection*/
+
+/*
+ * The implementation is only used when the following
+ * is defined.
+ */
+#ifdef IX_OSAL_USE_DEFAULT_BUFFER_MGT
+
+
+#define IX_OSAL_MBUF_SYS_SIGNATURE (0x8BADF00D)
+#define IX_OSAL_MBUF_SYS_SIGNATURE_MASK (0xEFFFFFFF)
+#define IX_OSAL_MBUF_USED_FLAG (0x10000000)
+#define IX_OSAL_MBUF_SYS_SIGNATURE_INIT(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr) = (UINT32)IX_OSAL_MBUF_SYS_SIGNATURE
+
+/*
+* This implementation is protect, the buffer pool management's ixOsalMBufFree
+* against an invalid MBUF pointer argument that already has been freed earlier
+* or in other words resides in the free pool of MBUFs. This added feature,
+* checks the MBUF "USED" FLAG. The Flag tells if the MBUF is still not freed
+* back to the Buffer Pool.
+* Disable this feature for performance reasons by undef
+* IX_OSAL_BUFFER_FREE_PROTECTION macro.
+*/
+#ifdef IX_OSAL_BUFFER_FREE_PROTECTION /*IX_OSAL_BUFFER_FREE_PROTECTION With Buffer Free protection*/
+
+#define IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) (IX_OSAL_MBUF_SIGNATURE (bufPtr)&(IX_OSAL_MBUF_SYS_SIGNATURE_MASK) )
+#define IX_OSAL_MBUF_SET_SYS_SIGNATURE(bufPtr) do { \
+ IX_OSAL_MBUF_SIGNATURE (bufPtr)&(~IX_OSAL_MBUF_SYS_SIGNATURE_MASK);\
+ IX_OSAL_MBUF_SIGNATURE (bufPtr)|=IX_OSAL_MBUF_SYS_SIGNATURE; \
+ }while(0)
+
+#define IX_OSAL_MBUF_SET_USED_FLAG(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr)|=IX_OSAL_MBUF_USED_FLAG
+#define IX_OSAL_MBUF_CLEAR_USED_FLAG(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr)&=~IX_OSAL_MBUF_USED_FLAG
+#define IX_OSAL_MBUF_ISSET_USED_FLAG(bufPtr) (IX_OSAL_MBUF_SIGNATURE (bufPtr)&IX_OSAL_MBUF_USED_FLAG)
+
+#else
+
+#define IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr)
+#define IX_OSAL_MBUF_SET_SYS_SIGNATURE(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr) = IX_OSAL_MBUF_SYS_SIGNATURE
+
+#endif /*IX_OSAL_BUFFER_FREE_PROTECTION With Buffer Free protection*/
+/*
+ * Variable declarations global to this file only. Externs are followed by
+ * static variables.
+ */
+
+/*
+ * A unit of 32, used to provide bit-shift for pool
+ * management. Needs some work if users want more than 32 pools.
+ */
+#define IX_OSAL_BUFF_FREE_BITS 32
+
+PRIVATE UINT32 ixOsalBuffFreePools[IX_OSAL_MBUF_MAX_POOLS /
+ IX_OSAL_BUFF_FREE_BITS];
+
+PUBLIC IX_OSAL_MBUF_POOL ixOsalBuffPools[IX_OSAL_MBUF_MAX_POOLS];
+
+static int ixOsalBuffPoolsInUse = 0;
+
+#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
+PRIVATE IX_OSAL_MBUF *
+ixOsalBuffPoolMbufInit (UINT32 mbufSizeAligned,
+ UINT32 dataSizeAligned,
+ IX_OSAL_MBUF_POOL *poolPtr);
+#endif
+
+PRIVATE IX_OSAL_MBUF_POOL * ixOsalPoolAlloc (void);
+
+/*
+ * Function definition: ixOsalPoolAlloc
+ */
+
+/****************************/
+
+PRIVATE IX_OSAL_MBUF_POOL *
+ixOsalPoolAlloc (void)
+{
+ register unsigned int i = 0;
+
+ /*
+ * Scan for the first free buffer. Free buffers are indicated by 0
+ * on the corrsponding bit in ixOsalBuffFreePools.
+ */
+ if (ixOsalBuffPoolsInUse >= IX_OSAL_MBUF_MAX_POOLS)
+ {
+ /*
+ * Fail to grab a ptr this time
+ */
+ return NULL;
+ }
+
+ while (ixOsalBuffFreePools[i / IX_OSAL_BUFF_FREE_BITS] &
+ (1 << (i % IX_OSAL_BUFF_FREE_BITS)))
+ i++;
+ /*
+ * Free buffer found. Mark it as busy and initialize.
+ */
+ ixOsalBuffFreePools[i / IX_OSAL_BUFF_FREE_BITS] |=
+ (1 << (i % IX_OSAL_BUFF_FREE_BITS));
+
+ memset (&ixOsalBuffPools[i], 0, sizeof (IX_OSAL_MBUF_POOL));
+
+ ixOsalBuffPools[i].poolIdx = i;
+ ixOsalBuffPoolsInUse++;
+
+ return &ixOsalBuffPools[i];
+}
+
+
+#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
+PRIVATE IX_OSAL_MBUF *
+ixOsalBuffPoolMbufInit (UINT32 mbufSizeAligned,
+ UINT32 dataSizeAligned,
+ IX_OSAL_MBUF_POOL *poolPtr)
+{
+ UINT8 *dataPtr;
+ IX_OSAL_MBUF *realMbufPtr;
+ /* Allocate cache-aligned memory for mbuf header */
+ realMbufPtr = (IX_OSAL_MBUF *) IX_OSAL_CACHE_DMA_MALLOC (mbufSizeAligned);
+ IX_OSAL_ASSERT (realMbufPtr != NULL);
+ memset (realMbufPtr, 0, mbufSizeAligned);
+
+ /* Allocate cache-aligned memory for mbuf data */
+ dataPtr = (UINT8 *) IX_OSAL_CACHE_DMA_MALLOC (dataSizeAligned);
+ IX_OSAL_ASSERT (dataPtr != NULL);
+ memset (dataPtr, 0, dataSizeAligned);
+
+ /* Fill in mbuf header fields */
+ IX_OSAL_MBUF_MDATA (realMbufPtr) = dataPtr;
+ IX_OSAL_MBUF_ALLOCATED_BUFF_DATA (realMbufPtr) = (UINT32)dataPtr;
+
+ IX_OSAL_MBUF_MLEN (realMbufPtr) = dataSizeAligned;
+ IX_OSAL_MBUF_ALLOCATED_BUFF_LEN (realMbufPtr) = dataSizeAligned;
+
+ IX_OSAL_MBUF_NET_POOL (realMbufPtr) = (IX_OSAL_MBUF_POOL *) poolPtr;
+
+ IX_OSAL_MBUF_SYS_SIGNATURE_INIT(realMbufPtr);
+
+ /* update some statistical information */
+ poolPtr->mbufMemSize += mbufSizeAligned;
+ poolPtr->dataMemSize += dataSizeAligned;
+
+ return realMbufPtr;
+}
+#endif /* #ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY */
+
+/*
+ * Function definition: ixOsalBuffPoolInit
+ */
+
+PUBLIC IX_OSAL_MBUF_POOL *
+ixOsalPoolInit (UINT32 count, UINT32 size, const char *name)
+{
+
+ /* These variables are only used if UX_OSAL_BUFFER_ALLOC_SEPERATELY
+ * is defined .
+ */
+#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
+ UINT32 i, mbufSizeAligned, dataSizeAligned;
+ IX_OSAL_MBUF *currentMbufPtr = NULL;
+#else
+ void *poolBufPtr;
+ void *poolDataPtr;
+ int mbufMemSize;
+ int dataMemSize;
+#endif
+
+ IX_OSAL_MBUF_POOL *poolPtr = NULL;
+
+ if (count <= 0)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalPoolInit(): " "count = 0 \n", 0, 0, 0, 0, 0, 0);
+ return NULL;
+ }
+
+ if (name == NULL)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalPoolInit(): " "NULL name \n", 0, 0, 0, 0, 0, 0);
+ return NULL;
+ }
+
+ if (strlen (name) > IX_OSAL_MBUF_POOL_NAME_LEN)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalPoolInit(): "
+ "ERROR - name length should be no greater than %d \n",
+ IX_OSAL_MBUF_POOL_NAME_LEN, 0, 0, 0, 0, 0);
+ return NULL;
+ }
+
+/* OS can choose whether to allocate all buffers all together (if it
+ * can handle a huge single alloc request), or to allocate buffers
+ * separately by the defining IX_OSAL_BUFFER_ALLOC_SEPARATELY.
+ */
+#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
+ /* Get a pool Ptr */
+ poolPtr = ixOsalPoolAlloc ();
+
+ if (poolPtr == NULL)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalPoolInit(): " "Fail to Get PoolPtr \n", 0, 0, 0, 0, 0, 0);
+ return NULL;
+ }
+
+ mbufSizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF));
+ dataSizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN(size);
+
+ poolPtr->nextFreeBuf = NULL;
+ poolPtr->mbufMemPtr = NULL;
+ poolPtr->dataMemPtr = NULL;
+ poolPtr->bufDataSize = dataSizeAligned;
+ poolPtr->totalBufsInPool = count;
+ poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC;
+ strcpy (poolPtr->name, name);
+
+
+ for (i = 0; i < count; i++)
+ {
+ /* create an mbuf */
+ currentMbufPtr = ixOsalBuffPoolMbufInit (mbufSizeAligned,
+ dataSizeAligned,
+ poolPtr);
+
+#ifdef IX_OSAL_BUFFER_FREE_PROTECTION
+/* Set the Buffer USED Flag. If not, ixOsalMBufFree will fail.
+ ixOsalMbufFree used here is in a special case whereby, it's
+ used to add MBUF to the Pool. By specification, ixOsalMbufFree
+ deallocates an allocated MBUF from Pool.
+*/
+ IX_OSAL_MBUF_SET_USED_FLAG(currentMbufPtr);
+#endif
+ /* Add it to the pool */
+ ixOsalMbufFree (currentMbufPtr);
+
+ /* flush the pool information to RAM */
+ IX_OSAL_CACHE_FLUSH (currentMbufPtr, mbufSizeAligned);
+ }
+
+ /*
+ * update the number of free buffers in the pool
+ */
+ poolPtr->freeBufsInPool = count;
+
+#else
+/* Otherwise allocate buffers in a continuous block fashion */
+ poolBufPtr = IX_OSAL_MBUF_POOL_MBUF_AREA_ALLOC (count, mbufMemSize);
+ IX_OSAL_ASSERT (poolBufPtr != NULL);
+ poolDataPtr =
+ IX_OSAL_MBUF_POOL_DATA_AREA_ALLOC (count, size, dataMemSize);
+ IX_OSAL_ASSERT (poolDataPtr != NULL);
+
+ poolPtr = ixOsalNoAllocPoolInit (poolBufPtr, poolDataPtr,
+ count, size, name);
+ if (poolPtr == NULL)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalPoolInit(): " "Fail to get pool ptr \n", 0, 0, 0, 0, 0, 0);
+ return NULL;
+ }
+
+ poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC;
+
+#endif /* IX_OSAL_BUFFER_ALLOC_SEPARATELY */
+ return poolPtr;
+}
+
+PUBLIC IX_OSAL_MBUF_POOL *
+ixOsalNoAllocPoolInit (void *poolBufPtr,
+ void *poolDataPtr, UINT32 count, UINT32 size, const char *name)
+{
+ UINT32 i, mbufSizeAligned, sizeAligned;
+ IX_OSAL_MBUF *currentMbufPtr = NULL;
+ IX_OSAL_MBUF *nextMbufPtr = NULL;
+ IX_OSAL_MBUF_POOL *poolPtr = NULL;
+
+ /*
+ * check parameters
+ */
+ if (poolBufPtr == NULL)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalNoAllocPoolInit(): "
+ "ERROR - NULL poolBufPtr \n", 0, 0, 0, 0, 0, 0);
+ return NULL;
+ }
+
+ if (count <= 0)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalNoAllocPoolInit(): "
+ "ERROR - count must > 0 \n", 0, 0, 0, 0, 0, 0);
+ return NULL;
+ }
+
+ if (name == NULL)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalNoAllocPoolInit(): "
+ "ERROR - NULL name ptr \n", 0, 0, 0, 0, 0, 0);
+ return NULL;
+ }
+
+ if (strlen (name) > IX_OSAL_MBUF_POOL_NAME_LEN)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalNoAllocPoolInit(): "
+ "ERROR - name length should be no greater than %d \n",
+ IX_OSAL_MBUF_POOL_NAME_LEN, 0, 0, 0, 0, 0);
+ return NULL;
+ }
+
+ poolPtr = ixOsalPoolAlloc ();
+
+ if (poolPtr == NULL)
+ {
+ return NULL;
+ }
+
+ /*
+ * Adjust sizes to ensure alignment on cache line boundaries
+ */
+ mbufSizeAligned =
+ IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF));
+ /*
+ * clear the mbuf memory area
+ */
+ memset (poolBufPtr, 0, mbufSizeAligned * count);
+
+ if (poolDataPtr != NULL)
+ {
+ /*
+ * Adjust sizes to ensure alignment on cache line boundaries
+ */
+ sizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN (size);
+ /*
+ * clear the data memory area
+ */
+ memset (poolDataPtr, 0, sizeAligned * count);
+ }
+ else
+ {
+ sizeAligned = 0;
+ }
+
+ /*
+ * initialise pool fields
+ */
+ strcpy ((poolPtr)->name, name);
+
+ poolPtr->dataMemPtr = poolDataPtr;
+ poolPtr->mbufMemPtr = poolBufPtr;
+ poolPtr->bufDataSize = sizeAligned;
+ poolPtr->totalBufsInPool = count;
+ poolPtr->mbufMemSize = mbufSizeAligned * count;
+ poolPtr->dataMemSize = sizeAligned * count;
+
+ currentMbufPtr = (IX_OSAL_MBUF *) poolBufPtr;
+
+ poolPtr->nextFreeBuf = currentMbufPtr;
+
+ for (i = 0; i < count; i++)
+ {
+ if (i < (count - 1))
+ {
+ nextMbufPtr =
+ (IX_OSAL_MBUF *) ((unsigned) currentMbufPtr +
+ mbufSizeAligned);
+ }
+ else
+ { /* last mbuf in chain */
+ nextMbufPtr = NULL;
+ }
+ IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (currentMbufPtr) = nextMbufPtr;
+ IX_OSAL_MBUF_NET_POOL (currentMbufPtr) = poolPtr;
+
+ IX_OSAL_MBUF_SYS_SIGNATURE_INIT(currentMbufPtr);
+
+ if (poolDataPtr != NULL)
+ {
+ IX_OSAL_MBUF_MDATA (currentMbufPtr) = poolDataPtr;
+ IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(currentMbufPtr) = (UINT32) poolDataPtr;
+
+ IX_OSAL_MBUF_MLEN (currentMbufPtr) = sizeAligned;
+ IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(currentMbufPtr) = sizeAligned;
+
+ poolDataPtr = (void *) ((unsigned) poolDataPtr + sizeAligned);
+ }
+
+ currentMbufPtr = nextMbufPtr;
+ }
+
+ /*
+ * update the number of free buffers in the pool
+ */
+ poolPtr->freeBufsInPool = count;
+
+ poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_USER_ALLOC;
+
+ return poolPtr;
+}
+
+/*
+ * Get a mbuf ptr from the pool
+ */
+PUBLIC IX_OSAL_MBUF *
+ixOsalMbufAlloc (IX_OSAL_MBUF_POOL * poolPtr)
+{
+ int lock;
+ IX_OSAL_MBUF *newBufPtr = NULL;
+
+ /*
+ * check parameters
+ */
+ if (poolPtr == NULL)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalMbufAlloc(): "
+ "ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0);
+ return NULL;
+ }
+
+ lock = ixOsalIrqLock ();
+
+ newBufPtr = poolPtr->nextFreeBuf;
+ if (newBufPtr)
+ {
+ poolPtr->nextFreeBuf =
+ IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (newBufPtr);
+ IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (newBufPtr) = NULL;
+
+ /*
+ * update the number of free buffers in the pool
+ */
+ poolPtr->freeBufsInPool--;
+ }
+ else
+ {
+ /* Return NULL to indicate to caller that request is denied. */
+ ixOsalIrqUnlock (lock);
+
+ return NULL;
+ }
+
+#ifdef IX_OSAL_BUFFER_FREE_PROTECTION
+ /* Set Buffer Used Flag to indicate state.*/
+ IX_OSAL_MBUF_SET_USED_FLAG(newBufPtr);
+#endif
+
+ ixOsalIrqUnlock (lock);
+
+ return newBufPtr;
+}
+
+PUBLIC IX_OSAL_MBUF *
+ixOsalMbufFree (IX_OSAL_MBUF * bufPtr)
+{
+ int lock;
+ IX_OSAL_MBUF_POOL *poolPtr;
+
+ IX_OSAL_MBUF *nextBufPtr = NULL;
+
+ /*
+ * check parameters
+ */
+ if (bufPtr == NULL)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalMbufFree(): "
+ "ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0);
+ return NULL;
+ }
+
+
+
+ lock = ixOsalIrqLock ();
+
+#ifdef IX_OSAL_BUFFER_FREE_PROTECTION
+
+ /* Prevention for Buffer freed more than once*/
+ if(!IX_OSAL_MBUF_ISSET_USED_FLAG(bufPtr))
+ {
+ return NULL;
+ }
+ IX_OSAL_MBUF_CLEAR_USED_FLAG(bufPtr);
+#endif
+
+ poolPtr = IX_OSAL_MBUF_NET_POOL (bufPtr);
+
+ /*
+ * check the mbuf wrapper signature (if mbuf wrapper was used)
+ */
+ if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC)
+ {
+ IX_OSAL_ENSURE ( (IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) == IX_OSAL_MBUF_SYS_SIGNATURE),
+ "ixOsalBuffPoolBufFree: ERROR - Invalid mbuf signature.");
+ }
+
+ nextBufPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (bufPtr);
+
+ IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (bufPtr) = poolPtr->nextFreeBuf;
+ poolPtr->nextFreeBuf = bufPtr;
+
+ /*
+ * update the number of free buffers in the pool
+ */
+ poolPtr->freeBufsInPool++;
+
+ ixOsalIrqUnlock (lock);
+
+ return nextBufPtr;
+}
+
+PUBLIC void
+ixOsalMbufChainFree (IX_OSAL_MBUF * bufPtr)
+{
+ while ((bufPtr = ixOsalMbufFree (bufPtr)));
+}
+
+/*
+ * Function definition: ixOsalBuffPoolShow
+ */
+PUBLIC void
+ixOsalMbufPoolShow (IX_OSAL_MBUF_POOL * poolPtr)
+{
+ IX_OSAL_MBUF *nextBufPtr;
+ int count = 0;
+ int lock;
+
+ /*
+ * check parameters
+ */
+ if (poolPtr == NULL)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalBuffPoolShow(): "
+ "ERROR - Invalid Parameter", 0, 0, 0, 0, 0, 0);
+ /*
+ * return IX_FAIL;
+ */
+ return;
+ }
+
+ lock = ixOsalIrqLock ();
+ count = poolPtr->freeBufsInPool;
+ nextBufPtr = poolPtr->nextFreeBuf;
+ ixOsalIrqUnlock (lock);
+
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE,
+ IX_OSAL_LOG_DEV_STDOUT, "=== POOL INFORMATION ===\n", 0, 0, 0,
+ 0, 0, 0);
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Pool Name: %s\n",
+ (unsigned int) poolPtr->name, 0, 0, 0, 0, 0);
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Pool Allocation Type: %d\n",
+ (unsigned int) poolPtr->poolAllocType, 0, 0, 0, 0, 0);
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Pool Mbuf Mem Usage (bytes): %d\n",
+ (unsigned int) poolPtr->mbufMemSize, 0, 0, 0, 0, 0);
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Pool Data Mem Usage (bytes): %d\n",
+ (unsigned int) poolPtr->dataMemSize, 0, 0, 0, 0, 0);
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Mbuf Data Capacity (bytes): %d\n",
+ (unsigned int) poolPtr->bufDataSize, 0, 0, 0, 0, 0);
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Total Mbufs in Pool: %d\n",
+ (unsigned int) poolPtr->totalBufsInPool, 0, 0, 0, 0, 0);
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Available Mbufs: %d\n", (unsigned int) count, 0,
+ 0, 0, 0, 0);
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Next Available Mbuf: %p\n", (unsigned int) nextBufPtr,
+ 0, 0, 0, 0, 0);
+
+ if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_USER_ALLOC)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "Mbuf Mem Area Start address: %p\n",
+ (unsigned int) poolPtr->mbufMemPtr, 0, 0, 0, 0, 0);
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+ "Data Mem Area Start address: %p\n",
+ (unsigned int) poolPtr->dataMemPtr, 0, 0, 0, 0, 0);
+ }
+}
+
+PUBLIC void
+ixOsalMbufDataPtrReset (IX_OSAL_MBUF * bufPtr)
+{
+ IX_OSAL_MBUF_POOL *poolPtr;
+ UINT8 *poolDataPtr;
+
+ if (bufPtr == NULL)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalBuffPoolBufDataPtrReset"
+ ": ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0);
+ return;
+ }
+
+ poolPtr = (IX_OSAL_MBUF_POOL *) IX_OSAL_MBUF_NET_POOL (bufPtr);
+ poolDataPtr = poolPtr->dataMemPtr;
+
+ if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC)
+ {
+ if (IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) != IX_OSAL_MBUF_SYS_SIGNATURE)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalBuffPoolBufDataPtrReset"
+ ": invalid mbuf, cannot reset mData pointer\n", 0, 0,
+ 0, 0, 0, 0);
+ return;
+ }
+ IX_OSAL_MBUF_MDATA (bufPtr) = (UINT8*)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA (bufPtr);
+ }
+ else
+ {
+ if (poolDataPtr)
+ {
+ unsigned int bufSize = poolPtr->bufDataSize;
+ unsigned int bufDataAddr =
+ (unsigned int) IX_OSAL_MBUF_MDATA (bufPtr);
+ unsigned int poolDataAddr = (unsigned int) poolDataPtr;
+
+ /*
+ * the pointer is still pointing somewhere in the mbuf payload.
+ * This operation moves the pointer to the beginning of the
+ * mbuf payload
+ */
+ bufDataAddr = ((bufDataAddr - poolDataAddr) / bufSize) * bufSize;
+ IX_OSAL_MBUF_MDATA (bufPtr) = &poolDataPtr[bufDataAddr];
+ }
+ else
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalBuffPoolBufDataPtrReset"
+ ": cannot be used if user supplied NULL pointer for pool data area "
+ "when pool was created\n", 0, 0, 0, 0, 0, 0);
+ return;
+ }
+ }
+
+}
+
+/*
+ * Function definition: ixOsalBuffPoolUninit
+ */
+PUBLIC IX_STATUS
+ixOsalBuffPoolUninit (IX_OSAL_MBUF_POOL * pool)
+{
+ if (!pool)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalBuffPoolUninit: NULL ptr \n", 0, 0, 0, 0, 0, 0);
+ return IX_FAIL;
+ }
+
+ if (pool->freeBufsInPool != pool->totalBufsInPool)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalBuffPoolUninit: need to return all ptrs to the pool first! \n",
+ 0, 0, 0, 0, 0, 0);
+ return IX_FAIL;
+ }
+
+ if (pool->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC)
+ {
+#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
+ UINT32 i;
+ IX_OSAL_MBUF* pBuf;
+
+ pBuf = pool->nextFreeBuf;
+ /* Freed the Buffer one by one till all the Memory is freed*/
+ for (i= pool->freeBufsInPool; i >0 && pBuf!=NULL ;i--){
+ IX_OSAL_MBUF* pBufTemp;
+ pBufTemp = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(pBuf);
+ /* Freed MBUF Data Memory area*/
+ IX_OSAL_CACHE_DMA_FREE( (void *) (IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(pBuf)) );
+ /* Freed MBUF Struct Memory area*/
+ IX_OSAL_CACHE_DMA_FREE(pBuf);
+ pBuf = pBufTemp;
+ }
+
+#else
+ IX_OSAL_CACHE_DMA_FREE (pool->mbufMemPtr);
+ IX_OSAL_CACHE_DMA_FREE (pool->dataMemPtr);
+#endif
+ }
+
+ ixOsalBuffFreePools[pool->poolIdx / IX_OSAL_BUFF_FREE_BITS] &=
+ ~(1 << (pool->poolIdx % IX_OSAL_BUFF_FREE_BITS));
+ ixOsalBuffPoolsInUse--;
+ return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixOsalBuffPoolDataAreaSizeGet
+ */
+PUBLIC UINT32
+ixOsalBuffPoolDataAreaSizeGet (int count, int size)
+{
+ UINT32 memorySize;
+ memorySize = count * IX_OSAL_MBUF_POOL_SIZE_ALIGN (size);
+ return memorySize;
+}
+
+/*
+ * Function definition: ixOsalBuffPoolMbufAreaSizeGet
+ */
+PUBLIC UINT32
+ixOsalBuffPoolMbufAreaSizeGet (int count)
+{
+ UINT32 memorySize;
+ memorySize =
+ count * IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF));
+ return memorySize;
+}
+
+/*
+ * Function definition: ixOsalBuffPoolFreeCountGet
+ */
+PUBLIC UINT32 ixOsalBuffPoolFreeCountGet(IX_OSAL_MBUF_POOL * poolPtr)
+
+{
+
+ return poolPtr->freeBufsInPool;
+
+}
+
+#endif /* IX_OSAL_USE_DEFAULT_BUFFER_MGT */
diff --git a/cpu/ixp/npe/IxOsalIoMem.c b/cpu/ixp/npe/IxOsalIoMem.c
new file mode 100644
index 0000000..9e540c1
--- /dev/null
+++ b/cpu/ixp/npe/IxOsalIoMem.c
@@ -0,0 +1,332 @@
+/**
+ * @file IxOsalIoMem.c
+ *
+ * @brief OS-independent IO/Mem implementation
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/* Access to the global mem map is only allowed in this file */
+#define IxOsalIoMem_C
+
+#include "IxOsal.h"
+
+#define SEARCH_PHYSICAL_ADDRESS (1)
+#define SEARCH_VIRTUAL_ADDRESS (2)
+
+/*
+ * Searches for map using one of the following criteria:
+ *
+ * - enough room to include a zone starting with the physical "requestedAddress" of size "size" (for mapping)
+ * - includes the virtual "requestedAddress" in its virtual address space (already mapped, for unmapping)
+ * - correct coherency
+ *
+ * Returns a pointer to the map or NULL if a suitable map is not found.
+ */
+PRIVATE IxOsalMemoryMap *
+ixOsalMemMapFind (UINT32 requestedAddress,
+ UINT32 size, UINT32 searchCriteria, UINT32 requestedEndianType)
+{
+ UINT32 mapIndex;
+
+ UINT32 numMapElements =
+ sizeof (ixOsalGlobalMemoryMap) / sizeof (IxOsalMemoryMap);
+
+ for (mapIndex = 0; mapIndex < numMapElements; mapIndex++)
+ {
+ IxOsalMemoryMap *map = &ixOsalGlobalMemoryMap[mapIndex];
+
+ if (searchCriteria == SEARCH_PHYSICAL_ADDRESS
+ && requestedAddress >= map->physicalAddress
+ && (requestedAddress + size) <= (map->physicalAddress + map->size)
+ && (map->mapEndianType & requestedEndianType) != 0)
+ {
+ return map;
+ }
+ else if (searchCriteria == SEARCH_VIRTUAL_ADDRESS
+ && requestedAddress >= map->virtualAddress
+ && requestedAddress <= (map->virtualAddress + map->size)
+ && (map->mapEndianType & requestedEndianType) != 0)
+ {
+ return map;
+ }
+ else if (searchCriteria == SEARCH_PHYSICAL_ADDRESS)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "Osal: Checking [phys addr 0x%x:size 0x%x:endianType %d]\n",
+ map->physicalAddress, map->size, map->mapEndianType, 0, 0, 0);
+ }
+ }
+
+ /*
+ * not found
+ */
+ return NULL;
+}
+
+/*
+ * This function maps an I/O mapped physical memory zone of the given size
+ * into a virtual memory zone accessible by the caller and returns a cookie -
+ * the start address of the virtual memory zone.
+ * IX_OSAL_MMAP_PHYS_TO_VIRT should NOT therefore be used on the returned
+ * virtual address.
+ * The memory zone is to be unmapped using ixOsalMemUnmap once the caller has
+ * finished using this zone (e.g. on driver unload) using the cookie as
+ * parameter.
+ * The IX_OSAL_READ/WRITE_LONG/SHORT macros should be used to read and write
+ * the mapped memory, adding the necessary offsets to the address cookie.
+ *
+ * Note: this function is not to be used directly. Use IX_OSAL_MEM_MAP
+ * instead.
+ */
+PUBLIC void *
+ixOsalIoMemMap (UINT32 requestedAddress,
+ UINT32 size, IxOsalMapEndianessType requestedEndianType)
+{
+ IxOsalMemoryMap *map;
+
+ ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "OSAL: Mapping [addr 0x%x:size 0x%x:endianType %d]\n",
+ requestedAddress, size, requestedEndianType, 0, 0, 0);
+
+ if (requestedEndianType == IX_OSAL_LE)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalIoMemMap: Please specify component coherency mode to use MEM functions \n",
+ 0, 0, 0, 0, 0, 0);
+ return (NULL);
+ }
+ map = ixOsalMemMapFind (requestedAddress,
+ size, SEARCH_PHYSICAL_ADDRESS, requestedEndianType);
+ if (map != NULL)
+ {
+ UINT32 offset = requestedAddress - map->physicalAddress;
+
+ ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
+ IX_OSAL_LOG_DEV_STDOUT, "OSAL: Found map [", 0, 0, 0, 0, 0, 0);
+ ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
+ IX_OSAL_LOG_DEV_STDOUT, map->name, 0, 0, 0, 0, 0, 0);
+ ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
+ IX_OSAL_LOG_DEV_STDOUT,
+ ":addr 0x%x: virt 0x%x:size 0x%x:ref %d:endianType %d]\n",
+ map->physicalAddress, map->virtualAddress,
+ map->size, map->refCount, map->mapEndianType, 0);
+
+ if (map->type == IX_OSAL_DYNAMIC_MAP && map->virtualAddress == 0)
+ {
+ if (map->mapFunction != NULL)
+ {
+ map->mapFunction (map);
+
+ if (map->virtualAddress == 0)
+ {
+ /*
+ * failed
+ */
+ ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
+ IX_OSAL_LOG_DEV_STDERR,
+ "OSAL: Remap failed - [addr 0x%x:size 0x%x:endianType %d]\n",
+ requestedAddress, size, requestedEndianType, 0, 0, 0);
+ return NULL;
+ }
+ }
+ else
+ {
+ /*
+ * error, no map function for a dynamic map
+ */
+ ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
+ IX_OSAL_LOG_DEV_STDERR,
+ "OSAL: No map function for a dynamic map - "
+ "[addr 0x%x:size 0x%x:endianType %d]\n",
+ requestedAddress, size, requestedEndianType, 0, 0, 0);
+
+ return NULL;
+ }
+ }
+
+ /*
+ * increment reference count
+ */
+ map->refCount++;
+
+ return (void *) (map->virtualAddress + offset);
+ }
+
+ /*
+ * requested address is not described in the global memory map
+ */
+ ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
+ IX_OSAL_LOG_DEV_STDERR,
+ "OSAL: No mapping found - [addr 0x%x:size 0x%x:endianType %d]\n",
+ requestedAddress, size, requestedEndianType, 0, 0, 0);
+ return NULL;
+}
+
+/*
+ * This function unmaps a previously mapped I/O memory zone using
+ * the cookie obtained in the mapping operation. The memory zone in question
+ * becomes unavailable to the caller once unmapped and the cookie should be
+ * discarded.
+ *
+ * This function cannot fail if the given parameter is correct and does not
+ * return a value.
+ *
+ * Note: this function is not to be used directly. Use IX_OSAL_MEM_UNMAP
+ * instead.
+ */
+PUBLIC void
+ixOsalIoMemUnmap (UINT32 requestedAddress, UINT32 endianType)
+{
+ IxOsalMemoryMap *map;
+
+ if (endianType == IX_OSAL_LE)
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalIoMemUnmap: Please specify component coherency mode to use MEM functions \n",
+ 0, 0, 0, 0, 0, 0);
+ return;
+ }
+
+ if (requestedAddress == 0)
+ {
+ /*
+ * invalid virtual address
+ */
+ return;
+ }
+
+ map =
+ ixOsalMemMapFind (requestedAddress, 0, SEARCH_VIRTUAL_ADDRESS,
+ endianType);
+
+ if (map != NULL)
+ {
+ if (map->refCount > 0)
+ {
+ /*
+ * decrement reference count
+ */
+ map->refCount--;
+
+ if (map->refCount == 0)
+ {
+ /*
+ * no longer used, deallocate
+ */
+ if (map->type == IX_OSAL_DYNAMIC_MAP
+ && map->unmapFunction != NULL)
+ {
+ map->unmapFunction (map);
+ }
+ }
+ }
+ }
+ else
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_WARNING,
+ IX_OSAL_LOG_DEV_STDERR,
+ "OSAL: ixOsServMemUnmap didn't find the requested map "
+ "[virt addr 0x%x: endianType %d], ignoring call\n",
+ requestedAddress, endianType, 0, 0, 0, 0);
+ }
+}
+
+/*
+ * This function Converts a virtual address into a physical
+ * address, including the dynamically mapped memory.
+ *
+ * Parameters virtAddr - virtual address to convert
+ * Return value: corresponding physical address, or NULL
+ * if there is no physical address addressable
+ * by the given virtual address
+ * OS: VxWorks, Linux, WinCE, QNX, eCos
+ * Reentrant: Yes
+ * IRQ safe: Yes
+ */
+PUBLIC UINT32
+ixOsalIoMemVirtToPhys (UINT32 virtualAddress, UINT32 requestedCoherency)
+{
+ IxOsalMemoryMap *map =
+ ixOsalMemMapFind (virtualAddress, 0, SEARCH_VIRTUAL_ADDRESS,
+ requestedCoherency);
+
+ if (map != NULL)
+ {
+ return map->physicalAddress + virtualAddress - map->virtualAddress;
+ }
+ else
+ {
+ return (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS (virtualAddress);
+ }
+}
+
+/*
+ * This function Converts a virtual address into a physical
+ * address, including the dynamically mapped memory.
+ *
+ * Parameters virtAddr - virtual address to convert
+ * Return value: corresponding physical address, or NULL
+ * if there is no physical address addressable
+ * by the given virtual address
+ * OS: VxWorks, Linux, WinCE, QNX, eCos
+ * Reentrant: Yes
+ * IRQ safe: Yes
+ */
+PUBLIC UINT32
+ixOsalIoMemPhysToVirt (UINT32 physicalAddress, UINT32 requestedCoherency)
+{
+ IxOsalMemoryMap *map =
+ ixOsalMemMapFind (physicalAddress, 0, SEARCH_PHYSICAL_ADDRESS,
+ requestedCoherency);
+
+ if (map != NULL)
+ {
+ return map->virtualAddress + physicalAddress - map->physicalAddress;
+ }
+ else
+ {
+ return (UINT32) IX_OSAL_MMU_PHYS_TO_VIRT (physicalAddress);
+ }
+}
diff --git a/cpu/ixp/npe/IxOsalOsCacheMMU.c b/cpu/ixp/npe/IxOsalOsCacheMMU.c
new file mode 100644
index 0000000..3db1a70
--- /dev/null
+++ b/cpu/ixp/npe/IxOsalOsCacheMMU.c
@@ -0,0 +1,67 @@
+/**
+ * @file IxOsalOsCacheMMU.c (linux)
+ *
+ * @brief Cache MemAlloc and MemFree.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 1.5
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxOsal.h"
+
+#include <malloc.h>
+
+/*
+ * Allocate on a cache line boundary (null pointers are
+ * not affected by this operation). This operation is NOT cache safe.
+ */
+void *
+ixOsalCacheDmaMalloc (UINT32 n)
+{
+ return malloc(n);
+}
+
+/*
+ *
+ */
+void
+ixOsalCacheDmaFree (void *ptr)
+{
+ free(ptr);
+}
diff --git a/cpu/ixp/npe/IxOsalOsMsgQ.c b/cpu/ixp/npe/IxOsalOsMsgQ.c
new file mode 100644
index 0000000..45a5c68
--- /dev/null
+++ b/cpu/ixp/npe/IxOsalOsMsgQ.c
@@ -0,0 +1,79 @@
+/**
+ * @file IxOsalOsMsgQ.c (eCos)
+ *
+ * @brief OS-specific Message Queue implementation.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 1.5
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxOsal.h"
+
+/*******************************
+ * Public functions
+ *******************************/
+PUBLIC IX_STATUS
+ixOsalMessageQueueCreate (IxOsalMessageQueue * queue,
+ UINT32 msgCount, UINT32 msgLen)
+{
+ diag_printf("%s called\n", __FUNCTION__);
+ return IX_FAIL;
+}
+
+PUBLIC IX_STATUS
+ixOsalMessageQueueDelete (IxOsalMessageQueue * queue)
+{
+ diag_printf("%s called\n", __FUNCTION__);
+ return IX_FAIL;
+}
+
+PUBLIC IX_STATUS
+ixOsalMessageQueueSend (IxOsalMessageQueue * queue, UINT8 * message)
+{
+ diag_printf("%s called\n", __FUNCTION__);
+ return IX_FAIL;
+}
+
+PUBLIC IX_STATUS
+ixOsalMessageQueueReceive (IxOsalMessageQueue * queue, UINT8 * message)
+{
+ diag_printf("%s called\n", __FUNCTION__);
+ return IX_FAIL;
+}
+
diff --git a/cpu/ixp/npe/IxOsalOsSemaphore.c b/cpu/ixp/npe/IxOsalOsSemaphore.c
new file mode 100644
index 0000000..443aefd
--- /dev/null
+++ b/cpu/ixp/npe/IxOsalOsSemaphore.c
@@ -0,0 +1,233 @@
+/**
+ * @file IxOsalOsSemaphore.c (eCos)
+ *
+ * @brief Implementation for semaphore and mutex.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 1.5
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxOsal.h"
+#include "IxNpeMhReceive_p.h"
+
+/* Define a large number */
+#define IX_OSAL_MAX_LONG (0x7FFFFFFF)
+
+/* Max timeout in MS, used to guard against possible overflow */
+#define IX_OSAL_MAX_TIMEOUT_MS (IX_OSAL_MAX_LONG/HZ)
+
+
+PUBLIC IX_STATUS
+ixOsalSemaphoreInit (IxOsalSemaphore * sid, UINT32 start_value)
+{
+ diag_printf("%s called\n", __FUNCTION__);
+ return IX_SUCCESS;
+}
+
+/**
+ * DESCRIPTION: If the semaphore is 'empty', the calling thread is blocked.
+ * If the semaphore is 'full', it is taken and control is returned
+ * to the caller. If the time indicated in 'timeout' is reached,
+ * the thread will unblock and return an error indication. If the
+ * timeout is set to 'IX_OSAL_WAIT_NONE', the thread will never block;
+ * if it is set to 'IX_OSAL_WAIT_FOREVER', the thread will block until
+ * the semaphore is available.
+ *
+ *
+ */
+
+
+PUBLIC IX_STATUS
+ixOsalSemaphoreWait (IxOsalOsSemaphore * sid, INT32 timeout)
+{
+ diag_printf("%s called\n", __FUNCTION__);
+ return IX_SUCCESS;
+}
+
+/*
+ * Attempt to get semaphore, return immediately,
+ * no error info because users expect some failures
+ * when using this API.
+ */
+PUBLIC IX_STATUS
+ixOsalSemaphoreTryWait (IxOsalSemaphore * sid)
+{
+ diag_printf("%s called\n", __FUNCTION__);
+ return IX_FAIL;
+}
+
+/**
+ *
+ * DESCRIPTION: This function causes the next available thread in the pend queue
+ * to be unblocked. If no thread is pending on this semaphore, the
+ * semaphore becomes 'full'.
+ */
+PUBLIC IX_STATUS
+ixOsalSemaphorePost (IxOsalSemaphore * sid)
+{
+ diag_printf("%s called\n", __FUNCTION__);
+ return IX_SUCCESS;
+}
+
+PUBLIC IX_STATUS
+ixOsalSemaphoreGetValue (IxOsalSemaphore * sid, UINT32 * value)
+{
+ diag_printf("%s called\n", __FUNCTION__);
+ return IX_FAIL;
+}
+
+PUBLIC IX_STATUS
+ixOsalSemaphoreDestroy (IxOsalSemaphore * sid)
+{
+ diag_printf("%s called\n", __FUNCTION__);
+ return IX_FAIL;
+}
+
+/****************************
+ * Mutex
+ ****************************/
+
+static void drv_mutex_init(IxOsalMutex *mutex)
+{
+ *mutex = 0;
+}
+
+static void drv_mutex_destroy(IxOsalMutex *mutex)
+{
+ *mutex = -1;
+}
+
+static int drv_mutex_trylock(IxOsalMutex *mutex)
+{
+ int result = TRUE;
+
+ if (*mutex == 1)
+ result = FALSE;
+
+ return result;
+}
+
+static void drv_mutex_unlock(IxOsalMutex *mutex)
+{
+ if (*mutex == 1)
+ printf("Trying to unlock unlocked mutex!");
+
+ *mutex = 0;
+}
+
+PUBLIC IX_STATUS
+ixOsalMutexInit (IxOsalMutex * mutex)
+{
+ drv_mutex_init(mutex);
+ return IX_SUCCESS;
+}
+
+PUBLIC IX_STATUS
+ixOsalMutexLock (IxOsalMutex * mutex, INT32 timeout)
+{
+ int tries;
+
+ if (timeout == IX_OSAL_WAIT_NONE) {
+ if (drv_mutex_trylock(mutex))
+ return IX_SUCCESS;
+ else
+ return IX_FAIL;
+ }
+
+ tries = (timeout * 1000) / 50;
+ while (1) {
+ if (drv_mutex_trylock(mutex))
+ return IX_SUCCESS;
+ if (timeout != IX_OSAL_WAIT_FOREVER && tries-- <= 0)
+ break;
+ udelay(50);
+ }
+ return IX_FAIL;
+}
+
+PUBLIC IX_STATUS
+ixOsalMutexUnlock (IxOsalMutex * mutex)
+{
+ drv_mutex_unlock(mutex);
+ return IX_SUCCESS;
+}
+
+/*
+ * Attempt to get mutex, return immediately,
+ * no error info because users expect some failures
+ * when using this API.
+ */
+PUBLIC IX_STATUS
+ixOsalMutexTryLock (IxOsalMutex * mutex)
+{
+ if (drv_mutex_trylock(mutex))
+ return IX_SUCCESS;
+ return IX_FAIL;
+}
+
+PUBLIC IX_STATUS
+ixOsalMutexDestroy (IxOsalMutex * mutex)
+{
+ drv_mutex_destroy(mutex);
+ return IX_SUCCESS;
+}
+
+PUBLIC IX_STATUS
+ixOsalFastMutexInit (IxOsalFastMutex * mutex)
+{
+ return ixOsalMutexInit(mutex);
+}
+
+PUBLIC IX_STATUS ixOsalFastMutexTryLock(IxOsalFastMutex *mutex)
+{
+ return ixOsalMutexTryLock(mutex);
+}
+
+
+PUBLIC IX_STATUS
+ixOsalFastMutexUnlock (IxOsalFastMutex * mutex)
+{
+ return ixOsalMutexUnlock(mutex);
+}
+
+PUBLIC IX_STATUS
+ixOsalFastMutexDestroy (IxOsalFastMutex * mutex)
+{
+ return ixOsalMutexDestroy(mutex);
+}
diff --git a/cpu/ixp/npe/IxOsalOsServices.c b/cpu/ixp/npe/IxOsalOsServices.c
new file mode 100644
index 0000000..e18c6c4
--- /dev/null
+++ b/cpu/ixp/npe/IxOsalOsServices.c
@@ -0,0 +1,251 @@
+/**
+ * @file IxOsalOsServices.c (linux)
+ *
+ * @brief Implementation for Irq, Mem, sleep.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 1.5
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include <config.h>
+#include <common.h>
+#include "IxOsal.h"
+#include <IxEthAcc.h>
+#include <IxEthDB.h>
+#include <IxNpeDl.h>
+#include <IxQMgr.h>
+#include <IxNpeMh.h>
+
+static char *traceHeaders[] = {
+ "",
+ "[fatal] ",
+ "[error] ",
+ "[warning] ",
+ "[message] ",
+ "[debug1] ",
+ "[debug2] ",
+ "[debug3] ",
+ "[all]"
+};
+
+/* by default trace all but debug message */
+PRIVATE int ixOsalCurrLogLevel = IX_OSAL_LOG_LVL_MESSAGE;
+
+/**************************************
+ * Irq services
+ *************************************/
+
+PUBLIC IX_STATUS
+ixOsalIrqBind (UINT32 vector, IxOsalVoidFnVoidPtr routine, void *parameter)
+{
+ return IX_FAIL;
+}
+
+PUBLIC IX_STATUS
+ixOsalIrqUnbind (UINT32 vector)
+{
+ return IX_FAIL;
+}
+
+PUBLIC UINT32
+ixOsalIrqLock ()
+{
+ return 0;
+}
+
+/* Enable interrupts and task scheduling,
+ * input parameter: irqEnable status returned
+ * by ixOsalIrqLock().
+ */
+PUBLIC void
+ixOsalIrqUnlock (UINT32 lockKey)
+{
+}
+
+PUBLIC UINT32
+ixOsalIrqLevelSet (UINT32 level)
+{
+ return IX_FAIL;
+}
+
+PUBLIC void
+ixOsalIrqEnable (UINT32 irqLevel)
+{
+}
+
+PUBLIC void
+ixOsalIrqDisable (UINT32 irqLevel)
+{
+}
+
+/*********************
+ * Log function
+ *********************/
+
+INT32
+ixOsalLog (IxOsalLogLevel level,
+ IxOsalLogDevice device,
+ char *format, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6)
+{
+ /*
+ * Return -1 for custom display devices
+ */
+ if ((device != IX_OSAL_LOG_DEV_STDOUT)
+ && (device != IX_OSAL_LOG_DEV_STDERR))
+ {
+ debug("ixOsalLog: only IX_OSAL_LOG_DEV_STDOUT and IX_OSAL_LOG_DEV_STDERR are supported \n");
+ return (IX_OSAL_LOG_ERROR);
+ }
+
+ if (level <= ixOsalCurrLogLevel && level != IX_OSAL_LOG_LVL_NONE)
+ {
+#if 0 /* sr: U-Boots printf or debug doesn't return a length */
+ int headerByteCount = (level == IX_OSAL_LOG_LVL_USER) ? 0 : diag_printf(traceHeaders[level - 1]);
+
+ return headerByteCount + diag_printf (format, arg1, arg2, arg3, arg4, arg5, arg6);
+#else
+ int headerByteCount = (level == IX_OSAL_LOG_LVL_USER) ? 0 : strlen(traceHeaders[level - 1]);
+
+ return headerByteCount + strlen(format);
+#endif
+ }
+ else
+ {
+ /*
+ * Return error
+ */
+ return (IX_OSAL_LOG_ERROR);
+ }
+}
+
+PUBLIC UINT32
+ixOsalLogLevelSet (UINT32 level)
+{
+ UINT32 oldLevel;
+
+ /*
+ * Check value first
+ */
+ if ((level < IX_OSAL_LOG_LVL_NONE) || (level > IX_OSAL_LOG_LVL_ALL))
+ {
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE,
+ IX_OSAL_LOG_DEV_STDOUT,
+ "ixOsalLogLevelSet: Log Level is between %d and%d \n",
+ IX_OSAL_LOG_LVL_NONE, IX_OSAL_LOG_LVL_ALL, 0, 0, 0, 0);
+ return IX_OSAL_LOG_LVL_NONE;
+ }
+ oldLevel = ixOsalCurrLogLevel;
+
+ ixOsalCurrLogLevel = level;
+
+ return oldLevel;
+}
+
+/**************************************
+ * Task services
+ *************************************/
+
+PUBLIC void
+ixOsalBusySleep (UINT32 microseconds)
+{
+ udelay(microseconds);
+}
+
+PUBLIC void
+ixOsalSleep (UINT32 milliseconds)
+{
+ if (milliseconds != 0) {
+#if 1
+ /*
+ * sr: We poll while we wait because interrupts are off in U-Boot
+ * and CSR expects messages, etc to be dispatched while sleeping.
+ */
+ int i;
+ IxQMgrDispatcherFuncPtr qDispatcherFunc;
+
+ ixQMgrDispatcherLoopGet(&qDispatcherFunc);
+
+ while (milliseconds--) {
+ for (i = 1; i <= 2; i++)
+ ixNpeMhMessagesReceive(i);
+ (*qDispatcherFunc)(IX_QMGR_QUELOW_GROUP);
+
+ udelay(1000);
+ }
+#endif
+ }
+}
+
+/**************************************
+ * Memory functions
+ *************************************/
+
+void *
+ixOsalMemAlloc (UINT32 size)
+{
+ return (void *)0;
+}
+
+void
+ixOsalMemFree (void *ptr)
+{
+}
+
+/*
+ * Copy count bytes from src to dest ,
+ * returns pointer to the dest mem zone.
+ */
+void *
+ixOsalMemCopy (void *dest, void *src, UINT32 count)
+{
+ IX_OSAL_ASSERT (dest != NULL);
+ IX_OSAL_ASSERT (src != NULL);
+ return (memcpy (dest, src, count));
+}
+
+/*
+ * Fills a memory zone with a given constant byte,
+ * returns pointer to the memory zone.
+ */
+void *
+ixOsalMemSet (void *ptr, UINT8 filler, UINT32 count)
+{
+ IX_OSAL_ASSERT (ptr != NULL);
+ return (memset (ptr, filler, count));
+}
diff --git a/cpu/ixp/npe/IxOsalOsThread.c b/cpu/ixp/npe/IxOsalOsThread.c
new file mode 100644
index 0000000..e6a4967
--- /dev/null
+++ b/cpu/ixp/npe/IxOsalOsThread.c
@@ -0,0 +1,98 @@
+/**
+ * @file IxOsalOsThread.c (eCos)
+ *
+ * @brief OS-specific thread implementation.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 1.5
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxOsal.h"
+
+/* Thread attribute is ignored */
+PUBLIC IX_STATUS
+ixOsalThreadCreate (IxOsalThread * ptrTid,
+ IxOsalThreadAttr * threadAttr, IxOsalVoidFnVoidPtr entryPoint, void *arg)
+{
+ return IX_SUCCESS;
+}
+
+/*
+ * Start thread after given its thread handle
+ */
+PUBLIC IX_STATUS
+ixOsalThreadStart (IxOsalThread * tId)
+{
+ /* Thread already started upon creation */
+ return IX_SUCCESS;
+}
+
+/*
+ * In Linux threadKill does not actually destroy the thread,
+ * it will stop the signal handling.
+ */
+PUBLIC IX_STATUS
+ixOsalThreadKill (IxOsalThread * tid)
+{
+ return IX_SUCCESS;
+}
+
+PUBLIC void
+ixOsalThreadExit (void)
+{
+}
+
+PUBLIC IX_STATUS
+ixOsalThreadPrioritySet (IxOsalOsThread * tid, UINT32 priority)
+{
+ return IX_SUCCESS;
+}
+
+PUBLIC IX_STATUS
+ixOsalThreadSuspend (IxOsalThread * tId)
+{
+ return IX_SUCCESS;
+
+}
+
+PUBLIC IX_STATUS
+ixOsalThreadResume (IxOsalThread * tId)
+{
+ return IX_SUCCESS;
+}
diff --git a/cpu/ixp/npe/IxQMgrAqmIf.c b/cpu/ixp/npe/IxQMgrAqmIf.c
new file mode 100644
index 0000000..b27b3a2
--- /dev/null
+++ b/cpu/ixp/npe/IxQMgrAqmIf.c
@@ -0,0 +1,963 @@
+/*
+ * @file: IxQMgrAqmIf.c
+ *
+ * @author Intel Corporation
+ * @date 30-Oct-2001
+ *
+ * @brief This component provides a set of functions for
+ * perfoming I/O on the AQM hardware.
+ *
+ * Design Notes:
+ * These functions are intended to be as fast as possible
+ * and as a result perform NO PARAMETER CHECKING.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * Inlines are compiled as function when this is defined.
+ * N.B. Must be placed before #include of "IxQMgrAqmIf_p.h
+ */
+#ifndef IXQMGRAQMIF_P_H
+# define IXQMGRAQMIF_C
+#else
+# error
+#endif
+
+/*
+ * User defined include files.
+ */
+#include "IxOsal.h"
+#include "IxQMgr.h"
+#include "IxQMgrAqmIf_p.h"
+#include "IxQMgrLog_p.h"
+
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/* These defines are the bit offsets of the various fields of
+ * the queue configuration register
+ */
+#define IX_QMGR_Q_CONFIG_WRPTR_OFFSET 0x00
+#define IX_QMGR_Q_CONFIG_RDPTR_OFFSET 0x07
+#define IX_QMGR_Q_CONFIG_BADDR_OFFSET 0x0E
+#define IX_QMGR_Q_CONFIG_ESIZE_OFFSET 0x16
+#define IX_QMGR_Q_CONFIG_BSIZE_OFFSET 0x18
+#define IX_QMGR_Q_CONFIG_NE_OFFSET 0x1A
+#define IX_QMGR_Q_CONFIG_NF_OFFSET 0x1D
+
+#define IX_QMGR_BASE_ADDR_16_WORD_ALIGN 0x40
+#define IX_QMGR_BASE_ADDR_16_WORD_SHIFT 0x6
+
+#define IX_QMGR_NE_NF_CLEAR_MASK 0x03FFFFFF
+#define IX_QMGR_NE_MASK 0x7
+#define IX_QMGR_NF_MASK 0x7
+#define IX_QMGR_SIZE_MASK 0x3
+#define IX_QMGR_ENTRY_SIZE_MASK 0x3
+#define IX_QMGR_BADDR_MASK 0x003FC000
+#define IX_QMGR_RDPTR_MASK 0x7F
+#define IX_QMGR_WRPTR_MASK 0x7F
+#define IX_QMGR_RDWRPTR_MASK 0x00003FFF
+
+#define IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS 0x1000
+
+/* Base address of AQM SRAM */
+#define IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET \
+((IX_QMGR_QUECONFIG_BASE_OFFSET) + (IX_QMGR_QUECONFIG_SIZE))
+
+/* Min buffer size used for generating buffer size in QUECONFIG */
+#define IX_QMGR_MIN_BUFFER_SIZE 16
+
+/* Reset values of QMgr hardware registers */
+#define IX_QMGR_QUELOWSTAT_RESET_VALUE 0x33333333
+#define IX_QMGR_QUEUOSTAT_RESET_VALUE 0x00000000
+#define IX_QMGR_QUEUPPSTAT0_RESET_VALUE 0xFFFFFFFF
+#define IX_QMGR_QUEUPPSTAT1_RESET_VALUE 0x00000000
+#define IX_QMGR_INT0SRCSELREG_RESET_VALUE 0x00000000
+#define IX_QMGR_QUEIEREG_RESET_VALUE 0x00000000
+#define IX_QMGR_QINTREG_RESET_VALUE 0xFFFFFFFF
+#define IX_QMGR_QUECONFIG_RESET_VALUE 0x00000000
+
+#define IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS IX_OSAL_IXP400_QMGR_PHYS_BASE
+
+#define IX_QMGR_QUELOWSTAT_BITS_PER_Q (BITS_PER_WORD/IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)
+
+#define IX_QMGR_QUELOWSTAT_QID_MASK 0x7
+#define IX_QMGR_Q_CONFIG_ADDR_GET(qId)\
+ (((qId) * IX_QMGR_NUM_BYTES_PER_WORD) +\
+ IX_QMGR_QUECONFIG_BASE_OFFSET)
+
+#define IX_QMGR_ENTRY1_OFFSET 0
+#define IX_QMGR_ENTRY2_OFFSET 1
+#define IX_QMGR_ENTRY4_OFFSET 3
+
+/*
+ * Variable declarations global to this file. Externs are followed by
+ * statics.
+ */
+UINT32 aqmBaseAddress = 0;
+/* Store addresses and bit-masks for certain queue access and status registers.
+ * This is to facilitate inlining of QRead, QWrite and QStatusGet functions
+ * in IxQMgr,h
+ */
+extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
+UINT32 * ixQMgrAqmIfQueAccRegAddr[IX_QMGR_MAX_NUM_QUEUES];
+UINT32 ixQMgrAqmIfQueLowStatRegAddr[IX_QMGR_MIN_QUEUPP_QID];
+UINT32 ixQMgrAqmIfQueLowStatBitsOffset[IX_QMGR_MIN_QUEUPP_QID];
+UINT32 ixQMgrAqmIfQueLowStatBitsMask;
+UINT32 ixQMgrAqmIfQueUppStat0RegAddr;
+UINT32 ixQMgrAqmIfQueUppStat1RegAddr;
+UINT32 ixQMgrAqmIfQueUppStat0BitMask[IX_QMGR_MIN_QUEUPP_QID];
+UINT32 ixQMgrAqmIfQueUppStat1BitMask[IX_QMGR_MIN_QUEUPP_QID];
+
+/*
+ * Fast mutexes, one for each queue, used to protect peek & poke functions
+ */
+IxOsalFastMutex ixQMgrAqmIfPeekPokeFastMutex[IX_QMGR_MAX_NUM_QUEUES];
+
+/*
+ * Function prototypes
+ */
+PRIVATE unsigned
+watermarkToAqmWatermark (IxQMgrWMLevel watermark );
+
+PRIVATE unsigned
+entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize);
+
+PRIVATE unsigned
+bufferSizeToAqmBufferSize (unsigned bufferSizeInWords);
+
+PRIVATE void
+ixQMgrAqmIfRegistersReset (void);
+
+PRIVATE void
+ixQMgrAqmIfEntryAddressGet (unsigned int entryIndex,
+ UINT32 configRegWord,
+ unsigned int qEntrySizeInwords,
+ unsigned int qSizeInWords,
+ UINT32 **address);
+/*
+ * Function definitions
+ */
+void
+ixQMgrAqmIfInit (void)
+{
+ UINT32 aqmVirtualAddr;
+ int i;
+
+ /* The value of aqmBaseAddress depends on the logical address
+ * assigned by the MMU.
+ */
+ aqmVirtualAddr =
+ (UINT32) IX_OSAL_MEM_MAP(IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS,
+ IX_OSAL_IXP400_QMGR_MAP_SIZE);
+ IX_OSAL_ASSERT (aqmVirtualAddr);
+
+ ixQMgrAqmIfBaseAddressSet (aqmVirtualAddr);
+
+ ixQMgrAqmIfRegistersReset ();
+
+ for (i = 0; i< IX_QMGR_MAX_NUM_QUEUES; i++)
+ {
+ ixOsalFastMutexInit(&ixQMgrAqmIfPeekPokeFastMutex[i]);
+
+ /********************************************************************
+ * Register addresses and bit masks are calculated and stored here to
+ * facilitate inlining of QRead, QWrite and QStatusGet functions in
+ * IxQMgr.h.
+ * These calculations are normally performed dynamically in inlined
+ * functions in IxQMgrAqmIf_p.h, and their semantics are reused here.
+ */
+
+ /* AQM Queue access reg addresses, per queue */
+ ixQMgrAqmIfQueAccRegAddr[i] =
+ (UINT32 *)(aqmBaseAddress + IX_QMGR_Q_ACCESS_ADDR_GET(i));
+ ixQMgrQInlinedReadWriteInfo[i].qAccRegAddr =
+ (volatile UINT32 *)(aqmBaseAddress + IX_QMGR_Q_ACCESS_ADDR_GET(i));
+
+
+ ixQMgrQInlinedReadWriteInfo[i].qConfigRegAddr =
+ (volatile UINT32 *)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(i));
+
+ /* AQM Queue lower-group (0-31), only */
+ if (i < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ /* AQM Q underflow/overflow status register addresses, per queue */
+ ixQMgrQInlinedReadWriteInfo[i].qUOStatRegAddr =
+ (volatile UINT32 *)(aqmBaseAddress +
+ IX_QMGR_QUEUOSTAT0_OFFSET +
+ ((i / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD) *
+ IX_QMGR_NUM_BYTES_PER_WORD));
+
+ /* AQM Q underflow status bit masks for status register per queue */
+ ixQMgrQInlinedReadWriteInfo[i].qUflowStatBitMask =
+ (IX_QMGR_UNDERFLOW_BIT_OFFSET + 1) <<
+ ((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) *
+ (BITS_PER_WORD / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD));
+
+ /* AQM Q overflow status bit masks for status register, per queue */
+ ixQMgrQInlinedReadWriteInfo[i].qOflowStatBitMask =
+ (IX_QMGR_OVERFLOW_BIT_OFFSET + 1) <<
+ ((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) *
+ (BITS_PER_WORD / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD));
+
+ /* AQM Q lower-group (0-31) status register addresses, per queue */
+ ixQMgrAqmIfQueLowStatRegAddr[i] = aqmBaseAddress +
+ IX_QMGR_QUELOWSTAT0_OFFSET +
+ ((i / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) *
+ IX_QMGR_NUM_BYTES_PER_WORD);
+
+ /* AQM Q lower-group (0-31) status register bit offset */
+ ixQMgrAqmIfQueLowStatBitsOffset[i] =
+ (i & (IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD - 1)) *
+ (BITS_PER_WORD / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD);
+ }
+ else /* AQM Q upper-group (32-63), only */
+ {
+ /* AQM Q upper-group (32-63) Nearly Empty status reg bit masks */
+ ixQMgrAqmIfQueUppStat0BitMask[i - IX_QMGR_MIN_QUEUPP_QID] =
+ (1 << (i - IX_QMGR_MIN_QUEUPP_QID));
+
+ /* AQM Q upper-group (32-63) Full status register bit masks */
+ ixQMgrAqmIfQueUppStat1BitMask[i - IX_QMGR_MIN_QUEUPP_QID] =
+ (1 << (i - IX_QMGR_MIN_QUEUPP_QID));
+ }
+ }
+
+ /* AQM Q lower-group (0-31) status register bit mask */
+ ixQMgrAqmIfQueLowStatBitsMask = (1 <<
+ (BITS_PER_WORD /
+ IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)) - 1;
+
+ /* AQM Q upper-group (32-63) Nearly Empty status register address */
+ ixQMgrAqmIfQueUppStat0RegAddr = aqmBaseAddress + IX_QMGR_QUEUPPSTAT0_OFFSET;
+
+ /* AQM Q upper-group (32-63) Full status register address */
+ ixQMgrAqmIfQueUppStat1RegAddr = aqmBaseAddress + IX_QMGR_QUEUPPSTAT1_OFFSET;
+}
+
+/*
+ * Uninitialise the AqmIf module by unmapping memory, etc
+ */
+void
+ixQMgrAqmIfUninit (void)
+{
+ UINT32 virtAddr;
+
+ ixQMgrAqmIfBaseAddressGet (&virtAddr);
+ IX_OSAL_MEM_UNMAP (virtAddr);
+ ixQMgrAqmIfBaseAddressSet (0);
+}
+
+/*
+ * Set the the logical base address of AQM
+ */
+void
+ixQMgrAqmIfBaseAddressSet (UINT32 address)
+{
+ aqmBaseAddress = address;
+}
+
+/*
+ * Get the logical base address of AQM
+ */
+void
+ixQMgrAqmIfBaseAddressGet (UINT32 *address)
+{
+ *address = aqmBaseAddress;
+}
+
+/*
+ * Get the logical base address of AQM SRAM
+ */
+void
+ixQMgrAqmIfSramBaseAddressGet (UINT32 *address)
+{
+ *address = aqmBaseAddress +
+ IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET;
+}
+
+/*
+ * This function will write the status bits of a queue
+ * specified by qId.
+ */
+void
+ixQMgrAqmIfQRegisterBitsWrite (IxQMgrQId qId,
+ UINT32 registerBaseAddrOffset,
+ unsigned queuesPerRegWord,
+ UINT32 value)
+{
+ volatile UINT32 *registerAddress;
+ UINT32 registerWord;
+ UINT32 statusBitsMask;
+ UINT32 bitsPerQueue;
+
+ bitsPerQueue = BITS_PER_WORD / queuesPerRegWord;
+
+ /*
+ * Calculate the registerAddress
+ * multiple queues split accross registers
+ */
+ registerAddress = (UINT32*)(aqmBaseAddress +
+ registerBaseAddrOffset +
+ ((qId / queuesPerRegWord) *
+ IX_QMGR_NUM_BYTES_PER_WORD));
+
+ /* Read the current data */
+ ixQMgrAqmIfWordRead (registerAddress, &registerWord);
+
+
+ if( (registerBaseAddrOffset == IX_QMGR_INT0SRCSELREG0_OFFSET) &&
+ (qId == IX_QMGR_QUEUE_0) )
+ {
+ statusBitsMask = 0x7 ;
+
+ /* Queue 0 at INT0SRCSELREG should not corrupt the value bit-3 */
+ value &= 0x7 ;
+ }
+ else
+ {
+ /* Calculate the mask for the status bits for this queue. */
+ statusBitsMask = ((1 << bitsPerQueue) - 1);
+ statusBitsMask <<= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue);
+
+ /* Mask out bits in value that would overwrite other q data */
+ value <<= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue);
+ value &= statusBitsMask;
+ }
+
+ /* Mask out bits to write to */
+ registerWord &= ~statusBitsMask;
+
+
+ /* Set the write bits */
+ registerWord |= value;
+
+ /*
+ * Write the data
+ */
+ ixQMgrAqmIfWordWrite (registerAddress, registerWord);
+}
+
+/*
+ * This function generates the parameters that can be used to
+ * check if a Qs status matches the specified source select.
+ * It calculates which status word to check (statusWordOffset),
+ * the value to check the status against (checkValue) and the
+ * mask (mask) to mask out all but the bits to check in the status word.
+ */
+void
+ixQMgrAqmIfQStatusCheckValsCalc (IxQMgrQId qId,
+ IxQMgrSourceId srcSel,
+ unsigned int *statusWordOffset,
+ UINT32 *checkValue,
+ UINT32 *mask)
+{
+ UINT32 shiftVal;
+
+ if (qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ switch (srcSel)
+ {
+ case IX_QMGR_Q_SOURCE_ID_E:
+ *checkValue = IX_QMGR_Q_STATUS_E_BIT_MASK;
+ *mask = IX_QMGR_Q_STATUS_E_BIT_MASK;
+ break;
+ case IX_QMGR_Q_SOURCE_ID_NE:
+ *checkValue = IX_QMGR_Q_STATUS_NE_BIT_MASK;
+ *mask = IX_QMGR_Q_STATUS_NE_BIT_MASK;
+ break;
+ case IX_QMGR_Q_SOURCE_ID_NF:
+ *checkValue = IX_QMGR_Q_STATUS_NF_BIT_MASK;
+ *mask = IX_QMGR_Q_STATUS_NF_BIT_MASK;
+ break;
+ case IX_QMGR_Q_SOURCE_ID_F:
+ *checkValue = IX_QMGR_Q_STATUS_F_BIT_MASK;
+ *mask = IX_QMGR_Q_STATUS_F_BIT_MASK;
+ break;
+ case IX_QMGR_Q_SOURCE_ID_NOT_E:
+ *checkValue = 0;
+ *mask = IX_QMGR_Q_STATUS_E_BIT_MASK;
+ break;
+ case IX_QMGR_Q_SOURCE_ID_NOT_NE:
+ *checkValue = 0;
+ *mask = IX_QMGR_Q_STATUS_NE_BIT_MASK;
+ break;
+ case IX_QMGR_Q_SOURCE_ID_NOT_NF:
+ *checkValue = 0;
+ *mask = IX_QMGR_Q_STATUS_NF_BIT_MASK;
+ break;
+ case IX_QMGR_Q_SOURCE_ID_NOT_F:
+ *checkValue = 0;
+ *mask = IX_QMGR_Q_STATUS_F_BIT_MASK;
+ break;
+ default:
+ /* Should never hit */
+ IX_OSAL_ASSERT(0);
+ break;
+ }
+
+ /* One nibble of status per queue so need to shift the
+ * check value and mask out to the correct position.
+ */
+ shiftVal = (qId % IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) *
+ IX_QMGR_QUELOWSTAT_BITS_PER_Q;
+
+ /* Calculate the which status word to check from the qId,
+ * 8 Qs status per word
+ */
+ *statusWordOffset = qId / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD;
+
+ *checkValue <<= shiftVal;
+ *mask <<= shiftVal;
+ }
+ else
+ {
+ /* One status word */
+ *statusWordOffset = 0;
+ /* Single bits per queue and int source bit hardwired NE,
+ * Qs start at 32.
+ */
+ *mask = 1 << (qId - IX_QMGR_MIN_QUEUPP_QID);
+ *checkValue = *mask;
+ }
+}
+
+void
+ixQMgrAqmIfQInterruptEnable (IxQMgrQId qId)
+{
+ volatile UINT32 *registerAddress;
+ UINT32 registerWord;
+ UINT32 actualBitOffset;
+
+ if (qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET);
+ }
+ else
+ {
+ registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET);
+ }
+
+ actualBitOffset = 1 << (qId % IX_QMGR_MIN_QUEUPP_QID);
+
+ ixQMgrAqmIfWordRead (registerAddress, &registerWord);
+ ixQMgrAqmIfWordWrite (registerAddress, (registerWord | actualBitOffset));
+}
+
+void
+ixQMgrAqmIfQInterruptDisable (IxQMgrQId qId)
+{
+ volatile UINT32 *registerAddress;
+ UINT32 registerWord;
+ UINT32 actualBitOffset;
+
+ if (qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET);
+ }
+ else
+ {
+ registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET);
+ }
+
+ actualBitOffset = 1 << (qId % IX_QMGR_MIN_QUEUPP_QID);
+
+ ixQMgrAqmIfWordRead (registerAddress, &registerWord);
+ ixQMgrAqmIfWordWrite (registerAddress, registerWord & (~actualBitOffset));
+}
+
+void
+ixQMgrAqmIfQueCfgWrite (IxQMgrQId qId,
+ IxQMgrQSizeInWords qSizeInWords,
+ IxQMgrQEntrySizeInWords entrySizeInWords,
+ UINT32 freeSRAMAddress)
+{
+ volatile UINT32 *cfgAddress = NULL;
+ UINT32 qCfg = 0;
+ UINT32 baseAddress = 0;
+ unsigned aqmEntrySize = 0;
+ unsigned aqmBufferSize = 0;
+
+ /* Build config register */
+ aqmEntrySize = entrySizeToAqmEntrySize (entrySizeInWords);
+ qCfg |= (aqmEntrySize&IX_QMGR_ENTRY_SIZE_MASK) <<
+ IX_QMGR_Q_CONFIG_ESIZE_OFFSET;
+
+ aqmBufferSize = bufferSizeToAqmBufferSize (qSizeInWords);
+ qCfg |= (aqmBufferSize&IX_QMGR_SIZE_MASK) << IX_QMGR_Q_CONFIG_BSIZE_OFFSET;
+
+ /* baseAddress, calculated relative to aqmBaseAddress and start address */
+ baseAddress = freeSRAMAddress -
+ (aqmBaseAddress + IX_QMGR_QUECONFIG_BASE_OFFSET);
+
+ /* Verify base address aligned to a 16 word boundary */
+ if ((baseAddress % IX_QMGR_BASE_ADDR_16_WORD_ALIGN) != 0)
+ {
+ IX_QMGR_LOG_ERROR0("ixQMgrAqmIfQueCfgWrite () address is not on 16 word boundary\n");
+ }
+ /* Now convert it to a 16 word pointer as required by QUECONFIG register */
+ baseAddress >>= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
+
+
+ qCfg |= (baseAddress << IX_QMGR_Q_CONFIG_BADDR_OFFSET);
+
+
+ cfgAddress = (UINT32*)(aqmBaseAddress +
+ IX_QMGR_Q_CONFIG_ADDR_GET(qId));
+
+
+ /* NOTE: High and Low watermarks are set to zero */
+ ixQMgrAqmIfWordWrite (cfgAddress, qCfg);
+}
+
+void
+ixQMgrAqmIfQueCfgRead (IxQMgrQId qId,
+ unsigned int numEntries,
+ UINT32 *baseAddress,
+ unsigned int *ne,
+ unsigned int *nf,
+ UINT32 *readPtr,
+ UINT32 *writePtr)
+{
+ UINT32 qcfg;
+ UINT32 *cfgAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
+ unsigned int qEntrySizeInwords;
+ unsigned int qSizeInWords;
+ UINT32 *readPtr_ = NULL;
+
+ /* Read the queue configuration register */
+ ixQMgrAqmIfWordRead (cfgAddress, &qcfg);
+
+ /* Extract the base address */
+ *baseAddress = (UINT32)((qcfg & IX_QMGR_BADDR_MASK) >>
+ (IX_QMGR_Q_CONFIG_BADDR_OFFSET));
+
+ /* Base address is a 16 word pointer from the start of AQM SRAM.
+ * Convert to absolute word address.
+ */
+ *baseAddress <<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
+ *baseAddress += (UINT32)IX_QMGR_QUECONFIG_BASE_OFFSET;
+
+ /*
+ * Extract the watermarks. 0->0 entries, 1->1 entries, 2->2 entries, 3->4 entries......
+ * If ne > 0 ==> neInEntries = 2^(ne - 1)
+ * If ne == 0 ==> neInEntries = 0
+ * The same applies.
+ */
+ *ne = ((qcfg) >> (IX_QMGR_Q_CONFIG_NE_OFFSET)) & IX_QMGR_NE_MASK;
+ *nf = ((qcfg) >> (IX_QMGR_Q_CONFIG_NF_OFFSET)) & IX_QMGR_NF_MASK;
+
+ if (0 != *ne)
+ {
+ *ne = 1 << (*ne - 1);
+ }
+ if (0 != *nf)
+ {
+ *nf = 1 << (*nf - 1);
+ }
+
+ /* Get the queue entry size in words */
+ qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);
+
+ /* Get the queue size in words */
+ qSizeInWords = ixQMgrQSizeInWordsGet (qId);
+
+ ixQMgrAqmIfEntryAddressGet (0/* Entry 0. i.e the readPtr*/,
+ qcfg,
+ qEntrySizeInwords,
+ qSizeInWords,
+ &readPtr_);
+ *readPtr = (UINT32)readPtr_;
+ *readPtr -= (UINT32)aqmBaseAddress;/* Offset, not absolute address */
+
+ *writePtr = (qcfg >> IX_QMGR_Q_CONFIG_WRPTR_OFFSET) & IX_QMGR_WRPTR_MASK;
+ *writePtr = *baseAddress + (*writePtr * (IX_QMGR_NUM_BYTES_PER_WORD));
+ return;
+}
+
+unsigned
+ixQMgrAqmIfLog2 (unsigned number)
+{
+ unsigned count = 0;
+
+ /*
+ * N.B. this function will return 0
+ * for ixQMgrAqmIfLog2 (0)
+ */
+ while (number/2)
+ {
+ number /=2;
+ count++;
+ }
+
+ return count;
+}
+
+void ixQMgrAqmIfIntSrcSelReg0Bit3Set (void)
+{
+
+ volatile UINT32 *registerAddress;
+ UINT32 registerWord;
+
+ /*
+ * Calculate the registerAddress
+ * multiple queues split accross registers
+ */
+ registerAddress = (UINT32*)(aqmBaseAddress +
+ IX_QMGR_INT0SRCSELREG0_OFFSET);
+
+ /* Read the current data */
+ ixQMgrAqmIfWordRead (registerAddress, &registerWord);
+
+ /* Set the write bits */
+ registerWord |= (1<<IX_QMGR_INT0SRCSELREG0_BIT3) ;
+
+ /*
+ * Write the data
+ */
+ ixQMgrAqmIfWordWrite (registerAddress, registerWord);
+}
+
+
+void
+ixQMgrAqmIfIntSrcSelWrite (IxQMgrQId qId,
+ IxQMgrSourceId sourceId)
+{
+ ixQMgrAqmIfQRegisterBitsWrite (qId,
+ IX_QMGR_INT0SRCSELREG0_OFFSET,
+ IX_QMGR_INTSRC_NUM_QUE_PER_WORD,
+ sourceId);
+}
+
+
+
+void
+ixQMgrAqmIfWatermarkSet (IxQMgrQId qId,
+ unsigned ne,
+ unsigned nf)
+{
+ volatile UINT32 *address = 0;
+ UINT32 value = 0;
+ unsigned aqmNeWatermark = 0;
+ unsigned aqmNfWatermark = 0;
+
+ address = (UINT32*)(aqmBaseAddress +
+ IX_QMGR_Q_CONFIG_ADDR_GET(qId));
+
+ aqmNeWatermark = watermarkToAqmWatermark (ne);
+ aqmNfWatermark = watermarkToAqmWatermark (nf);
+
+ /* Read the current watermarks */
+ ixQMgrAqmIfWordRead (address, &value);
+
+ /* Clear out the old watermarks */
+ value &= IX_QMGR_NE_NF_CLEAR_MASK;
+
+ /* Generate the value to write */
+ value |= (aqmNeWatermark << IX_QMGR_Q_CONFIG_NE_OFFSET) |
+ (aqmNfWatermark << IX_QMGR_Q_CONFIG_NF_OFFSET);
+
+ ixQMgrAqmIfWordWrite (address, value);
+
+}
+
+PRIVATE void
+ixQMgrAqmIfEntryAddressGet (unsigned int entryIndex,
+ UINT32 configRegWord,
+ unsigned int qEntrySizeInwords,
+ unsigned int qSizeInWords,
+ UINT32 **address)
+{
+ UINT32 readPtr;
+ UINT32 baseAddress;
+ UINT32 *topOfAqmSram;
+
+ topOfAqmSram = ((UINT32 *)aqmBaseAddress + IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS);
+
+ /* Extract the base address */
+ baseAddress = (UINT32)((configRegWord & IX_QMGR_BADDR_MASK) >>
+ (IX_QMGR_Q_CONFIG_BADDR_OFFSET));
+
+ /* Base address is a 16 word pointer from the start of AQM SRAM.
+ * Convert to absolute word address.
+ */
+ baseAddress <<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
+ baseAddress += ((UINT32)aqmBaseAddress + (UINT32)IX_QMGR_QUECONFIG_BASE_OFFSET);
+
+ /* Extract the read pointer. Read pointer is a word pointer */
+ readPtr = (UINT32)((configRegWord >>
+ IX_QMGR_Q_CONFIG_RDPTR_OFFSET)&IX_QMGR_RDPTR_MASK);
+
+ /* Read/Write pointers(word pointers) are offsets from the queue buffer space base address.
+ * Calculate the absolute read pointer address. NOTE: Queues are circular buffers.
+ */
+ readPtr = (readPtr + (entryIndex * qEntrySizeInwords)) & (qSizeInWords - 1); /* Mask by queue size */
+ *address = (UINT32 *)(baseAddress + (readPtr * (IX_QMGR_NUM_BYTES_PER_WORD)));
+
+ switch (qEntrySizeInwords)
+ {
+ case IX_QMGR_Q_ENTRY_SIZE1:
+ IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY1_OFFSET) < topOfAqmSram);
+ break;
+ case IX_QMGR_Q_ENTRY_SIZE2:
+ IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY2_OFFSET) < topOfAqmSram);
+ break;
+ case IX_QMGR_Q_ENTRY_SIZE4:
+ IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY4_OFFSET) < topOfAqmSram);
+ break;
+ default:
+ IX_QMGR_LOG_ERROR0("Invalid Q Entry size passed to ixQMgrAqmIfEntryAddressGet");
+ break;
+ }
+
+}
+
+IX_STATUS
+ixQMgrAqmIfQPeek (IxQMgrQId qId,
+ unsigned int entryIndex,
+ unsigned int *entry)
+{
+ UINT32 *cfgRegAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
+ UINT32 *entryAddress = NULL;
+ UINT32 configRegWordOnEntry;
+ UINT32 configRegWordOnExit;
+ unsigned int qEntrySizeInwords;
+ unsigned int qSizeInWords;
+
+ /* Get the queue entry size in words */
+ qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);
+
+ /* Get the queue size in words */
+ qSizeInWords = ixQMgrQSizeInWordsGet (qId);
+
+ /* Read the config register */
+ ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnEntry);
+
+ /* Get the entry address */
+ ixQMgrAqmIfEntryAddressGet (entryIndex,
+ configRegWordOnEntry,
+ qEntrySizeInwords,
+ qSizeInWords,
+ &entryAddress);
+
+ /* Get the lock or return busy */
+ if (IX_SUCCESS != ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex[qId]))
+ {
+ return IX_FAIL;
+ }
+
+ while(qEntrySizeInwords--)
+ {
+ ixQMgrAqmIfWordRead (entryAddress++, entry++);
+ }
+
+ /* Release the lock */
+ ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex[qId]);
+
+ /* Read the config register */
+ ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnExit);
+
+ /* Check that the read and write pointers have not changed */
+ if (configRegWordOnEntry != configRegWordOnExit)
+ {
+ return IX_FAIL;
+ }
+
+ return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrAqmIfQPoke (IxQMgrQId qId,
+ unsigned entryIndex,
+ unsigned int *entry)
+{
+ UINT32 *cfgRegAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
+ UINT32 *entryAddress = NULL;
+ UINT32 configRegWordOnEntry;
+ UINT32 configRegWordOnExit;
+ unsigned int qEntrySizeInwords;
+ unsigned int qSizeInWords;
+
+ /* Get the queue entry size in words */
+ qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);
+
+ /* Get the queue size in words */
+ qSizeInWords = ixQMgrQSizeInWordsGet (qId);
+
+ /* Read the config register */
+ ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnEntry);
+
+ /* Get the entry address */
+ ixQMgrAqmIfEntryAddressGet (entryIndex,
+ configRegWordOnEntry,
+ qEntrySizeInwords,
+ qSizeInWords,
+ &entryAddress);
+
+ /* Get the lock or return busy */
+ if (IX_SUCCESS != ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex[qId]))
+ {
+ return IX_FAIL;
+ }
+
+ /* Else read the entry directly from SRAM. This will not move the read pointer */
+ while(qEntrySizeInwords--)
+ {
+ ixQMgrAqmIfWordWrite (entryAddress++, *entry++);
+ }
+
+ /* Release the lock */
+ ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex[qId]);
+
+ /* Read the config register */
+ ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnExit);
+
+ /* Check that the read and write pointers have not changed */
+ if (configRegWordOnEntry != configRegWordOnExit)
+ {
+ return IX_FAIL;
+ }
+
+ return IX_SUCCESS;
+}
+
+PRIVATE unsigned
+watermarkToAqmWatermark (IxQMgrWMLevel watermark )
+{
+ unsigned aqmWatermark = 0;
+
+ /*
+ * Watermarks 0("000"),1("001"),2("010"),4("011"),
+ * 8("100"),16("101"),32("110"),64("111")
+ */
+ aqmWatermark = ixQMgrAqmIfLog2 (watermark * 2);
+
+ return aqmWatermark;
+}
+
+PRIVATE unsigned
+entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize)
+{
+ /* entrySize 1("00"),2("01"),4("10") */
+ return (ixQMgrAqmIfLog2 (entrySize));
+}
+
+PRIVATE unsigned
+bufferSizeToAqmBufferSize (unsigned bufferSizeInWords)
+{
+ /* bufferSize 16("00"),32("01),64("10"),128("11") */
+ return (ixQMgrAqmIfLog2 (bufferSizeInWords / IX_QMGR_MIN_BUFFER_SIZE));
+}
+
+/*
+ * Reset AQM registers to default values.
+ */
+PRIVATE void
+ixQMgrAqmIfRegistersReset (void)
+{
+ volatile UINT32 *qConfigWordAddress = NULL;
+ unsigned int i;
+
+ /*
+ * Need to initialize AQM hardware registers to an initial
+ * value as init may have been called as a result of a soft
+ * reset. i.e. soft reset does not reset hardware registers.
+ */
+
+ /* Reset queues 0..31 status registers 0..3 */
+ ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT0_OFFSET),
+ IX_QMGR_QUELOWSTAT_RESET_VALUE);
+ ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT1_OFFSET),
+ IX_QMGR_QUELOWSTAT_RESET_VALUE);
+ ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT2_OFFSET),
+ IX_QMGR_QUELOWSTAT_RESET_VALUE);
+ ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT3_OFFSET),
+ IX_QMGR_QUELOWSTAT_RESET_VALUE);
+
+ /* Reset underflow/overflow status registers 0..1 */
+ ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUOSTAT0_OFFSET),
+ IX_QMGR_QUEUOSTAT_RESET_VALUE);
+ ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUOSTAT1_OFFSET),
+ IX_QMGR_QUEUOSTAT_RESET_VALUE);
+
+ /* Reset queues 32..63 nearly empty status registers */
+ ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUPPSTAT0_OFFSET),
+ IX_QMGR_QUEUPPSTAT0_RESET_VALUE);
+
+ /* Reset queues 32..63 full status registers */
+ ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUPPSTAT1_OFFSET),
+ IX_QMGR_QUEUPPSTAT1_RESET_VALUE);
+
+ /* Reset int0 status flag source select registers 0..3 */
+ ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG0_OFFSET),
+ IX_QMGR_INT0SRCSELREG_RESET_VALUE);
+ ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG1_OFFSET),
+ IX_QMGR_INT0SRCSELREG_RESET_VALUE);
+ ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG2_OFFSET),
+ IX_QMGR_INT0SRCSELREG_RESET_VALUE);
+ ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG3_OFFSET),
+ IX_QMGR_INT0SRCSELREG_RESET_VALUE);
+
+ /* Reset queue interrupt enable register 0..1 */
+ ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET),
+ IX_QMGR_QUEIEREG_RESET_VALUE);
+ ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET),
+ IX_QMGR_QUEIEREG_RESET_VALUE);
+
+ /* Reset queue interrupt register 0..1 */
+ ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QINTREG0_OFFSET),
+ IX_QMGR_QINTREG_RESET_VALUE);
+ ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QINTREG1_OFFSET),
+ IX_QMGR_QINTREG_RESET_VALUE);
+
+ /* Reset queue configuration words 0..63 */
+ qConfigWordAddress = (UINT32 *)(aqmBaseAddress + IX_QMGR_QUECONFIG_BASE_OFFSET);
+ for (i = 0; i < (IX_QMGR_QUECONFIG_SIZE / sizeof(UINT32)); i++)
+ {
+ ixQMgrAqmIfWordWrite(qConfigWordAddress,
+ IX_QMGR_QUECONFIG_RESET_VALUE);
+ /* Next word */
+ qConfigWordAddress++;
+ }
+}
+
diff --git a/cpu/ixp/npe/IxQMgrDispatcher.c b/cpu/ixp/npe/IxQMgrDispatcher.c
new file mode 100644
index 0000000..09f69ce
--- /dev/null
+++ b/cpu/ixp/npe/IxQMgrDispatcher.c
@@ -0,0 +1,1347 @@
+/**
+ * @file IxQMgrDispatcher.c
+ *
+ * @author Intel Corporation
+ * @date 20-Dec-2001
+ *
+ * @brief This file contains the implementation of the Dispatcher sub component
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * User defined include files.
+ */
+#include "IxQMgr.h"
+#include "IxQMgrAqmIf_p.h"
+#include "IxQMgrQCfg_p.h"
+#include "IxQMgrDispatcher_p.h"
+#include "IxQMgrLog_p.h"
+#include "IxQMgrDefines_p.h"
+#include "IxFeatureCtrl.h"
+#include "IxOsal.h"
+
+
+
+/*
+ * #defines and macros used in this file.
+ */
+
+
+/*
+ * This constant is used to indicate the number of priority levels supported
+ */
+#define IX_QMGR_NUM_PRIORITY_LEVELS 3
+
+/*
+ * This constant is used to set the size of the array of status words
+ */
+#define MAX_Q_STATUS_WORDS 4
+
+/*
+ * This macro is used to check if a given priority is valid
+ */
+#define IX_QMGR_DISPATCHER_PRIORITY_CHECK(priority) \
+(((priority) >= IX_QMGR_Q_PRIORITY_0) && ((priority) <= IX_QMGR_Q_PRIORITY_2))
+
+/*
+ * This macto is used to check that a given interrupt source is valid
+ */
+#define IX_QMGR_DISPATCHER_SOURCE_ID_CHECK(srcSel) \
+(((srcSel) >= IX_QMGR_Q_SOURCE_ID_E) && ((srcSel) <= IX_QMGR_Q_SOURCE_ID_NOT_F))
+
+/*
+ * Number of times a dummy callback is called before logging a trace
+ * message
+ */
+#define LOG_THROTTLE_COUNT 1000000
+
+/* Priority tables limits */
+#define IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX (0)
+#define IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX (16)
+#define IX_QMGR_MAX_LOW_QUE_PRIORITY_TABLE_INDEX (31)
+#define IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX (32)
+#define IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX (48)
+#define IX_QMGR_MAX_UPP_QUE_PRIORITY_TABLE_INDEX (63)
+
+/*
+ * This macro is used to check if a given callback type is valid
+ */
+#define IX_QMGR_DISPATCHER_CALLBACK_TYPE_CHECK(type) \
+ (((type) >= IX_QMGR_TYPE_REALTIME_OTHER) && \
+ ((type) <= IX_QMGR_TYPE_REALTIME_SPORADIC))
+
+/*
+ * define max index in lower queue to use in loops
+ */
+#define IX_QMGR_MAX_LOW_QUE_TABLE_INDEX (31)
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/*
+ * Information on a queue needed by the Dispatcher
+ */
+typedef struct
+{
+ IxQMgrCallback callback; /* Notification callback */
+ IxQMgrCallbackId callbackId; /* Notification callback identifier */
+ unsigned dummyCallbackCount; /* Number of times runs of dummy callback */
+ IxQMgrPriority priority; /* Dispatch priority */
+ unsigned int statusWordOffset; /* Offset to the status word to check */
+ UINT32 statusMask; /* Status mask */
+ UINT32 statusCheckValue; /* Status check value */
+ UINT32 intRegCheckMask; /* Interrupt register check mask */
+} IxQMgrQInfo;
+
+/*
+ * Variable declarations global to this file. Externs are followed by
+ * statics.
+ */
+
+/*
+ * Flag to keep record of what dispatcher set in featureCtrl when ixQMgrInit()
+ * is called. This is needed because it is possible that a client might
+ * change whether the live lock prevention dispatcher is used between
+ * calls to ixQMgrInit() and ixQMgrDispatcherLoopGet().
+ */
+PRIVATE IX_STATUS ixQMgrOrigB0Dispatcher = IX_FEATURE_CTRL_COMPONENT_ENABLED;
+
+/*
+ * keep record of Q types - not in IxQMgrQInfo for performance as
+ * it is only used with ixQMgrDispatcherLoopRunB0LLP()
+ */
+PRIVATE IxQMgrType ixQMgrQTypes[IX_QMGR_MAX_NUM_QUEUES];
+
+/*
+ * This array contains a list of queue identifiers ordered by priority. The table
+ * is split logically between queue identifiers 0-31 and 32-63.
+ */
+static IxQMgrQId priorityTable[IX_QMGR_MAX_NUM_QUEUES];
+
+/*
+ * This flag indicates to the dispatcher that the priority table needs to be rebuilt.
+ */
+static BOOL rebuildTable = FALSE;
+
+/* Dispatcher statistics */
+static IxQMgrDispatcherStats dispatcherStats;
+
+/* Table of queue information */
+static IxQMgrQInfo dispatchQInfo[IX_QMGR_MAX_NUM_QUEUES];
+
+/* Masks use to identify the first queues in the priority tables
+* when comparing with the interrupt register
+*/
+static unsigned int lowPriorityTableFirstHalfMask;
+static unsigned int uppPriorityTableFirstHalfMask;
+
+/*
+ * Static function prototypes
+ */
+
+/*
+ * This function is the default callback for all queues
+ */
+PRIVATE void
+dummyCallback (IxQMgrQId qId,
+ IxQMgrCallbackId cbId);
+
+PRIVATE void
+ixQMgrDispatcherReBuildPriorityTable (void);
+
+/*
+ * Function definitions.
+ */
+void
+ixQMgrDispatcherInit (void)
+{
+ int i;
+ IxFeatureCtrlProductId productId = 0;
+ IxFeatureCtrlDeviceId deviceId = 0;
+ BOOL stickyIntSilicon = TRUE;
+
+ /* Set default priorities */
+ for (i=0; i< IX_QMGR_MAX_NUM_QUEUES; i++)
+ {
+ dispatchQInfo[i].callback = dummyCallback;
+ dispatchQInfo[i].callbackId = 0;
+ dispatchQInfo[i].dummyCallbackCount = 0;
+ dispatchQInfo[i].priority = IX_QMGR_Q_PRIORITY_2;
+ dispatchQInfo[i].statusWordOffset = 0;
+ dispatchQInfo[i].statusCheckValue = 0;
+ dispatchQInfo[i].statusMask = 0;
+ /*
+ * There are two interrupt registers, 32 bits each. One for the lower
+ * queues(0-31) and one for the upper queues(32-63). Therefore need to
+ * mod by 32 i.e the min upper queue identifier.
+ */
+ dispatchQInfo[i].intRegCheckMask = (1<<(i%(IX_QMGR_MIN_QUEUPP_QID)));
+
+ /*
+ * Set the Q types - will only be used with livelock
+ */
+ ixQMgrQTypes[i] = IX_QMGR_TYPE_REALTIME_OTHER;
+
+ /* Reset queue statistics */
+ dispatcherStats.queueStats[i].callbackCnt = 0;
+ dispatcherStats.queueStats[i].priorityChangeCnt = 0;
+ dispatcherStats.queueStats[i].intNoCallbackCnt = 0;
+ dispatcherStats.queueStats[i].intLostCallbackCnt = 0;
+ dispatcherStats.queueStats[i].notificationEnabled = FALSE;
+ dispatcherStats.queueStats[i].srcSel = 0;
+
+ }
+
+ /* Priority table. Order the table from queue 0 to 63 */
+ ixQMgrDispatcherReBuildPriorityTable();
+
+ /* Reset statistics */
+ dispatcherStats.loopRunCnt = 0;
+
+ /* Get the device ID for the underlying silicon */
+ deviceId = ixFeatureCtrlDeviceRead();
+
+ /* Get the product ID for the underlying silicon */
+ productId = ixFeatureCtrlProductIdRead();
+
+ /*
+ * Check featureCtrl to see if Livelock prevention is required
+ */
+ ixQMgrOrigB0Dispatcher = ixFeatureCtrlSwConfigurationCheck(
+ IX_FEATURECTRL_ORIGB0_DISPATCHER);
+
+ /*
+ * Check if the silicon supports the sticky interrupt feature.
+ * IF (IXP42X AND A0) -> No sticky interrupt feature supported
+ */
+ if ((IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X ==
+ (IX_FEATURE_CTRL_DEVICE_TYPE_MASK & deviceId)) &&
+ (IX_FEATURE_CTRL_SILICON_TYPE_A0 ==
+ (IX_FEATURE_CTRL_SILICON_STEPPING_MASK & productId)))
+ {
+ stickyIntSilicon = FALSE;
+ }
+
+ /*
+ * IF user wants livelock prev option AND silicon supports sticky interrupt
+ * feature -> enable the sticky interrupt bit
+ */
+ if ((IX_FEATURE_CTRL_SWCONFIG_DISABLED == ixQMgrOrigB0Dispatcher) &&
+ stickyIntSilicon)
+ {
+ ixQMgrStickyInterruptRegEnable();
+ }
+}
+
+IX_STATUS
+ixQMgrDispatcherPrioritySet (IxQMgrQId qId,
+ IxQMgrPriority priority)
+{
+ int ixQMgrLockKey;
+
+ if (!ixQMgrQIsConfigured(qId))
+ {
+ return IX_QMGR_Q_NOT_CONFIGURED;
+ }
+
+ if (!IX_QMGR_DISPATCHER_PRIORITY_CHECK(priority))
+ {
+ return IX_QMGR_Q_INVALID_PRIORITY;
+ }
+
+ ixQMgrLockKey = ixOsalIrqLock();
+
+ /* Change priority */
+ dispatchQInfo[qId].priority = priority;
+ /* Set flag */
+ rebuildTable = TRUE;
+
+ ixOsalIrqUnlock(ixQMgrLockKey);
+
+#ifndef NDEBUG
+ /* Update statistics */
+ dispatcherStats.queueStats[qId].priorityChangeCnt++;
+#endif
+
+ return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrNotificationCallbackSet (IxQMgrQId qId,
+ IxQMgrCallback callback,
+ IxQMgrCallbackId callbackId)
+{
+ if (!ixQMgrQIsConfigured(qId))
+ {
+ return IX_QMGR_Q_NOT_CONFIGURED;
+ }
+
+ if (NULL == callback)
+ {
+ /* Reset to dummy callback */
+ dispatchQInfo[qId].callback = dummyCallback;
+ dispatchQInfo[qId].dummyCallbackCount = 0;
+ dispatchQInfo[qId].callbackId = 0;
+ }
+ else
+ {
+ dispatchQInfo[qId].callback = callback;
+ dispatchQInfo[qId].callbackId = callbackId;
+ }
+
+ return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrNotificationEnable (IxQMgrQId qId,
+ IxQMgrSourceId srcSel)
+{
+ IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */
+ IxQMgrQStatus qStatusOnExit; /* to this function */
+ int ixQMgrLockKey;
+
+#ifndef NDEBUG
+ if (!ixQMgrQIsConfigured (qId))
+ {
+ return IX_QMGR_Q_NOT_CONFIGURED;
+ }
+
+ if ((qId < IX_QMGR_MIN_QUEUPP_QID) &&
+ !IX_QMGR_DISPATCHER_SOURCE_ID_CHECK(srcSel))
+ {
+ /* QId 0-31 source id invalid */
+ return IX_QMGR_INVALID_INT_SOURCE_ID;
+ }
+
+ if ((IX_QMGR_Q_SOURCE_ID_NE != srcSel) &&
+ (qId >= IX_QMGR_MIN_QUEUPP_QID))
+ {
+ /*
+ * For queues 32-63 the interrupt source is fixed to the Nearly
+ * Empty status flag and therefore should have a srcSel of NE.
+ */
+ return IX_QMGR_INVALID_INT_SOURCE_ID;
+ }
+#endif
+
+#ifndef NDEBUG
+ dispatcherStats.queueStats[qId].notificationEnabled = TRUE;
+ dispatcherStats.queueStats[qId].srcSel = srcSel;
+#endif
+
+ /* Get the current queue status */
+ ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry);
+
+ /*
+ * Enabling interrupts results in Read-Modify-Write
+ * so need critical section
+ */
+
+ ixQMgrLockKey = ixOsalIrqLock();
+
+ /* Calculate the checkMask and checkValue for this q */
+ ixQMgrAqmIfQStatusCheckValsCalc (qId,
+ srcSel,
+ &dispatchQInfo[qId].statusWordOffset,
+ &dispatchQInfo[qId].statusCheckValue,
+ &dispatchQInfo[qId].statusMask);
+
+
+ /* Set the interupt source is this queue is in the range 0-31 */
+ if (qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ ixQMgrAqmIfIntSrcSelWrite (qId, srcSel);
+ }
+
+ /* Enable the interrupt */
+ ixQMgrAqmIfQInterruptEnable (qId);
+
+ ixOsalIrqUnlock(ixQMgrLockKey);
+
+ /* Get the current queue status */
+ ixQMgrAqmIfQueStatRead (qId, &qStatusOnExit);
+
+ /* If the status has changed return a warning */
+ if (qStatusOnEntry != qStatusOnExit)
+ {
+ return IX_QMGR_WARNING;
+ }
+
+ return IX_SUCCESS;
+}
+
+
+IX_STATUS
+ixQMgrNotificationDisable (IxQMgrQId qId)
+{
+ int ixQMgrLockKey;
+
+#ifndef NDEBUG
+ /* Validate parameters */
+ if (!ixQMgrQIsConfigured (qId))
+ {
+ return IX_QMGR_Q_NOT_CONFIGURED;
+ }
+#endif
+
+ /*
+ * Enabling interrupts results in Read-Modify-Write
+ * so need critical section
+ */
+#ifndef NDEBUG
+ dispatcherStats.queueStats[qId].notificationEnabled = FALSE;
+#endif
+
+ ixQMgrLockKey = ixOsalIrqLock();
+
+ ixQMgrAqmIfQInterruptDisable (qId);
+
+ ixOsalIrqUnlock(ixQMgrLockKey);
+
+ return IX_SUCCESS;
+}
+
+void
+ixQMgrStickyInterruptRegEnable(void)
+{
+ /* Use Aqm If function to set Interrupt Register0 Bit-3 */
+ ixQMgrAqmIfIntSrcSelReg0Bit3Set ();
+}
+
+#if !defined __XSCALE__ || defined __linux
+
+/* Count the number of leading zero bits in a word,
+ * and return the same value than the CLZ instruction.
+ *
+ * word (in) return value (out)
+ * 0x80000000 0
+ * 0x40000000 1
+ * ,,, ,,,
+ * 0x00000002 30
+ * 0x00000001 31
+ * 0x00000000 32
+ *
+ * The C version of this function is used as a replacement
+ * for system not providing the equivalent of the CLZ
+ * assembly language instruction.
+ *
+ * Note that this version is big-endian
+ */
+unsigned int
+ixQMgrCountLeadingZeros(UINT32 word)
+{
+ unsigned int leadingZerosCount = 0;
+
+ if (word == 0)
+ {
+ return 32;
+ }
+ /* search the first bit set by testing the MSB and shifting the input word */
+ while ((word & 0x80000000) == 0)
+ {
+ word <<= 1;
+ leadingZerosCount++;
+ }
+ return leadingZerosCount;
+}
+#endif /* not __XSCALE__ or __linux */
+
+void
+ixQMgrDispatcherLoopGet (IxQMgrDispatcherFuncPtr *qDispatcherFuncPtr)
+{
+ IxFeatureCtrlProductId productId = 0;
+ IxFeatureCtrlDeviceId deviceId = 0;
+
+ /* Get the device ID for the underlying silicon */
+ deviceId = ixFeatureCtrlDeviceRead();
+
+ /* Get the product ID for the underlying silicon */
+ productId = ixFeatureCtrlProductIdRead ();
+
+ /* IF (IXP42X AND A0 silicon) -> use ixQMgrDispatcherLoopRunA0 */
+ if ((IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X ==
+ (IX_FEATURE_CTRL_DEVICE_TYPE_MASK & deviceId)) &&
+ (IX_FEATURE_CTRL_SILICON_TYPE_A0 ==
+ (IX_FEATURE_CTRL_SILICON_STEPPING_MASK & productId)))
+ {
+ /*For IXP42X A0 silicon */
+ *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunA0 ;
+ }
+ else /*For IXP42X B0 or IXP46X silicon*/
+ {
+ if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == ixQMgrOrigB0Dispatcher)
+ {
+ /* Default for IXP42X B0 and IXP46X silicon */
+ *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunB0;
+ }
+ else
+ {
+ /* FeatureCtrl indicated that livelock dispatcher be used */
+ *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunB0LLP;
+ }
+ }
+}
+
+void
+ixQMgrDispatcherLoopRunA0 (IxQMgrDispatchGroup group)
+{
+ UINT32 intRegVal; /* Interrupt reg val */
+ UINT32 intRegValAfterWrite; /* Interrupt reg val after writing back */
+ UINT32 intRegCheckMask; /* Mask for checking interrupt bits */
+ UINT32 qStatusWordsB4Write[MAX_Q_STATUS_WORDS]; /* Status b4 interrupt write */
+ UINT32 qStatusWordsAfterWrite[MAX_Q_STATUS_WORDS]; /* Status after interrupt write */
+ IxQMgrQInfo *currDispatchQInfo;
+ BOOL statusChangeFlag;
+
+ int priorityTableIndex;/* Priority table index */
+ int qIndex; /* Current queue being processed */
+ int endIndex; /* Index of last queue to process */
+
+#ifndef NDEBUG
+ IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) ||
+ (group == IX_QMGR_QUELOW_GROUP));
+#endif
+
+ /* Read Q status registers before interrupt status read/write */
+ ixQMgrAqmIfQStatusRegsRead (group, qStatusWordsB4Write);
+
+ /* Read the interrupt register */
+ ixQMgrAqmIfQInterruptRegRead (group, &intRegVal);
+
+ /* No bit set : nothing to process (the reaminder of the algorithm is
+ * based on the fact that the interrupt register value contains at
+ * least one bit set
+ */
+ if (intRegVal == 0)
+ {
+#ifndef NDEBUG
+ /* Update statistics */
+ dispatcherStats.loopRunCnt++;
+#endif
+
+ /* Rebuild the priority table if needed */
+ if (rebuildTable)
+ {
+ ixQMgrDispatcherReBuildPriorityTable ();
+ }
+
+ return;
+ }
+
+ /* Write it back to clear the interrupt */
+ ixQMgrAqmIfQInterruptRegWrite (group, intRegVal);
+
+ /* Read Q status registers after interrupt status read/write */
+ ixQMgrAqmIfQStatusRegsRead (group, qStatusWordsAfterWrite);
+
+ /* get the first queue Id from the interrupt register value */
+ qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal);
+
+ /* check if any change occured during hw register modifications */
+ if (IX_QMGR_QUELOW_GROUP == group)
+ {
+ statusChangeFlag =
+ (qStatusWordsB4Write[0] != qStatusWordsAfterWrite[0]) ||
+ (qStatusWordsB4Write[1] != qStatusWordsAfterWrite[1]) ||
+ (qStatusWordsB4Write[2] != qStatusWordsAfterWrite[2]) ||
+ (qStatusWordsB4Write[3] != qStatusWordsAfterWrite[3]);
+ }
+ else
+ {
+ statusChangeFlag =
+ (qStatusWordsB4Write[0] != qStatusWordsAfterWrite[0]);
+ /* Set the queue range based on the queue group to proccess */
+ qIndex += IX_QMGR_MIN_QUEUPP_QID;
+ }
+
+ if (statusChangeFlag == FALSE)
+ {
+ /* check if the interrupt register contains
+ * only 1 bit set (happy day scenario)
+ */
+ currDispatchQInfo = &dispatchQInfo[qIndex];
+ if (intRegVal == currDispatchQInfo->intRegCheckMask)
+ {
+ /* only 1 queue event triggered a notification *
+ * Call the callback function for this queue
+ */
+ currDispatchQInfo->callback (qIndex,
+ currDispatchQInfo->callbackId);
+#ifndef NDEBUG
+ /* Update statistics */
+ dispatcherStats.queueStats[qIndex].callbackCnt++;
+#endif
+ }
+ else
+ {
+ /* the event is triggered by more than 1 queue,
+ * the queue search will be starting from the beginning
+ * or the middle of the priority table
+ *
+ * the serach will end when all the bits of the interrupt
+ * register are cleared. There is no need to maintain
+ * a seperate value and test it at each iteration.
+ */
+ if (IX_QMGR_QUELOW_GROUP == group)
+ {
+ /* check if any bit related to queues in the first
+ * half of the priority table is set
+ */
+ if (intRegVal & lowPriorityTableFirstHalfMask)
+ {
+ priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX;
+ }
+ else
+ {
+ priorityTableIndex = IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX;
+ }
+ }
+ else
+ {
+ /* check if any bit related to queues in the first
+ * half of the priority table is set
+ */
+ if (intRegVal & uppPriorityTableFirstHalfMask)
+ {
+ priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX;
+ }
+ else
+ {
+ priorityTableIndex = IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX;
+ }
+ }
+
+ /* iterate following the priority table until all the bits
+ * of the interrupt register are cleared.
+ */
+ do
+ {
+ qIndex = priorityTable[priorityTableIndex++];
+ currDispatchQInfo = &dispatchQInfo[qIndex];
+ intRegCheckMask = currDispatchQInfo->intRegCheckMask;
+
+ /* If this queue caused this interrupt to be raised */
+ if (intRegVal & intRegCheckMask)
+ {
+ /* Call the callback function for this queue */
+ currDispatchQInfo->callback (qIndex,
+ currDispatchQInfo->callbackId);
+#ifndef NDEBUG
+ /* Update statistics */
+ dispatcherStats.queueStats[qIndex].callbackCnt++;
+#endif
+
+ /* Clear the interrupt register bit */
+ intRegVal &= ~intRegCheckMask;
+ }
+ }
+ while(intRegVal);
+ }
+ }
+ else
+ {
+ /* A change in queue status occured during the hw interrupt
+ * register update. To maintain the interrupt consistency, it
+ * is necessary to iterate through all queues of the queue group.
+ */
+
+ /* Read interrupt status again */
+ ixQMgrAqmIfQInterruptRegRead (group, &intRegValAfterWrite);
+
+ if (IX_QMGR_QUELOW_GROUP == group)
+ {
+ priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX;
+ endIndex = IX_QMGR_MAX_LOW_QUE_PRIORITY_TABLE_INDEX;
+ }
+ else
+ {
+ priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX;
+ endIndex = IX_QMGR_MAX_UPP_QUE_PRIORITY_TABLE_INDEX;
+ }
+
+ for ( ; priorityTableIndex<=endIndex; priorityTableIndex++)
+ {
+ qIndex = priorityTable[priorityTableIndex];
+ currDispatchQInfo = &dispatchQInfo[qIndex];
+ intRegCheckMask = currDispatchQInfo->intRegCheckMask;
+
+ /* If this queue caused this interrupt to be raised */
+ if (intRegVal & intRegCheckMask)
+ {
+ /* Call the callback function for this queue */
+ currDispatchQInfo->callback (qIndex,
+ currDispatchQInfo->callbackId);
+#ifndef NDEBUG
+ /* Update statistics */
+ dispatcherStats.queueStats[qIndex].callbackCnt++;
+#endif
+
+ } /* if (intRegVal .. */
+
+ /*
+ * If interrupt bit is set in intRegValAfterWrite don't
+ * proceed as this will be caught in next interrupt
+ */
+ else if ((intRegValAfterWrite & intRegCheckMask) == 0)
+ {
+ /* Check if an interrupt was lost for this Q */
+ if (ixQMgrAqmIfQStatusCheck(qStatusWordsB4Write,
+ qStatusWordsAfterWrite,
+ currDispatchQInfo->statusWordOffset,
+ currDispatchQInfo->statusCheckValue,
+ currDispatchQInfo->statusMask))
+ {
+ /* Call the callback function for this queue */
+ currDispatchQInfo->callback (qIndex,
+ dispatchQInfo[qIndex].callbackId);
+#ifndef NDEBUG
+ /* Update statistics */
+ dispatcherStats.queueStats[qIndex].callbackCnt++;
+ dispatcherStats.queueStats[qIndex].intLostCallbackCnt++;
+#endif
+ } /* if ixQMgrAqmIfQStatusCheck(.. */
+ } /* else if ((intRegValAfterWrite ... */
+ } /* for (priorityTableIndex=0 ... */
+ }
+
+ /* Rebuild the priority table if needed */
+ if (rebuildTable)
+ {
+ ixQMgrDispatcherReBuildPriorityTable ();
+ }
+
+#ifndef NDEBUG
+ /* Update statistics */
+ dispatcherStats.loopRunCnt++;
+#endif
+}
+
+
+
+void
+ixQMgrDispatcherLoopRunB0 (IxQMgrDispatchGroup group)
+{
+ UINT32 intRegVal; /* Interrupt reg val */
+ UINT32 intRegCheckMask; /* Mask for checking interrupt bits */
+ IxQMgrQInfo *currDispatchQInfo;
+
+
+ int priorityTableIndex; /* Priority table index */
+ int qIndex; /* Current queue being processed */
+
+#ifndef NDEBUG
+ IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) ||
+ (group == IX_QMGR_QUELOW_GROUP));
+ IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) ||
+ (group == IX_QMGR_QUELOW_GROUP));
+#endif
+
+ /* Read the interrupt register */
+ ixQMgrAqmIfQInterruptRegRead (group, &intRegVal);
+
+
+ /* No queue has interrupt register set */
+ if (intRegVal != 0)
+ {
+
+ /* Write it back to clear the interrupt */
+ ixQMgrAqmIfQInterruptRegWrite (group, intRegVal);
+
+ /* get the first queue Id from the interrupt register value */
+ qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal);
+
+ if (IX_QMGR_QUEUPP_GROUP == group)
+ {
+ /* Set the queue range based on the queue group to proccess */
+ qIndex += IX_QMGR_MIN_QUEUPP_QID;
+ }
+
+ /* check if the interrupt register contains
+ * only 1 bit set
+ * For example:
+ * intRegVal = 0x0010
+ * currDispatchQInfo->intRegCheckMask = 0x0010
+ * intRegVal == currDispatchQInfo->intRegCheckMask is TRUE.
+ */
+ currDispatchQInfo = &dispatchQInfo[qIndex];
+ if (intRegVal == currDispatchQInfo->intRegCheckMask)
+ {
+ /* only 1 queue event triggered a notification *
+ * Call the callback function for this queue
+ */
+ currDispatchQInfo->callback (qIndex,
+ currDispatchQInfo->callbackId);
+#ifndef NDEBUG
+ /* Update statistics */
+ dispatcherStats.queueStats[qIndex].callbackCnt++;
+#endif
+ }
+ else
+ {
+ /* the event is triggered by more than 1 queue,
+ * the queue search will be starting from the beginning
+ * or the middle of the priority table
+ *
+ * the serach will end when all the bits of the interrupt
+ * register are cleared. There is no need to maintain
+ * a seperate value and test it at each iteration.
+ */
+ if (IX_QMGR_QUELOW_GROUP == group)
+ {
+ /* check if any bit related to queues in the first
+ * half of the priority table is set
+ */
+ if (intRegVal & lowPriorityTableFirstHalfMask)
+ {
+ priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX;
+ }
+ else
+ {
+ priorityTableIndex = IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX;
+ }
+ }
+ else
+ {
+ /* check if any bit related to queues in the first
+ * half of the priority table is set
+ */
+ if (intRegVal & uppPriorityTableFirstHalfMask)
+ {
+ priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX;
+ }
+ else
+ {
+ priorityTableIndex = IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX;
+ }
+ }
+
+ /* iterate following the priority table until all the bits
+ * of the interrupt register are cleared.
+ */
+ do
+ {
+ qIndex = priorityTable[priorityTableIndex++];
+ currDispatchQInfo = &dispatchQInfo[qIndex];
+ intRegCheckMask = currDispatchQInfo->intRegCheckMask;
+
+ /* If this queue caused this interrupt to be raised */
+ if (intRegVal & intRegCheckMask)
+ {
+ /* Call the callback function for this queue */
+ currDispatchQInfo->callback (qIndex,
+ currDispatchQInfo->callbackId);
+#ifndef NDEBUG
+ /* Update statistics */
+ dispatcherStats.queueStats[qIndex].callbackCnt++;
+#endif
+
+ /* Clear the interrupt register bit */
+ intRegVal &= ~intRegCheckMask;
+ }
+ }
+ while(intRegVal);
+ } /*End of intRegVal == currDispatchQInfo->intRegCheckMask */
+ } /* End of intRegVal != 0 */
+
+#ifndef NDEBUG
+ /* Update statistics */
+ dispatcherStats.loopRunCnt++;
+#endif
+
+ /* Rebuild the priority table if needed */
+ if (rebuildTable)
+ {
+ ixQMgrDispatcherReBuildPriorityTable ();
+ }
+}
+
+void
+ixQMgrDispatcherLoopRunB0LLP (IxQMgrDispatchGroup group)
+{
+ UINT32 intRegVal =0; /* Interrupt reg val */
+ UINT32 intRegCheckMask; /* Mask for checking interrupt bits */
+ IxQMgrQInfo *currDispatchQInfo;
+
+ int priorityTableIndex; /* Priority table index */
+ int qIndex; /* Current queue being processed */
+
+ UINT32 intRegValCopy = 0;
+ UINT32 intEnableRegVal = 0;
+ UINT8 i = 0;
+
+#ifndef NDEBUG
+ IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) ||
+ (group == IX_QMGR_QUELOW_GROUP));
+#endif
+
+ /* Read the interrupt register */
+ ixQMgrAqmIfQInterruptRegRead (group, &intRegVal);
+
+ /*
+ * mask any interrupts that are not enabled
+ */
+ ixQMgrAqmIfQInterruptEnableRegRead (group, &intEnableRegVal);
+ intRegVal &= intEnableRegVal;
+
+ /* No queue has interrupt register set */
+ if (intRegVal != 0)
+ {
+ if (IX_QMGR_QUELOW_GROUP == group)
+ {
+ /*
+ * As the sticky bit is set, the interrupt register will
+ * not clear if write back at this point because the condition
+ * has not been cleared. Take a copy and write back later after
+ * the condition has been cleared
+ */
+ intRegValCopy = intRegVal;
+ }
+ else
+ {
+ /* no sticky for upper Q's, so write back now */
+ ixQMgrAqmIfQInterruptRegWrite (group, intRegVal);
+ }
+
+ /* get the first queue Id from the interrupt register value */
+ qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal);
+
+ if (IX_QMGR_QUEUPP_GROUP == group)
+ {
+ /* Set the queue range based on the queue group to proccess */
+ qIndex += IX_QMGR_MIN_QUEUPP_QID;
+ }
+
+ /* check if the interrupt register contains
+ * only 1 bit set
+ * For example:
+ * intRegVal = 0x0010
+ * currDispatchQInfo->intRegCheckMask = 0x0010
+ * intRegVal == currDispatchQInfo->intRegCheckMask is TRUE.
+ */
+ currDispatchQInfo = &dispatchQInfo[qIndex];
+ if (intRegVal == currDispatchQInfo->intRegCheckMask)
+ {
+
+ /*
+ * check if Q type periodic - only lower queues can
+ * have there type set to periodic
+ */
+ if (IX_QMGR_TYPE_REALTIME_PERIODIC == ixQMgrQTypes[qIndex])
+ {
+ /*
+ * Disable the notifications on any sporadics
+ */
+ for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++)
+ {
+ if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrQTypes[i])
+ {
+ ixQMgrNotificationDisable(i);
+#ifndef NDEBUG
+ /* Update statistics */
+ dispatcherStats.queueStats[i].disableCount++;
+#endif
+ }
+ }
+ }
+
+ currDispatchQInfo->callback (qIndex,
+ currDispatchQInfo->callbackId);
+#ifndef NDEBUG
+ /* Update statistics */
+ dispatcherStats.queueStats[qIndex].callbackCnt++;
+#endif
+ }
+ else
+ {
+ /* the event is triggered by more than 1 queue,
+ * the queue search will be starting from the beginning
+ * or the middle of the priority table
+ *
+ * the serach will end when all the bits of the interrupt
+ * register are cleared. There is no need to maintain
+ * a seperate value and test it at each iteration.
+ */
+ if (IX_QMGR_QUELOW_GROUP == group)
+ {
+ /* check if any bit related to queues in the first
+ * half of the priority table is set
+ */
+ if (intRegVal & lowPriorityTableFirstHalfMask)
+ {
+ priorityTableIndex =
+ IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX;
+ }
+ else
+ {
+ priorityTableIndex =
+ IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX;
+ }
+ }
+ else
+ {
+ /* check if any bit related to queues in the first
+ * half of the priority table is set
+ */
+ if (intRegVal & uppPriorityTableFirstHalfMask)
+ {
+ priorityTableIndex =
+ IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX;
+ }
+ else
+ {
+ priorityTableIndex =
+ IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX;
+ }
+ }
+
+ /* iterate following the priority table until all the bits
+ * of the interrupt register are cleared.
+ */
+ do
+ {
+ qIndex = priorityTable[priorityTableIndex++];
+ currDispatchQInfo = &dispatchQInfo[qIndex];
+ intRegCheckMask = currDispatchQInfo->intRegCheckMask;
+
+ /* If this queue caused this interrupt to be raised */
+ if (intRegVal & intRegCheckMask)
+ {
+ /*
+ * check if Q type periodic - only lower queues can
+ * have there type set to periodic. There can only be one
+ * periodic queue, so the sporadics are only disabled once.
+ */
+ if (IX_QMGR_TYPE_REALTIME_PERIODIC == ixQMgrQTypes[qIndex])
+ {
+ /*
+ * Disable the notifications on any sporadics
+ */
+ for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++)
+ {
+ if (IX_QMGR_TYPE_REALTIME_SPORADIC ==
+ ixQMgrQTypes[i])
+ {
+ ixQMgrNotificationDisable(i);
+ /*
+ * remove from intRegVal as we don't want
+ * to service any sporadics now
+ */
+ intRegVal &= ~dispatchQInfo[i].intRegCheckMask;
+#ifndef NDEBUG
+ /* Update statistics */
+ dispatcherStats.queueStats[i].disableCount++;
+#endif
+ }
+ }
+ }
+
+ currDispatchQInfo->callback (qIndex,
+ currDispatchQInfo->callbackId);
+#ifndef NDEBUG
+ /* Update statistics */
+ dispatcherStats.queueStats[qIndex].callbackCnt++;
+#endif
+ /* Clear the interrupt register bit */
+ intRegVal &= ~intRegCheckMask;
+ }
+ }
+ while(intRegVal);
+ } /*End of intRegVal == currDispatchQInfo->intRegCheckMask */
+ } /* End of intRegVal != 0 */
+
+#ifndef NDEBUG
+ /* Update statistics */
+ dispatcherStats.loopRunCnt++;
+#endif
+
+ if ((intRegValCopy != 0) && (IX_QMGR_QUELOW_GROUP == group))
+ {
+ /*
+ * lower groups (therefore sticky) AND at least one enabled interrupt
+ * Write back to clear the interrupt
+ */
+ ixQMgrAqmIfQInterruptRegWrite (IX_QMGR_QUELOW_GROUP, intRegValCopy);
+ }
+
+ /* Rebuild the priority table if needed */
+ if (rebuildTable)
+ {
+ ixQMgrDispatcherReBuildPriorityTable ();
+ }
+}
+
+PRIVATE void
+ixQMgrDispatcherReBuildPriorityTable (void)
+{
+ UINT32 qIndex;
+ UINT32 priority;
+ int lowQuePriorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX;
+ int uppQuePriorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX;
+
+ /* Reset the rebuild flag */
+ rebuildTable = FALSE;
+
+ /* initialize the mak used to identify the queues in the first half
+ * of the priority table
+ */
+ lowPriorityTableFirstHalfMask = 0;
+ uppPriorityTableFirstHalfMask = 0;
+
+ /* For each priority level */
+ for(priority=0; priority<IX_QMGR_NUM_PRIORITY_LEVELS; priority++)
+ {
+ /* Foreach low queue in this priority */
+ for(qIndex=0; qIndex<IX_QMGR_MIN_QUEUPP_QID; qIndex++)
+ {
+ if (dispatchQInfo[qIndex].priority == priority)
+ {
+ /* build the priority table bitmask which match the
+ * queues of the first half of the priority table
+ */
+ if (lowQuePriorityTableIndex < IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX)
+ {
+ lowPriorityTableFirstHalfMask |= dispatchQInfo[qIndex].intRegCheckMask;
+ }
+ /* build the priority table */
+ priorityTable[lowQuePriorityTableIndex++] = qIndex;
+ }
+ }
+ /* Foreach upp queue */
+ for(qIndex=IX_QMGR_MIN_QUEUPP_QID; qIndex<=IX_QMGR_MAX_QID; qIndex++)
+ {
+ if (dispatchQInfo[qIndex].priority == priority)
+ {
+ /* build the priority table bitmask which match the
+ * queues of the first half of the priority table
+ */
+ if (uppQuePriorityTableIndex < IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX)
+ {
+ uppPriorityTableFirstHalfMask |= dispatchQInfo[qIndex].intRegCheckMask;
+ }
+ /* build the priority table */
+ priorityTable[uppQuePriorityTableIndex++] = qIndex;
+ }
+ }
+ }
+}
+
+IxQMgrDispatcherStats*
+ixQMgrDispatcherStatsGet (void)
+{
+ return &dispatcherStats;
+}
+
+PRIVATE void
+dummyCallback (IxQMgrQId qId,
+ IxQMgrCallbackId cbId)
+{
+ /* Throttle the trace message */
+ if ((dispatchQInfo[qId].dummyCallbackCount % LOG_THROTTLE_COUNT) == 0)
+ {
+ IX_QMGR_LOG_WARNING2("--> dummyCallback: qId (%d), callbackId (%d)\n",qId,cbId);
+ }
+ dispatchQInfo[qId].dummyCallbackCount++;
+
+#ifndef NDEBUG
+ /* Update statistcs */
+ dispatcherStats.queueStats[qId].intNoCallbackCnt++;
+#endif
+}
+void
+ixQMgrLLPShow (int resetStats)
+{
+#ifndef NDEBUG
+ UINT8 i = 0;
+ IxQMgrQInfo *q;
+ UINT32 intEnableRegVal = 0;
+
+ printf ("Livelock statistics are printed on the fly.\n");
+ printf ("qId Type EnableCnt DisableCnt IntEnableState Callbacks\n");
+ printf ("=== ======== ========= ========== ============== =========\n");
+
+ for (i=0; i<= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++)
+ {
+ q = &dispatchQInfo[i];
+
+ if (ixQMgrQTypes[i] != IX_QMGR_TYPE_REALTIME_OTHER)
+ {
+ printf (" %2d ", i);
+
+ if (ixQMgrQTypes[i] == IX_QMGR_TYPE_REALTIME_SPORADIC)
+ {
+ printf ("Sporadic");
+ }
+ else
+ {
+ printf ("Periodic");
+ }
+
+
+ ixQMgrAqmIfQInterruptEnableRegRead (IX_QMGR_QUELOW_GROUP,
+ &intEnableRegVal);
+
+
+ intEnableRegVal &= dispatchQInfo[i].intRegCheckMask;
+ intEnableRegVal = intEnableRegVal >> i;
+
+ printf (" %10d %10d %10d %10d\n",
+ dispatcherStats.queueStats[i].enableCount,
+ dispatcherStats.queueStats[i].disableCount,
+ intEnableRegVal,
+ dispatcherStats.queueStats[i].callbackCnt);
+
+ if (resetStats)
+ {
+ dispatcherStats.queueStats[i].enableCount =
+ dispatcherStats.queueStats[i].disableCount =
+ dispatcherStats.queueStats[i].callbackCnt = 0;
+ }
+ }
+ }
+#else
+ IX_QMGR_LOG0("Livelock Prevention statistics are only collected in debug mode\n");
+#endif
+}
+
+void
+ixQMgrPeriodicDone (void)
+{
+ UINT32 i = 0;
+ UINT32 ixQMgrLockKey = 0;
+
+ /*
+ * for the lower queues
+ */
+ for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++)
+ {
+ /*
+ * check for sporadics
+ */
+ if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrQTypes[i])
+ {
+ /*
+ * enable any sporadics
+ */
+ ixQMgrLockKey = ixOsalIrqLock();
+ ixQMgrAqmIfQInterruptEnable(i);
+ ixOsalIrqUnlock(ixQMgrLockKey);
+#ifndef NDEBUG
+ /*
+ * Update statistics
+ */
+ dispatcherStats.queueStats[i].enableCount++;
+ dispatcherStats.queueStats[i].notificationEnabled = TRUE;
+#endif
+ }
+ }
+}
+IX_STATUS
+ixQMgrCallbackTypeSet (IxQMgrQId qId,
+ IxQMgrType type)
+{
+ UINT32 ixQMgrLockKey = 0;
+ IxQMgrType ixQMgrOldType =0;
+
+#ifndef NDEBUG
+ if (!ixQMgrQIsConfigured(qId))
+ {
+ return IX_QMGR_Q_NOT_CONFIGURED;
+ }
+ if (qId >= IX_QMGR_MIN_QUEUPP_QID)
+ {
+ return IX_QMGR_PARAMETER_ERROR;
+ }
+ if(!IX_QMGR_DISPATCHER_CALLBACK_TYPE_CHECK(type))
+ {
+ return IX_QMGR_PARAMETER_ERROR;
+ }
+#endif
+
+ ixQMgrOldType = ixQMgrQTypes[qId];
+ ixQMgrQTypes[qId] = type;
+
+ /*
+ * check if Q has been changed from type SPORADIC
+ */
+ if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrOldType)
+ {
+ /*
+ * previously Q was a SPORADIC, this means that LLP
+ * might have had it disabled. enable it now.
+ */
+ ixQMgrLockKey = ixOsalIrqLock();
+ ixQMgrAqmIfQInterruptEnable(qId);
+ ixOsalIrqUnlock(ixQMgrLockKey);
+
+#ifndef NDEBUG
+ /*
+ * Update statistics
+ */
+ dispatcherStats.queueStats[qId].enableCount++;
+#endif
+ }
+
+ return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrCallbackTypeGet (IxQMgrQId qId,
+ IxQMgrType *type)
+{
+#ifndef NDEBUG
+ if (!ixQMgrQIsConfigured(qId))
+ {
+ return IX_QMGR_Q_NOT_CONFIGURED;
+ }
+ if (qId >= IX_QMGR_MIN_QUEUPP_QID)
+ {
+ return IX_QMGR_PARAMETER_ERROR;
+ }
+ if(type == NULL)
+ {
+ return IX_QMGR_PARAMETER_ERROR;
+ }
+#endif
+
+ *type = ixQMgrQTypes[qId];
+ return IX_SUCCESS;
+}
diff --git a/cpu/ixp/npe/IxQMgrInit.c b/cpu/ixp/npe/IxQMgrInit.c
new file mode 100644
index 0000000..b00c22d
--- /dev/null
+++ b/cpu/ixp/npe/IxQMgrInit.c
@@ -0,0 +1,233 @@
+/**
+ * @file IxQMgrInit.c
+ *
+ * @author Intel Corporation
+ * @date 30-Oct-2001
+ *
+ * @brief: Provided initialization of the QMgr component and its subcomponents.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * System defined include files.
+ */
+
+/*
+ * User defined include files.
+ */
+#include "IxOsal.h"
+#include "IxQMgr.h"
+#include "IxQMgrQCfg_p.h"
+#include "IxQMgrDispatcher_p.h"
+#include "IxQMgrLog_p.h"
+#include "IxQMgrQAccess_p.h"
+#include "IxQMgrDefines_p.h"
+#include "IxQMgrAqmIf_p.h"
+
+/*
+ * Set to true if initialized
+ * N.B. global so integration/unit tests can reinitialize
+ */
+BOOL qMgrIsInitialized = FALSE;
+
+/*
+ * Function definitions.
+ */
+IX_STATUS
+ixQMgrInit (void)
+{
+ if (qMgrIsInitialized)
+ {
+ IX_QMGR_LOG0("ixQMgrInit: IxQMgr already initialised\n");
+ return IX_FAIL;
+ }
+
+ /* Initialise the QCfg component */
+ ixQMgrQCfgInit ();
+
+ /* Initialise the Dispatcher component */
+ ixQMgrDispatcherInit ();
+
+ /* Initialise the Access component */
+ ixQMgrQAccessInit ();
+
+ /* Initialization complete */
+ qMgrIsInitialized = TRUE;
+
+ return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrUnload (void)
+{
+ if (!qMgrIsInitialized)
+ {
+ return IX_FAIL;
+ }
+
+ /* Uninitialise the QCfg component */
+ ixQMgrQCfgUninit ();
+
+ /* Uninitialization complete */
+ qMgrIsInitialized = FALSE;
+
+ return IX_SUCCESS;
+}
+
+void
+ixQMgrShow (void)
+{
+ IxQMgrQCfgStats *qCfgStats = NULL;
+ IxQMgrDispatcherStats *dispatcherStats = NULL;
+ int i;
+ UINT32 lowIntRegRead, upIntRegRead;
+
+ qCfgStats = ixQMgrQCfgStatsGet ();
+ dispatcherStats = ixQMgrDispatcherStatsGet ();
+ ixQMgrAqmIfQInterruptRegRead (IX_QMGR_QUELOW_GROUP, &lowIntRegRead);
+ ixQMgrAqmIfQInterruptRegRead (IX_QMGR_QUEUPP_GROUP, &upIntRegRead);
+ printf("Generic Stats........\n");
+ printf("=====================\n");
+ printf("Loop Run Count..........%u\n",dispatcherStats->loopRunCnt);
+ printf("Watermark set count.....%d\n", qCfgStats->wmSetCnt);
+ printf("===========================================\n");
+ printf("On the fly Interrupt Register Stats........\n");
+ printf("===========================================\n");
+ printf("Lower Interrupt Register............0x%08x\n",lowIntRegRead);
+ printf("Upper Interrupt Register............0x%08x\n",upIntRegRead);
+ printf("==============================================\n");
+ printf("Queue Specific Stats........\n");
+ printf("============================\n");
+
+ for (i=0; i<IX_QMGR_MAX_NUM_QUEUES; i++)
+ {
+ if (ixQMgrQIsConfigured(i))
+ {
+ ixQMgrQShow(i);
+ }
+ }
+
+ printf("============================\n");
+}
+
+IX_STATUS
+ixQMgrQShow (IxQMgrQId qId)
+{
+ IxQMgrQCfgStats *qCfgStats = NULL;
+ IxQMgrDispatcherStats *dispatcherStats = NULL;
+
+ if (!ixQMgrQIsConfigured(qId))
+ {
+ return IX_QMGR_Q_NOT_CONFIGURED;
+ }
+
+ dispatcherStats = ixQMgrDispatcherStatsGet ();
+ qCfgStats = ixQMgrQCfgQStatsGet (qId);
+
+ printf("QId %d\n", qId);
+ printf("======\n");
+ printf(" IxQMgrQCfg Stats\n");
+ printf(" Name..................... \"%s\"\n", qCfgStats->qStats[qId].qName);
+ printf(" Size in words............ %u\n", qCfgStats->qStats[qId].qSizeInWords);
+ printf(" Entry size in words...... %u\n", qCfgStats->qStats[qId].qEntrySizeInWords);
+ printf(" Nearly empty watermark... %u\n", qCfgStats->qStats[qId].ne);
+ printf(" Nearly full watermark.... %u\n", qCfgStats->qStats[qId].nf);
+ printf(" Number of full entries... %u\n", qCfgStats->qStats[qId].numEntries);
+ printf(" Sram base address........ 0x%X\n", qCfgStats->qStats[qId].baseAddress);
+ printf(" Read pointer............. 0x%X\n", qCfgStats->qStats[qId].readPtr);
+ printf(" Write pointer............ 0x%X\n", qCfgStats->qStats[qId].writePtr);
+
+#ifndef NDEBUG
+ if (dispatcherStats->queueStats[qId].notificationEnabled)
+ {
+ char *localEvent = "none ????";
+ switch (dispatcherStats->queueStats[qId].srcSel)
+ {
+ case IX_QMGR_Q_SOURCE_ID_E:
+ localEvent = "Empty";
+ break;
+ case IX_QMGR_Q_SOURCE_ID_NE:
+ localEvent = "Nearly Empty";
+ break;
+ case IX_QMGR_Q_SOURCE_ID_NF:
+ localEvent = "Nearly Full";
+ break;
+ case IX_QMGR_Q_SOURCE_ID_F:
+ localEvent = "Full";
+ break;
+ case IX_QMGR_Q_SOURCE_ID_NOT_E:
+ localEvent = "Not Empty";
+ break;
+ case IX_QMGR_Q_SOURCE_ID_NOT_NE:
+ localEvent = "Not Nearly Empty";
+ break;
+ case IX_QMGR_Q_SOURCE_ID_NOT_NF:
+ localEvent = "Not Nearly Full";
+ break;
+ case IX_QMGR_Q_SOURCE_ID_NOT_F:
+ localEvent = "Not Full";
+ break;
+ default :
+ break;
+ }
+ printf(" Notifications localEvent...... %s\n", localEvent);
+ }
+ else
+ {
+ printf(" Notifications............ not enabled\n");
+ }
+ printf(" IxQMgrDispatcher Stats\n");
+ printf(" Callback count................%d\n",
+ dispatcherStats->queueStats[qId].callbackCnt);
+ printf(" Priority change count.........%d\n",
+ dispatcherStats->queueStats[qId].priorityChangeCnt);
+ printf(" Interrupt no callback count...%d\n",
+ dispatcherStats->queueStats[qId].intNoCallbackCnt);
+ printf(" Interrupt lost callback count...%d\n",
+ dispatcherStats->queueStats[qId].intLostCallbackCnt);
+#endif
+
+ return IX_SUCCESS;
+}
+
+
+
+
diff --git a/cpu/ixp/npe/IxQMgrQAccess.c b/cpu/ixp/npe/IxQMgrQAccess.c
new file mode 100644
index 0000000..2c3e302
--- /dev/null
+++ b/cpu/ixp/npe/IxQMgrQAccess.c
@@ -0,0 +1,796 @@
+/**
+ * @file IxQMgrQAccess.c
+ *
+ * @author Intel Corporation
+ * @date 30-Oct-2001
+ *
+ * @brief This file contains functions for putting entries on a queue and
+ * removing entries from a queue.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * Inlines are compiled as function when this is defined.
+ * N.B. Must be placed before #include of "IxQMgr.h"
+ */
+#ifndef IXQMGR_H
+# define IXQMGRQACCESS_C
+#else
+# error
+#endif
+
+/*
+ * System defined include files.
+ */
+
+/*
+ * User defined include files.
+ */
+#include "IxQMgr.h"
+#include "IxQMgrAqmIf_p.h"
+#include "IxQMgrQAccess_p.h"
+#include "IxQMgrQCfg_p.h"
+#include "IxQMgrDefines_p.h"
+
+/*
+ * Global variables and extern definitions
+ */
+extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
+
+/*
+ * Function definitions.
+ */
+void
+ixQMgrQAccessInit (void)
+{
+}
+
+IX_STATUS
+ixQMgrQReadWithChecks (IxQMgrQId qId,
+ UINT32 *entry)
+{
+ IxQMgrQEntrySizeInWords entrySizeInWords;
+ IxQMgrQInlinedReadWriteInfo *infoPtr;
+
+ if (NULL == entry)
+ {
+ return IX_QMGR_PARAMETER_ERROR;
+ }
+
+ /* Check QId */
+ if (!ixQMgrQIsConfigured(qId))
+ {
+ return IX_QMGR_Q_NOT_CONFIGURED;
+ }
+
+ /* Get the q entry size in words */
+ entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId);
+
+ ixQMgrAqmIfQPop (qId, entrySizeInWords, entry);
+
+ /* reset the current read count if the counter wrapped around
+ * (unsigned arithmetic)
+ */
+ infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+ if (infoPtr->qReadCount-- > infoPtr->qSizeInEntries)
+ {
+ infoPtr->qReadCount = 0;
+ }
+
+ /* Check if underflow occurred on the read */
+ if (ixQMgrAqmIfUnderflowCheck (qId))
+ {
+ return IX_QMGR_Q_UNDERFLOW;
+ }
+
+ return IX_SUCCESS;
+}
+
+/* this function reads the remaining of the q entry
+ * for queues configured with many words.
+ * (the first word of the entry is already read
+ * in the inlined function and the entry pointer already
+ * incremented
+ */
+IX_STATUS
+ixQMgrQReadMWordsMinus1 (IxQMgrQId qId,
+ UINT32 *entry)
+{
+ IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+ UINT32 entrySize = infoPtr->qEntrySizeInWords;
+ volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
+
+ while (--entrySize)
+ {
+ /* read the entry and accumulate the result */
+ *(++entry) = IX_OSAL_READ_LONG(++qAccRegAddr);
+ }
+ /* underflow is available for lower queues only */
+ if (qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ /* get the queue status */
+ UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
+
+ /* check the underflow status */
+ if (status & infoPtr->qUflowStatBitMask)
+ {
+ /* the queue is empty
+ * clear the underflow status bit if it was set
+ */
+ IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
+ status & ~infoPtr->qUflowStatBitMask);
+ return IX_QMGR_Q_UNDERFLOW;
+ }
+ }
+ return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrQWriteWithChecks (IxQMgrQId qId,
+ UINT32 *entry)
+{
+ IxQMgrQEntrySizeInWords entrySizeInWords;
+ IxQMgrQInlinedReadWriteInfo *infoPtr;
+
+ if (NULL == entry)
+ {
+ return IX_QMGR_PARAMETER_ERROR;
+ }
+
+ /* Check QId */
+ if (!ixQMgrQIsConfigured(qId))
+ {
+ return IX_QMGR_Q_NOT_CONFIGURED;
+ }
+
+ /* Get the q entry size in words */
+ entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId);
+
+ ixQMgrAqmIfQPush (qId, entrySizeInWords, entry);
+
+ /* reset the current read count if the counter wrapped around
+ * (unsigned arithmetic)
+ */
+ infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+ if (infoPtr->qWriteCount++ >= infoPtr->qSizeInEntries)
+ {
+ infoPtr->qWriteCount = infoPtr->qSizeInEntries;
+ }
+
+ /* Check if overflow occurred on the write*/
+ if (ixQMgrAqmIfOverflowCheck (qId))
+ {
+ return IX_QMGR_Q_OVERFLOW;
+ }
+
+ return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrQPeek (IxQMgrQId qId,
+ unsigned int entryIndex,
+ UINT32 *entry)
+{
+ unsigned int numEntries;
+
+#ifndef NDEBUG
+ if ((NULL == entry) || (entryIndex >= IX_QMGR_Q_SIZE_INVALID))
+ {
+ return IX_QMGR_PARAMETER_ERROR;
+ }
+
+ if (!ixQMgrQIsConfigured(qId))
+ {
+ return IX_QMGR_Q_NOT_CONFIGURED;
+ }
+#endif
+
+ if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries))
+ {
+ return IX_FAIL;
+ }
+
+ if (entryIndex >= numEntries) /* entryIndex starts at 0 */
+ {
+ return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS;
+ }
+
+ return ixQMgrAqmIfQPeek (qId, entryIndex, entry);
+}
+
+IX_STATUS
+ixQMgrQPoke (IxQMgrQId qId,
+ unsigned entryIndex,
+ UINT32 *entry)
+{
+ unsigned int numEntries;
+
+#ifndef NDEBUG
+ if ((NULL == entry) || (entryIndex > 128))
+ {
+ return IX_QMGR_PARAMETER_ERROR;
+ }
+
+ if (!ixQMgrQIsConfigured(qId))
+ {
+ return IX_QMGR_Q_NOT_CONFIGURED;
+ }
+#endif
+
+ if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries))
+ {
+ return IX_FAIL;
+ }
+
+ if (numEntries < (entryIndex + 1)) /* entryIndex starts at 0 */
+ {
+ return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS;
+ }
+
+ return ixQMgrAqmIfQPoke (qId, entryIndex, entry);
+}
+
+IX_STATUS
+ixQMgrQStatusGetWithChecks (IxQMgrQId qId,
+ IxQMgrQStatus *qStatus)
+{
+ if (NULL == qStatus)
+ {
+ return IX_QMGR_PARAMETER_ERROR;
+ }
+
+ if (!ixQMgrQIsConfigured (qId))
+ {
+ return IX_QMGR_Q_NOT_CONFIGURED;
+ }
+
+ ixQMgrAqmIfQueStatRead (qId, qStatus);
+
+ return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrQNumEntriesGet (IxQMgrQId qId,
+ unsigned *numEntriesPtr)
+{
+ UINT32 qPtrs;
+ UINT32 qStatus;
+ unsigned numEntries;
+ IxQMgrQInlinedReadWriteInfo *infoPtr;
+
+
+#ifndef NDEBUG
+ if (NULL == numEntriesPtr)
+ {
+ return IX_QMGR_PARAMETER_ERROR;
+ }
+
+ /* Check QId */
+ if (!ixQMgrQIsConfigured(qId))
+ {
+ return IX_QMGR_Q_NOT_CONFIGURED;
+ }
+#endif
+
+ /* get fast access data */
+ infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+
+ /* get snapshot */
+ qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
+
+ /* Mod subtraction of pointers to get number of words in Q. */
+ numEntries = (qPtrs - (qPtrs >> 7)) & 0x7f;
+
+ if (numEntries == 0)
+ {
+ /*
+ * Could mean either full or empty queue
+ * so look at status
+ */
+ ixQMgrAqmIfQueStatRead (qId, &qStatus);
+
+ if (qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ if (qStatus & IX_QMGR_Q_STATUS_E_BIT_MASK)
+ {
+ /* Empty */
+ *numEntriesPtr = 0;
+ }
+ else if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK)
+ {
+ /* Full */
+ *numEntriesPtr = infoPtr->qSizeInEntries;
+ }
+ else
+ {
+ /*
+ * Queue status and read/write pointers are volatile.
+ * The queue state has changed since we took the
+ * snapshot of the read and write pointers.
+ * Client can retry if they wish
+ */
+ *numEntriesPtr = 0;
+ return IX_QMGR_WARNING;
+ }
+ }
+ else /* It is an upper queue which does not have an empty status bit maintained */
+ {
+ if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK)
+ {
+ /* The queue is Full at the time of snapshot. */
+ *numEntriesPtr = infoPtr->qSizeInEntries;
+ }
+ else
+ {
+ /* The queue is either empty, either moving,
+ * Client can retry if they wish
+ */
+ *numEntriesPtr = 0;
+ return IX_QMGR_WARNING;
+ }
+ }
+ }
+ else
+ {
+ *numEntriesPtr = (numEntries / infoPtr->qEntrySizeInWords) & (infoPtr->qSizeInEntries - 1);
+ }
+
+ return IX_SUCCESS;
+}
+
+#if defined(__wince) && defined(NO_INLINE_APIS)
+
+PUBLIC IX_STATUS
+ixQMgrQRead (IxQMgrQId qId,
+ UINT32 *entryPtr)
+{
+ extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
+ IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+ UINT32 entry, entrySize;
+
+ /* get a new entry */
+ entrySize = infoPtr->qEntrySizeInWords;
+ entry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr);
+
+ if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
+ {
+ *entryPtr = entry;
+ /* process the remaining part of the entry */
+ return ixQMgrQReadMWordsMinus1(qId, entryPtr);
+ }
+
+ /* underflow is available for lower queues only */
+ if (qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ /* the counter of queue entries is decremented. In happy
+ * day scenario there are many entries in the queue
+ * and the counter does not reach zero.
+ */
+ if (infoPtr->qReadCount-- == 0)
+ {
+ /* There is maybe no entry in the queue
+ * qReadCount is now negative, but will be corrected before
+ * the function returns.
+ */
+ UINT32 qPtrs; /* queue internal pointers */
+
+ /* when a queue is empty, the hw guarantees to return
+ * a null value. If the value is not null, the queue is
+ * not empty.
+ */
+ if (entry == 0)
+ {
+ /* get the queue status */
+ UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
+
+ /* check the underflow status */
+ if (status & infoPtr->qUflowStatBitMask)
+ {
+ /* the queue is empty
+ * clear the underflow status bit if it was set
+ */
+ IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
+ status & ~infoPtr->qUflowStatBitMask);
+ *entryPtr = 0;
+ infoPtr->qReadCount = 0;
+ return IX_QMGR_Q_UNDERFLOW;
+ }
+ }
+ /* store the result */
+ *entryPtr = entry;
+
+ /* No underflow occured : someone is filling the queue
+ * or the queue contains null entries.
+ * The current counter needs to be
+ * updated from the current number of entries in the queue
+ */
+
+ /* get snapshot of queue pointers */
+ qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
+
+ /* Mod subtraction of pointers to get number of words in Q. */
+ qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f;
+
+ if (qPtrs == 0)
+ {
+ /* no entry in the queue */
+ infoPtr->qReadCount = 0;
+ }
+ else
+ {
+ /* convert the number of words inside the queue
+ * to a number of entries
+ */
+ infoPtr->qReadCount = qPtrs & (infoPtr->qSizeInEntries - 1);
+ }
+ return IX_SUCCESS;
+ }
+ }
+ *entryPtr = entry;
+ return IX_SUCCESS;
+}
+
+PUBLIC IX_STATUS
+ixQMgrQBurstRead (IxQMgrQId qId,
+ UINT32 numEntries,
+ UINT32 *entries)
+{
+ extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
+ IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+ UINT32 nullCheckEntry;
+
+ if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
+ {
+ volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
+
+ /* the code is optimized to take care of data dependencies:
+ * Durig a read, there are a few cycles needed to get the
+ * read complete. During these cycles, it is poossible to
+ * do some CPU, e.g. increment pointers and decrement
+ * counters.
+ */
+
+ /* fetch a queue entry */
+ nullCheckEntry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr);
+
+ /* iterate the specified number of queue entries */
+ while (--numEntries)
+ {
+ /* check the result of the previous read */
+ if (nullCheckEntry == 0)
+ {
+ /* if we read a NULL entry, stop. We have underflowed */
+ break;
+ }
+ else
+ {
+ /* write the entry */
+ *entries = nullCheckEntry;
+ /* fetch next entry */
+ nullCheckEntry = IX_OSAL_READ_LONG(qAccRegAddr);
+ /* increment the write address */
+ entries++;
+ }
+ }
+ /* write the pre-fetched entry */
+ *entries = nullCheckEntry;
+ }
+ else
+ {
+ IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
+ /* read the specified number of queue entries */
+ nullCheckEntry = 0;
+ while (numEntries--)
+ {
+ int i;
+
+ for (i = 0; i < entrySizeInWords; i++)
+ {
+ *entries = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr + i);
+ nullCheckEntry |= *entries++;
+ }
+
+ /* if we read a NULL entry, stop. We have underflowed */
+ if (nullCheckEntry == 0)
+ {
+ break;
+ }
+ nullCheckEntry = 0;
+ }
+ }
+
+ /* reset the current read count : next access to the read function
+ * will force a underflow status check
+ */
+ infoPtr->qWriteCount = 0;
+
+ /* Check if underflow occurred on the read */
+ if (nullCheckEntry == 0 && qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ /* get the queue status */
+ UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
+
+ if (status & infoPtr->qUflowStatBitMask)
+ {
+ /* clear the underflow status bit if it was set */
+ IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
+ status & ~infoPtr->qUflowStatBitMask);
+ return IX_QMGR_Q_UNDERFLOW;
+ }
+ }
+
+ return IX_SUCCESS;
+}
+
+PUBLIC IX_STATUS
+ixQMgrQWrite (IxQMgrQId qId,
+ UINT32 *entry)
+{
+ extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
+ IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+ UINT32 entrySize;
+
+ /* write the entry */
+ IX_OSAL_WRITE_LONG(infoPtr->qAccRegAddr, *entry);
+ entrySize = infoPtr->qEntrySizeInWords;
+
+ if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
+ {
+ /* process the remaining part of the entry */
+ volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
+ while (--entrySize)
+ {
+ ++entry;
+ IX_OSAL_WRITE_LONG(++qAccRegAddr, *entry);
+ }
+ entrySize = infoPtr->qEntrySizeInWords;
+ }
+
+ /* overflow is available for lower queues only */
+ if (qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ UINT32 qSize = infoPtr->qSizeInEntries;
+ /* increment the current number of entries in the queue
+ * and check for overflow
+ */
+ if (infoPtr->qWriteCount++ == qSize)
+ {
+ /* the queue may have overflow */
+ UINT32 qPtrs; /* queue internal pointers */
+
+ /* get the queue status */
+ UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
+
+ /* read the status twice because the status may
+ * not be immediately ready after the write operation
+ */
+ if ((status & infoPtr->qOflowStatBitMask) ||
+ ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr))
+ & infoPtr->qOflowStatBitMask))
+ {
+ /* the queue is full, clear the overflow status
+ * bit if it was set
+ */
+ IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
+ status & ~infoPtr->qOflowStatBitMask);
+ infoPtr->qWriteCount = infoPtr->qSizeInEntries;
+ return IX_QMGR_Q_OVERFLOW;
+ }
+ /* No overflow occured : someone is draining the queue
+ * and the current counter needs to be
+ * updated from the current number of entries in the queue
+ */
+
+ /* get q pointer snapshot */
+ qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
+
+ /* Mod subtraction of pointers to get number of words in Q. */
+ qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f;
+
+ if (qPtrs == 0)
+ {
+ /* the queue may be full at the time of the
+ * snapshot. Next access will check
+ * the overflow status again.
+ */
+ infoPtr->qWriteCount = qSize;
+ }
+ else
+ {
+ /* convert the number of words to a number of entries */
+ if (entrySize == IX_QMGR_Q_ENTRY_SIZE1)
+ {
+ infoPtr->qWriteCount = qPtrs & (qSize - 1);
+ }
+ else
+ {
+ infoPtr->qWriteCount = (qPtrs / entrySize) & (qSize - 1);
+ }
+ }
+ }
+ }
+ return IX_SUCCESS;
+}
+
+PUBLIC IX_STATUS
+ixQMgrQBurstWrite (IxQMgrQId qId,
+ unsigned numEntries,
+ UINT32 *entries)
+{
+ extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
+ IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+ UINT32 status;
+
+ /* update the current write count */
+ infoPtr->qWriteCount += numEntries;
+
+ if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
+ {
+ volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
+ while (numEntries--)
+ {
+ IX_OSAL_WRITE_LONG(qAccRegAddr, *entries);
+ entries++;
+ }
+ }
+ else
+ {
+ IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
+ int i;
+
+ /* write each queue entry */
+ while (numEntries--)
+ {
+ /* write the queueEntrySize number of words for each entry */
+ for (i = 0; i < entrySizeInWords; i++)
+ {
+ IX_OSAL_WRITE_LONG((infoPtr->qAccRegAddr + i), *entries);
+ entries++;
+ }
+ }
+ }
+
+ /* check if the write count overflows */
+ if (infoPtr->qWriteCount > infoPtr->qSizeInEntries)
+ {
+ /* reset the current write count */
+ infoPtr->qWriteCount = infoPtr->qSizeInEntries;
+ }
+
+ /* Check if overflow occurred on the write operation */
+ if (qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ /* get the queue status */
+ status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
+
+ /* read the status twice because the status may
+ * not be ready at the time of the write
+ */
+ if ((status & infoPtr->qOflowStatBitMask) ||
+ ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr))
+ & infoPtr->qOflowStatBitMask))
+ {
+ /* clear the underflow status bit if it was set */
+ IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
+ status & ~infoPtr->qOflowStatBitMask);
+ return IX_QMGR_Q_OVERFLOW;
+ }
+ }
+
+ return IX_SUCCESS;
+}
+
+PUBLIC IX_STATUS
+ixQMgrQStatusGet (IxQMgrQId qId,
+ IxQMgrQStatus *qStatus)
+{
+ /* read the status of a queue in the range 0-31 */
+ if (qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ extern UINT32 ixQMgrAqmIfQueLowStatRegAddr[];
+ extern UINT32 ixQMgrAqmIfQueLowStatBitsOffset[];
+ extern UINT32 ixQMgrAqmIfQueLowStatBitsMask;
+ extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
+ IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+ volatile UINT32 *lowStatRegAddr = (UINT32*)ixQMgrAqmIfQueLowStatRegAddr[qId];
+ volatile UINT32 *qUOStatRegAddr = infoPtr->qUOStatRegAddr;
+
+ UINT32 lowStatBitsOffset = ixQMgrAqmIfQueLowStatBitsOffset[qId];
+ UINT32 lowStatBitsMask = ixQMgrAqmIfQueLowStatBitsMask;
+ UINT32 underflowBitMask = infoPtr->qUflowStatBitMask;
+ UINT32 overflowBitMask = infoPtr->qOflowStatBitMask;
+
+ /* read the status register for this queue */
+ *qStatus = IX_OSAL_READ_LONG(lowStatRegAddr);
+ /* mask out the status bits relevant only to this queue */
+ *qStatus = (*qStatus >> lowStatBitsOffset) & lowStatBitsMask;
+
+ /* Check if the queue has overflowed */
+ if (IX_OSAL_READ_LONG(qUOStatRegAddr) & overflowBitMask)
+ {
+ /* clear the overflow status bit if it was set */
+ IX_OSAL_WRITE_LONG(qUOStatRegAddr,
+ (IX_OSAL_READ_LONG(qUOStatRegAddr) &
+ ~overflowBitMask));
+ *qStatus |= IX_QMGR_Q_STATUS_OF_BIT_MASK;
+ }
+
+ /* Check if the queue has underflowed */
+ if (IX_OSAL_READ_LONG(qUOStatRegAddr) & underflowBitMask)
+ {
+ /* clear the underflow status bit if it was set */
+ IX_OSAL_WRITE_LONG(qUOStatRegAddr,
+ (IX_OSAL_READ_LONG(qUOStatRegAddr) &
+ ~underflowBitMask));
+ *qStatus |= IX_QMGR_Q_STATUS_UF_BIT_MASK;
+ }
+ }
+ else /* read status of a queue in the range 32-63 */
+ {
+ extern UINT32 ixQMgrAqmIfQueUppStat0RegAddr;
+ extern UINT32 ixQMgrAqmIfQueUppStat1RegAddr;
+ extern UINT32 ixQMgrAqmIfQueUppStat0BitMask[];
+ extern UINT32 ixQMgrAqmIfQueUppStat1BitMask[];
+
+ volatile UINT32 *qNearEmptyStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat0RegAddr;
+ volatile UINT32 *qFullStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat1RegAddr;
+ int maskIndex = qId - IX_QMGR_MIN_QUEUPP_QID;
+ UINT32 qNearEmptyStatBitMask = ixQMgrAqmIfQueUppStat0BitMask[maskIndex];
+ UINT32 qFullStatBitMask = ixQMgrAqmIfQueUppStat1BitMask[maskIndex];
+
+ /* Reset the status bits */
+ *qStatus = 0;
+
+ /* Check if the queue is nearly empty */
+ if (IX_OSAL_READ_LONG(qNearEmptyStatRegAddr) & qNearEmptyStatBitMask)
+ {
+ *qStatus |= IX_QMGR_Q_STATUS_NE_BIT_MASK;
+ }
+
+ /* Check if the queue is full */
+ if (IX_OSAL_READ_LONG(qFullStatRegAddr) & qFullStatBitMask)
+ {
+ *qStatus |= IX_QMGR_Q_STATUS_F_BIT_MASK;
+ }
+ }
+ return IX_SUCCESS;
+}
+#endif /* def NO_INLINE_APIS */
diff --git a/cpu/ixp/npe/IxQMgrQCfg.c b/cpu/ixp/npe/IxQMgrQCfg.c
new file mode 100644
index 0000000..ec7d837
--- /dev/null
+++ b/cpu/ixp/npe/IxQMgrQCfg.c
@@ -0,0 +1,543 @@
+/**
+ * @file QMgrQCfg.c
+ *
+ * @author Intel Corporation
+ * @date 30-Oct-2001
+ *
+ * @brief This modules provides an interface for setting up the static
+ * configuration of AQM queues.This file contains the following
+ * functions:
+ *
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * System defined include files.
+ */
+
+/*
+ * User defined include files.
+ */
+#include "IxOsal.h"
+#include "IxQMgr.h"
+#include "IxQMgrAqmIf_p.h"
+#include "IxQMgrQCfg_p.h"
+#include "IxQMgrDefines_p.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+
+#define IX_QMGR_MIN_ENTRY_SIZE_IN_WORDS 16
+
+/* Total size of SRAM */
+#define IX_QMGR_AQM_SRAM_SIZE_IN_BYTES 0x4000
+
+/*
+ * Check that qId is a valid queue identifier. This is provided to
+ * make the code easier to read.
+ */
+#define IX_QMGR_QID_IS_VALID(qId) \
+(((qId) >= (IX_QMGR_MIN_QID)) && ((qId) <= (IX_QMGR_MAX_QID)))
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/*
+ * This struct describes an AQM queue.
+ * N.b. bufferSizeInWords and qEntrySizeInWords are stored in the queue
+ * as these are requested by Access in the data path. sizeInEntries is
+ * not required by the data path so it can be calculated dynamically.
+ *
+ */
+typedef struct
+{
+ char qName[IX_QMGR_MAX_QNAME_LEN+1]; /* Textual description of a queue*/
+ IxQMgrQSizeInWords qSizeInWords; /* The number of words in the queue */
+ IxQMgrQEntrySizeInWords qEntrySizeInWords; /* Number of words per queue entry*/
+ BOOL isConfigured; /* This flag is TRUE if the queue has
+ * been configured
+ */
+} IxQMgrCfgQ;
+
+/*
+ * Variable declarations global to this file. Externs are followed by
+ * statics.
+ */
+
+extern UINT32 * ixQMgrAqmIfQueAccRegAddr[];
+
+/* Store data required to inline read and write access
+ */
+IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[IX_QMGR_MAX_NUM_QUEUES];
+
+static IxQMgrCfgQ cfgQueueInfo[IX_QMGR_MAX_NUM_QUEUES];
+
+/* This pointer holds the starting address of AQM SRAM not used by
+ * the AQM queues.
+ */
+static UINT32 freeSramAddress=0;
+
+/* 4 words of zeroed memory for inline access */
+static UINT32 zeroedPlaceHolder[4] = { 0, 0, 0, 0 };
+
+static BOOL cfgInitialized = FALSE;
+
+static IxOsalMutex ixQMgrQCfgMutex;
+
+/*
+ * Statistics
+ */
+static IxQMgrQCfgStats stats;
+
+/*
+ * Function declarations
+ */
+PRIVATE BOOL
+watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level);
+
+PRIVATE BOOL
+qSizeInWordsIsOk (IxQMgrQSizeInWords qSize);
+
+PRIVATE BOOL
+qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize);
+
+/*
+ * Function definitions.
+ */
+void
+ixQMgrQCfgInit (void)
+{
+ int loopIndex;
+
+ for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
+ {
+ /* info for code inlining */
+ ixQMgrAqmIfQueAccRegAddr[loopIndex] = zeroedPlaceHolder;
+
+ /* info for code inlining */
+ ixQMgrQInlinedReadWriteInfo[loopIndex].qReadCount = 0;
+ ixQMgrQInlinedReadWriteInfo[loopIndex].qWriteCount = 0;
+ ixQMgrQInlinedReadWriteInfo[loopIndex].qAccRegAddr = zeroedPlaceHolder;
+ ixQMgrQInlinedReadWriteInfo[loopIndex].qUOStatRegAddr = zeroedPlaceHolder;
+ ixQMgrQInlinedReadWriteInfo[loopIndex].qUflowStatBitMask = 0;
+ ixQMgrQInlinedReadWriteInfo[loopIndex].qOflowStatBitMask = 0;
+ ixQMgrQInlinedReadWriteInfo[loopIndex].qEntrySizeInWords = 0;
+ ixQMgrQInlinedReadWriteInfo[loopIndex].qSizeInEntries = 0;
+ ixQMgrQInlinedReadWriteInfo[loopIndex].qConfigRegAddr = zeroedPlaceHolder;
+ }
+
+ /* Initialise the AqmIf component */
+ ixQMgrAqmIfInit ();
+
+ /* Reset all queues to have queue name = NULL, entry size = 0 and
+ * isConfigured = false
+ */
+ for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
+ {
+ strcpy (cfgQueueInfo[loopIndex].qName, "");
+ cfgQueueInfo[loopIndex].qSizeInWords = 0;
+ cfgQueueInfo[loopIndex].qEntrySizeInWords = 0;
+ cfgQueueInfo[loopIndex].isConfigured = FALSE;
+
+ /* Statistics */
+ stats.qStats[loopIndex].isConfigured = FALSE;
+ stats.qStats[loopIndex].qName = cfgQueueInfo[loopIndex].qName;
+ }
+
+ /* Statistics */
+ stats.wmSetCnt = 0;
+
+ ixQMgrAqmIfSramBaseAddressGet (&freeSramAddress);
+
+ ixOsalMutexInit(&ixQMgrQCfgMutex);
+
+ cfgInitialized = TRUE;
+}
+
+void
+ixQMgrQCfgUninit (void)
+{
+ cfgInitialized = FALSE;
+
+ /* Uninitialise the AqmIf component */
+ ixQMgrAqmIfUninit ();
+}
+
+IX_STATUS
+ixQMgrQConfig (char *qName,
+ IxQMgrQId qId,
+ IxQMgrQSizeInWords qSizeInWords,
+ IxQMgrQEntrySizeInWords qEntrySizeInWords)
+{
+ UINT32 aqmLocalBaseAddress;
+
+ if (!cfgInitialized)
+ {
+ return IX_FAIL;
+ }
+
+ if (!IX_QMGR_QID_IS_VALID(qId))
+ {
+ return IX_QMGR_INVALID_Q_ID;
+ }
+
+ else if (NULL == qName)
+ {
+ return IX_QMGR_PARAMETER_ERROR;
+ }
+
+ else if (strlen (qName) > IX_QMGR_MAX_QNAME_LEN)
+ {
+ return IX_QMGR_PARAMETER_ERROR;
+ }
+
+ else if (!qSizeInWordsIsOk (qSizeInWords))
+ {
+ return IX_QMGR_INVALID_QSIZE;
+ }
+
+ else if (!qEntrySizeInWordsIsOk (qEntrySizeInWords))
+ {
+ return IX_QMGR_INVALID_Q_ENTRY_SIZE;
+ }
+
+ else if (cfgQueueInfo[qId].isConfigured)
+ {
+ return IX_QMGR_Q_ALREADY_CONFIGURED;
+ }
+
+ ixOsalMutexLock(&ixQMgrQCfgMutex, IX_OSAL_WAIT_FOREVER);
+
+ /* Write the config register */
+ ixQMgrAqmIfQueCfgWrite (qId,
+ qSizeInWords,
+ qEntrySizeInWords,
+ freeSramAddress);
+
+
+ strcpy (cfgQueueInfo[qId].qName, qName);
+ cfgQueueInfo[qId].qSizeInWords = qSizeInWords;
+ cfgQueueInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
+
+ /* store pre-computed information in the same cache line
+ * to facilitate inlining of QRead and QWrite functions
+ * in IxQMgr.h
+ */
+ ixQMgrQInlinedReadWriteInfo[qId].qReadCount = 0;
+ ixQMgrQInlinedReadWriteInfo[qId].qWriteCount = 0;
+ ixQMgrQInlinedReadWriteInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
+ ixQMgrQInlinedReadWriteInfo[qId].qSizeInEntries =
+ (UINT32)qSizeInWords / (UINT32)qEntrySizeInWords;
+
+ /* Calculate the new freeSramAddress from the size of the queue
+ * currently being configured.
+ */
+ freeSramAddress += (qSizeInWords * IX_QMGR_NUM_BYTES_PER_WORD);
+
+ /* Get the virtual SRAM address */
+ ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
+
+ IX_OSAL_ASSERT((freeSramAddress - (aqmLocalBaseAddress + (IX_QMGR_QUEBUFFER_SPACE_OFFSET))) <=
+ IX_QMGR_QUE_BUFFER_SPACE_SIZE);
+
+ /* The queue is now configured */
+ cfgQueueInfo[qId].isConfigured = TRUE;
+
+ ixOsalMutexUnlock(&ixQMgrQCfgMutex);
+
+#ifndef NDEBUG
+ /* Update statistics */
+ stats.qStats[qId].isConfigured = TRUE;
+ stats.qStats[qId].qName = cfgQueueInfo[qId].qName;
+#endif
+ return IX_SUCCESS;
+}
+
+IxQMgrQSizeInWords
+ixQMgrQSizeInWordsGet (IxQMgrQId qId)
+{
+ /* No parameter checking as this is used on the data path */
+ return (cfgQueueInfo[qId].qSizeInWords);
+}
+
+IX_STATUS
+ixQMgrQSizeInEntriesGet (IxQMgrQId qId,
+ unsigned *qSizeInEntries)
+{
+ if (!ixQMgrQIsConfigured(qId))
+ {
+ return IX_QMGR_Q_NOT_CONFIGURED;
+ }
+
+ if(NULL == qSizeInEntries)
+ {
+ return IX_QMGR_PARAMETER_ERROR;
+ }
+
+ *qSizeInEntries = (UINT32)(cfgQueueInfo[qId].qSizeInWords) /
+ (UINT32)cfgQueueInfo[qId].qEntrySizeInWords;
+
+ return IX_SUCCESS;
+}
+
+IxQMgrQEntrySizeInWords
+ixQMgrQEntrySizeInWordsGet (IxQMgrQId qId)
+{
+ /* No parameter checking as this is used on the data path */
+ return (cfgQueueInfo[qId].qEntrySizeInWords);
+}
+
+IX_STATUS
+ixQMgrWatermarkSet (IxQMgrQId qId,
+ IxQMgrWMLevel ne,
+ IxQMgrWMLevel nf)
+{
+ IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */
+ IxQMgrQStatus qStatusOnExit; /* to this function */
+
+ if (!ixQMgrQIsConfigured(qId))
+ {
+ return IX_QMGR_Q_NOT_CONFIGURED;
+ }
+
+ if (!watermarkLevelIsOk (qId, ne))
+ {
+ return IX_QMGR_INVALID_Q_WM;
+ }
+
+ if (!watermarkLevelIsOk (qId, nf))
+ {
+ return IX_QMGR_INVALID_Q_WM;
+ }
+
+ /* Get the current queue status */
+ ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry);
+
+#ifndef NDEBUG
+ /* Update statistics */
+ stats.wmSetCnt++;
+#endif
+
+ ixQMgrAqmIfWatermarkSet (qId,
+ ne,
+ nf);
+
+ /* Get the current queue status */
+ ixQMgrAqmIfQueStatRead (qId, &qStatusOnExit);
+
+ /* If the status has changed return a warning */
+ if (qStatusOnEntry != qStatusOnExit)
+ {
+ return IX_QMGR_WARNING;
+ }
+
+ return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrAvailableSramAddressGet (UINT32 *address,
+ unsigned *sizeOfFreeRam)
+{
+ UINT32 aqmLocalBaseAddress;
+
+ if ((NULL == address)||(NULL == sizeOfFreeRam))
+ {
+ return IX_QMGR_PARAMETER_ERROR;
+ }
+ if (!cfgInitialized)
+ {
+ return IX_FAIL;
+ }
+
+ *address = freeSramAddress;
+
+ /* Get the virtual SRAM address */
+ ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
+
+ /*
+ * Calculate the size in bytes of free sram
+ * i.e. current free SRAM virtual pointer from
+ * (base + total size)
+ */
+ *sizeOfFreeRam =
+ (aqmLocalBaseAddress +
+ IX_QMGR_AQM_SRAM_SIZE_IN_BYTES) -
+ freeSramAddress;
+
+ if (0 == *sizeOfFreeRam)
+ {
+ return IX_QMGR_NO_AVAILABLE_SRAM;
+ }
+
+ return IX_SUCCESS;
+}
+
+BOOL
+ixQMgrQIsConfigured (IxQMgrQId qId)
+{
+ if (!IX_QMGR_QID_IS_VALID(qId))
+ {
+ return FALSE;
+ }
+
+ return cfgQueueInfo[qId].isConfigured;
+}
+
+IxQMgrQCfgStats*
+ixQMgrQCfgStatsGet (void)
+{
+ return &stats;
+}
+
+IxQMgrQCfgStats*
+ixQMgrQCfgQStatsGet (IxQMgrQId qId)
+{
+ unsigned int ne;
+ unsigned int nf;
+ UINT32 baseAddress;
+ UINT32 readPtr;
+ UINT32 writePtr;
+
+ stats.qStats[qId].qSizeInWords = cfgQueueInfo[qId].qSizeInWords;
+ stats.qStats[qId].qEntrySizeInWords = cfgQueueInfo[qId].qEntrySizeInWords;
+
+ if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
+ {
+ if (IX_QMGR_WARNING != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
+ {
+ IX_QMGR_LOG_WARNING1("Failed to get the number of entries in queue.... %d\n", qId);
+ }
+ }
+
+ ixQMgrAqmIfQueCfgRead (qId,
+ stats.qStats[qId].numEntries,
+ &baseAddress,
+ &ne,
+ &nf,
+ &readPtr,
+ &writePtr);
+
+ stats.qStats[qId].baseAddress = baseAddress;
+ stats.qStats[qId].ne = ne;
+ stats.qStats[qId].nf = nf;
+ stats.qStats[qId].readPtr = readPtr;
+ stats.qStats[qId].writePtr = writePtr;
+
+ return &stats;
+}
+
+/*
+ * Static function definitions
+ */
+
+PRIVATE BOOL
+watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level)
+{
+ unsigned qSizeInEntries;
+
+ switch (level)
+ {
+ case IX_QMGR_Q_WM_LEVEL0:
+ case IX_QMGR_Q_WM_LEVEL1:
+ case IX_QMGR_Q_WM_LEVEL2:
+ case IX_QMGR_Q_WM_LEVEL4:
+ case IX_QMGR_Q_WM_LEVEL8:
+ case IX_QMGR_Q_WM_LEVEL16:
+ case IX_QMGR_Q_WM_LEVEL32:
+ case IX_QMGR_Q_WM_LEVEL64:
+ break;
+ default:
+ return FALSE;
+ }
+
+ /* Check watermark is not bigger than the qSizeInEntries */
+ ixQMgrQSizeInEntriesGet(qId, &qSizeInEntries);
+
+ if ((unsigned)level > qSizeInEntries)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+PRIVATE BOOL
+qSizeInWordsIsOk (IxQMgrQSizeInWords qSize)
+{
+ BOOL status;
+
+ switch (qSize)
+ {
+ case IX_QMGR_Q_SIZE16:
+ case IX_QMGR_Q_SIZE32:
+ case IX_QMGR_Q_SIZE64:
+ case IX_QMGR_Q_SIZE128:
+ status = TRUE;
+ break;
+ default:
+ status = FALSE;
+ break;
+ }
+
+ return status;
+}
+
+PRIVATE BOOL
+qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize)
+{
+ BOOL status;
+
+ switch (entrySize)
+ {
+ case IX_QMGR_Q_ENTRY_SIZE1:
+ case IX_QMGR_Q_ENTRY_SIZE2:
+ case IX_QMGR_Q_ENTRY_SIZE4:
+ status = TRUE;
+ break;
+ default:
+ status = FALSE;
+ break;
+ }
+
+ return status;
+}
diff --git a/cpu/ixp/npe/Makefile b/cpu/ixp/npe/Makefile
new file mode 100644
index 0000000..412b418
--- /dev/null
+++ b/cpu/ixp/npe/Makefile
@@ -0,0 +1,100 @@
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB := $(obj)libnpe.a
+
+LOCAL_CFLAGS += -I$(TOPDIR)/cpu/ixp/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB
+CFLAGS += $(LOCAL_CFLAGS)
+HOST_CFLAGS += $(LOCAL_CFLAGS)
+
+COBJS := npe.o \
+ miiphy.o \
+ IxOsalBufferMgt.o \
+ IxOsalIoMem.o \
+ IxOsalOsCacheMMU.o \
+ IxOsalOsMsgQ.o \
+ IxOsalOsSemaphore.o \
+ IxOsalOsServices.o \
+ IxOsalOsThread.o \
+ IxEthAcc.o \
+ IxEthAccCommon.o \
+ IxEthAccControlInterface.o \
+ IxEthAccDataPlane.o \
+ IxEthAccMac.o \
+ IxEthAccMii.o \
+ IxEthDBAPI.o \
+ IxEthDBAPISupport.o \
+ IxEthDBCore.o \
+ IxEthDBEvents.o \
+ IxEthDBFeatures.o \
+ IxEthDBFirewall.o \
+ IxEthDBHashtable.o \
+ IxEthDBLearning.o \
+ IxEthDBMem.o \
+ IxEthDBNPEAdaptor.o \
+ IxEthDBPortUpdate.o \
+ IxEthDBReports.o \
+ IxEthDBSearch.o \
+ IxEthDBSpanningTree.o \
+ IxEthDBUtil.o \
+ IxEthDBVlan.o \
+ IxEthDBWiFi.o \
+ IxEthMii.o \
+ IxQMgrAqmIf.o \
+ IxQMgrDispatcher.o \
+ IxQMgrInit.o \
+ IxQMgrQAccess.o \
+ IxQMgrQCfg.o \
+ IxFeatureCtrl.o \
+ IxNpeDl.o \
+ IxNpeDlImageMgr.o \
+ IxNpeDlNpeMgr.o \
+ IxNpeDlNpeMgrUtils.o \
+ IxNpeMicrocode.o \
+ IxNpeMh.o \
+ IxNpeMhConfig.o \
+ IxNpeMhReceive.o \
+ IxNpeMhSend.o \
+ IxNpeMhSolicitedCbMgr.o \
+ IxNpeMhUnsolicitedCbMgr.o
+
+
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(LIB)
+
+$(LIB): $(obj).depend $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/ixp/npe/include/IxAssert.h b/cpu/ixp/npe/include/IxAssert.h
new file mode 100644
index 0000000..eae8b3f
--- /dev/null
+++ b/cpu/ixp/npe/include/IxAssert.h
@@ -0,0 +1,71 @@
+/**
+ * @file IxAssert.h
+ *
+ * @date 21-MAR-2002 (replaced by OSAL)
+ *
+ * @brief This file contains assert and ensure macros used by the IXP400 software
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxAssert IXP400 Assertion Macros (IxAssert) API
+ *
+ * @brief Assertion support
+ *
+ * @{
+ */
+
+#ifndef IXASSERT_H
+
+#ifndef __doxygen_HIDE
+#define IXASSERT_H
+#endif /* __doxygen_HIDE */
+
+#include "IxOsalBackward.h"
+
+#endif /* IXASSERT_H */
+
+/**
+ * @} addtogroup IxAssert
+ */
+
+
+
diff --git a/cpu/ixp/npe/include/IxAtmSch.h b/cpu/ixp/npe/include/IxAtmSch.h
new file mode 100644
index 0000000..73c3be2
--- /dev/null
+++ b/cpu/ixp/npe/include/IxAtmSch.h
@@ -0,0 +1,504 @@
+/**
+ * @file IxAtmSch.h
+ *
+ * @date 23-NOV-2001
+ *
+ * @brief Header file for the IXP400 ATM Traffic Shaper
+ *
+ * This component demonstrates an ATM Traffic Shaper implementation. It
+ * will perform shaping on upto 12 ports and total of 44 VCs accross all ports,
+ * 32 are intended for AAL0/5 and 12 for OAM (1 per port).
+ * The supported traffic types are;1 rt-VBR VC where PCR = SCR.
+ * (Effectively CBR) and Up-to 44 VBR VCs.
+ *
+ * This component models the ATM ports and VCs and is capable of producing
+ * a schedule of ATM cells per port which can be supplied to IxAtmdAcc
+ * for execution on the data path.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ *
+ * @sa IxAtmm.h
+ *
+ */
+
+/**
+ * @defgroup IxAtmSch IXP400 ATM Transmit Scheduler (IxAtmSch) API
+ *
+ * @brief IXP400 ATM scheduler component Public API
+ *
+ * @{
+ */
+
+#ifndef IXATMSCH_H
+#define IXATMSCH_H
+
+#include "IxOsalTypes.h"
+#include "IxAtmTypes.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/* Return codes */
+
+/**
+ * @ingroup IxAtmSch
+ *
+ * @def IX_ATMSCH_RET_NOT_ADMITTED
+ * @brief Indicates that CAC function has rejected VC registration due
+ * to insufficient line capacity.
+*/
+#define IX_ATMSCH_RET_NOT_ADMITTED 2
+
+/**
+ * @ingroup IxAtmSch
+ *
+ * @def IX_ATMSCH_RET_QUEUE_FULL
+ * @brief Indicates that the VC queue is full, no more demand can be
+ * queued at this time.
+ */
+#define IX_ATMSCH_RET_QUEUE_FULL 3
+
+/**
+ * @ingroup IxAtmSch
+ *
+ * @def IX_ATMSCH_RET_QUEUE_EMPTY
+ * @brief Indicates that all VC queues on this port are empty and
+ * therefore there are no cells to be scheduled at this time.
+ */
+#define IX_ATMSCH_RET_QUEUE_EMPTY 4
+
+/*
+ * Function declarations
+ */
+
+/**
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchInit(void)
+ *
+ * @brief This function is used to initialize the ixAtmSch component. It
+ * should be called before any other IxAtmSch API function.
+ *
+ * @param None
+ *
+ * @return
+ * - <b>IX_SUCCESS :</b> indicates that
+ * -# The ATM scheduler component has been successfully initialized.
+ * -# The scheduler is ready to accept Port modelling requests.
+ * - <b>IX_FAIL :</b> Some internal error has prevented the scheduler component
+ * from initialising.
+ */
+PUBLIC IX_STATUS
+ixAtmSchInit(void);
+
+/**
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchPortModelInitialize( IxAtmLogicalPort port,
+ unsigned int portRate,
+ unsigned int minCellsToSchedule)
+ *
+ * @brief This function shall be called first to initialize an ATM port before
+ * any other ixAtmSch API calls may be made for that port.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - The specific port to initialize. Valid
+ * values range from 0 to IX_UTOPIA_MAX_PORTS - 1, representing a
+ * maximum of IX_UTOPIA_MAX_PORTS possible ports.
+ *
+ * @param portRate unsigned int [in] - Value indicating the upstream capacity
+ * of the indicated port. The value should be supplied in
+ * units of ATM (53 bytes) cells per second.
+ * A port rate of 800Kbits/s is the equivalent
+ * of 1886 cells per second
+ *
+ * @param minCellsToSchedule unsigned int [in] - This parameter specifies the minimum
+ * number of cells which the scheduler will put in a schedule
+ * table for this port. This value sets the worst case CDVT for VCs
+ * on this port i.e. CDVT = 1*minCellsToSchedule/portRate.
+ * @return
+ * - <b>IX_SUCCESS :</b> indicates that
+ * -# The ATM scheduler has been successfully initialized.
+ * -# The requested port model has been established.
+ * -# The scheduler is ready to accept VC modelling requests
+ * on the ATM port.
+ * - <b>IX_FAIL :</b> indicates the requested port could not be
+ * initialized. */
+PUBLIC IX_STATUS
+ixAtmSchPortModelInitialize( IxAtmLogicalPort port,
+ unsigned int portRate,
+ unsigned int minCellsToSchedule);
+
+/**
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchPortRateModify( IxAtmLogicalPort port,
+ unsigned int portRate)
+ *
+ * @brief This function is called to modify the portRate on a
+ * previously initialized port, typically in the event that
+ * the line condition of the port changes.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port which is to be
+ * modified.
+ *
+ * @param portRate unsigned int [in] - Value indicating the new upstream
+ * capacity for this port in cells/second.
+ * A port rate of 800Kbits/s is the equivalent
+ * of 1886 cells per second
+ *
+ * @return
+ * - <b>IX_SUCCESS :</b> The port rate has been successfully modified.<br>
+ * - <b>IX_FAIL :</b> The port rate could not be modified, either
+ * because the input data was invalid, or the new port rate is
+ * insufficient to support established ATM VC contracts on this
+ * port.
+ *
+ * @warning The IxAtmSch component will validate the supplied port
+ * rate is sufficient to support all established VC
+ * contracts on the port. If the new port rate is
+ * insufficient to support all established contracts then
+ * the request to modify the port rate will be rejected.
+ * In this event, the user is expected to remove
+ * established contracts using the ixAtmSchVcModelRemove
+ * interface and then retry this interface.
+ *
+ * @sa ixAtmSchVcModelRemove() */
+PUBLIC IX_STATUS
+ixAtmSchPortRateModify( IxAtmLogicalPort port,
+ unsigned int portRate);
+
+
+/**
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchVcModelSetup( IxAtmLogicalPort port,
+ IxAtmTrafficDescriptor *trafficDesc,
+ IxAtmSchedulerVcId *vcId)
+ *
+ * @brief A client calls this interface to set up an upstream
+ * (transmitting) virtual connection model (VC) on the
+ * specified ATM port. This function also provides the
+ * virtual * connection admission control (CAC) service to the
+ * client.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the upstream
+ * VC is to be established.
+ *
+ * @param *trafficDesc @ref IxAtmTrafficDescriptor [in] - Pointer to a structure
+ * describing the requested traffic contract of the VC to be
+ * established. This structure contains the typical ATM
+ * traffic descriptor values (e.g. PCR, SCR, MBS, CDVT, etc.)
+ * defined by the ATM standard.
+ *
+ * @param *vcId @ref IxAtmSchedulerVcId [out] - This value will be filled with the
+ * port-unique identifier for this virtual connection. A
+ * valid identification is a non-negative number.
+ *
+ * @return
+ * - <b>IX_SUCCESS :</b> The VC has been successfully established on
+ * this port. The client may begin to submit demand on this VC.
+ * - <b>IX_ATMSCH_RET_NOT_ADMITTED :</b> The VC cannot be established
+ * on this port because there is insufficient upstream capacity
+ * available to support the requested traffic contract descriptor
+ * - <b>IX_FAIL :</b>Input data are invalid. VC has not been
+ * established.
+ */
+PUBLIC IX_STATUS
+ixAtmSchVcModelSetup( IxAtmLogicalPort port,
+ IxAtmTrafficDescriptor *trafficDesc,
+ IxAtmSchedulerVcId *vcId);
+
+/**
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchVcConnIdSet( IxAtmLogicalPort port,
+ IxAtmSchedulerVcId vcId,
+ IxAtmConnId vcUserConnId)
+ *
+ * @brief A client calls this interface to set the vcUserConnId for a VC on
+ * the specified ATM port. This vcUserConnId will default to
+ * IX_ATM_IDLE_CELLS_CONNID if this function is not called for a VC.
+ * Hence if the client does not call this function for a VC then only idle
+ * cells will be scheduled for this VC.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the upstream
+ * VC is has been established.
+ *
+ * @param vcId @ref IxAtmSchedulerVcId [in] - This is the unique identifier for this virtual
+ * connection. A valid identification is a non-negative number and is
+ * all ports.
+ *
+ * @param vcUserConnId @ref IxAtmConnId [in] - The connId is used to refer to a VC in schedule
+ * table entries. It is treated as the Id by which the scheduler client
+ * knows the VC. It is used in any communicatations from the Scheduler
+ * to the scheduler user e.g. schedule table entries.
+ *
+ * @return
+ * - <b>IX_SUCCESS :</b> The id has successfully been set.
+ * - <b>IX_FAIL :</b>Input data are invalid. connId id is not established.
+ */
+PUBLIC IX_STATUS
+ixAtmSchVcConnIdSet( IxAtmLogicalPort port,
+ IxAtmSchedulerVcId vcId,
+ IxAtmConnId vcUserConnId);
+
+/**
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchVcModelRemove( IxAtmLogicalPort port,
+ IxAtmSchedulerVcId vcId)
+ *
+ * @brief Interface called by the client to remove a previously
+ * established VC on a particular port.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be
+ * removed is established.
+ *
+ * @param vcId @ref IxAtmSchedulerVcId [in] - Identifies the VC to be removed. This is the
+ * value returned by the @ref ixAtmSchVcModelSetup call which
+ * established the relevant VC.
+ *
+ * @return
+ * - <b>IX_SUCCESS :</b> The VC has been successfully removed from
+ * this port. It is no longer modelled on this port.
+ * - <b>IX_FAIL :</b>Input data are invalid. The VC is still being modeled
+ * by the traffic shaper.
+ *
+ * @sa ixAtmSchVcModelSetup()
+ */
+PUBLIC IX_STATUS
+ixAtmSchVcModelRemove( IxAtmLogicalPort port,
+ IxAtmSchedulerVcId vcId);
+
+/**
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchVcQueueUpdate( IxAtmLogicalPort port,
+ IxAtmSchedulerVcId vcId,
+ unsigned int numberOfCells)
+ *
+ * @brief The client calls this function to notify IxAtmSch that the
+ * user of a VC has submitted cells for transmission.
+ *
+ * This information is stored, aggregated from a number of calls to
+ * ixAtmSchVcQueueUpdate and eventually used in the call to
+ * ixAtmSchTableUpdate.
+ *
+ * Normally IxAtmSch will update the VC queue by adding the number of
+ * cells to the current queue length. However, if IxAtmSch
+ * determines that the user has over-submitted for the VC and
+ * exceeded its transmission quota the queue request can be rejected.
+ * The user should resubmit the request later when the queue has been
+ * depleted.
+ *
+ * This implementation of ixAtmSchVcQueueUpdate uses no operating
+ * system or external facilities, either directly or indirectly.
+ * This allows clients to call this function form within an interrupt handler.
+ *
+ * This interface is structurally compatible with the
+ * IxAtmdAccSchQueueUpdate callback type definition required for
+ * IXP400 ATM scheduler interoperability.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be
+ * updated is established.
+ *
+ * @param vcId @ref IxAtmSchedulerVcId [in] - Identifies the VC to be updated. This is the
+ * value returned by the @ref ixAtmSchVcModelSetup call which
+ * established the relevant VC.
+ *
+ * @param numberOfCells unsigned int [in] - Indicates how many ATM cells should
+ * be added to the queue for this VC.
+ *
+ * @return
+ * - <b>IX_SUCCESS :</b> The VC queue has been successfully updated.
+ * - <b>IX_ATMSCH_RET_QUEUE_FULL :</b> The VC queue has reached a
+ * preset limit. This indicates the client has over-submitted
+ * and exceeded its transmission quota. The request is
+ * rejected. The VC queue is not updated. The VC user is
+ * advised to resubmit the request later.
+ * - <b>IX_FAIL :</b> The input are invalid. No VC queue is updated.
+ *
+ * @warning IxAtmSch assumes that the calling software ensures that
+ * calls to ixAtmSchVcQueueUpdate, ixAtmSchVcQueueClear and
+ * ixAtmSchTableUpdate are both self and mutually exclusive
+ * for the same port.
+ *
+ * @sa ixAtmSchVcQueueUpdate(), ixAtmSchVcQueueClear(), ixAtmSchTableUpdate(). */
+PUBLIC IX_STATUS
+ixAtmSchVcQueueUpdate( IxAtmLogicalPort port,
+ IxAtmSchedulerVcId vcId,
+ unsigned int numberOfCells);
+
+/**
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchVcQueueClear( IxAtmLogicalPort port,
+ IxAtmSchedulerVcId vcId)
+ *
+ * @brief The client calls this function to remove all currently
+ * queued cells from a registered VC. The pending cell count
+ * for the specified VC is reset to zero.
+ *
+ * This interface is structurally compatible with the
+ * IxAtmdAccSchQueueClear callback type definition required for
+ * IXP400 ATM scheduler interoperability.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be
+ * cleared is established.
+ *
+ * @param vcId @ref IxAtmSchedulerVcId [in] - Identifies the VC to be cleared. This is the
+ * value returned by the @ref ixAtmSchVcModelSetup call which
+ * established the relevant VC.
+ *
+ * @return
+ * - <b>IX_SUCCESS :</b> The VC queue has been successfully cleared.
+ * - <b>IX_FAIL :</b> The input are invalid. No VC queue is modified.
+ *
+ * @warning IxAtmSch assumes that the calling software ensures that
+ * calls to ixAtmSchVcQueueUpdate, ixAtmSchVcQueueClear and
+ * ixAtmSchTableUpdate are both self and mutually exclusive
+ * for the same port.
+ *
+ * @sa ixAtmSchVcQueueUpdate(), ixAtmSchVcQueueClear(), ixAtmSchTableUpdate(). */
+PUBLIC IX_STATUS
+ixAtmSchVcQueueClear( IxAtmLogicalPort port,
+ IxAtmSchedulerVcId vcId);
+
+/**
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchTableUpdate( IxAtmLogicalPort port,
+ unsigned int maxCells,
+ IxAtmScheduleTable **rettable)
+ *
+ * @brief The client calls this function to request an update of the
+ * schedule table for a particular ATM port.
+ *
+ * This is called when the client decides it needs a new sequence of
+ * cells to send (probably because the transmit queue is near to
+ * empty for this ATM port). The scheduler will use its stored
+ * information on the cells submitted for transmit (i.e. data
+ * supplied via @ref ixAtmSchVcQueueUpdate function) with the traffic
+ * descriptor information of all established VCs on the ATM port to
+ * decide the sequence of cells to be sent and fill the schedule
+ * table for a period of time into the future.
+ *
+ * IxAtmSch will guarantee a minimum of minCellsToSchedule if there
+ * is at least one cell ready to send. If there are no cells then
+ * IX_ATMSCH_RET_QUEUE_EMPTY is returned.
+ *
+ * This implementation of ixAtmSchTableUpdate uses no operating
+ * system or external facilities, either directly or indirectly.
+ * This allows clients to call this function form within an FIQ
+ * interrupt handler.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port for which requested
+ * schedule table is to be generated.
+ *
+ * @param maxCells unsigned [in] - Specifies the maximum number of cells
+ * that must be scheduled in the supplied table during any
+ * call to the interface.
+ *
+ * @param **table @ref IxAtmScheduleTable [out] - A pointer to an area of
+ * storage is returned which contains the generated
+ * schedule table. The client should not modify the
+ * contents of this table.
+ *
+ * @return
+ * - <b>IX_SUCCESS :</b> The schedule table has been published.
+ * Currently there is at least one VC queue that is nonempty.
+ * - <b>IX_ATMSCH_RET_QUEUE_EMPTY :</b> Currently all VC queues on
+ * this port are empty. The schedule table returned is set to
+ * NULL. The client is not expected to invoke this function
+ * again until more cells have been submitted on this port
+ * through the @ref ixAtmSchVcQueueUpdate function.
+ * - <b>IX_FAIL :</b> The input are invalid. No action is taken.
+ *
+ * @warning IxAtmSch assumes that the calling software ensures that
+ * calls to ixAtmSchVcQueueUpdate, ixAtmSchVcQueueClear and
+ * ixAtmSchTableUpdate are both self and mutually exclusive
+ * for the same port.
+ *
+ * @warning Subsequent calls to this function for the same port will
+ * overwrite the contents of previously supplied schedule
+ * tables. The client must be completely finished with the
+ * previously supplied schedule table before calling this
+ * function again for the same port.
+ *
+ * @sa ixAtmSchVcQueueUpdate(), ixAtmSchVcQueueClear(), ixAtmSchTableUpdate(). */
+PUBLIC IX_STATUS
+ixAtmSchTableUpdate( IxAtmLogicalPort port,
+ unsigned int maxCells,
+ IxAtmScheduleTable **rettable);
+
+/**
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchShow(void)
+ *
+ * @brief Utility function which will print statistics on the current
+ * and accumulated state of VCs and traffic in the ATM
+ * scheduler component. Output is sent to the default output
+ * device.
+ *
+ * @param none
+ * @return none
+ */
+PUBLIC void
+ixAtmSchShow(void);
+
+/**
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchStatsClear(void)
+ *
+ * @brief Utility function which will reset all counter statistics in
+ * the ATM scheduler to zero.
+ *
+ * @param none
+ * @return none
+ */
+PUBLIC void
+ixAtmSchStatsClear(void);
+
+#endif
+/* IXATMSCH_H */
+
+/** @} */
diff --git a/cpu/ixp/npe/include/IxAtmTypes.h b/cpu/ixp/npe/include/IxAtmTypes.h
new file mode 100644
index 0000000..8624c33
--- /dev/null
+++ b/cpu/ixp/npe/include/IxAtmTypes.h
@@ -0,0 +1,409 @@
+/**
+ * @file IxAtmTypes.h
+ *
+ * @date 24-MAR-2002
+ *
+ * @brief This file contains Atm types common to a number of Atm components.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/* ------------------------------------------------------
+ Doxygen group definitions
+ ------------------------------------------------------ */
+/**
+ * @defgroup IxAtmTypes IXP400 ATM Types (IxAtmTypes)
+ *
+ * @brief The common set of types used in many Atm components
+ *
+ * @{ */
+
+#ifndef IXATMTYPES_H
+#define IXATMTYPES_H
+
+#include "IxNpeA.h"
+
+/**
+ * @enum IxAtmLogicalPort
+ *
+ * @brief Logical Port Definitions :
+ *
+ * Only 1 port is available in SPHY configuration
+ * 12 ports are enabled in MPHY configuration
+ *
+ */
+typedef enum
+{
+ IX_UTOPIA_PORT_0 = 0, /**< Port 0 */
+#ifdef IX_NPE_MPHYMULTIPORT
+ IX_UTOPIA_PORT_1, /**< Port 1 */
+ IX_UTOPIA_PORT_2, /**< Port 2 */
+ IX_UTOPIA_PORT_3, /**< Port 3 */
+ IX_UTOPIA_PORT_4, /**< Port 4 */
+ IX_UTOPIA_PORT_5, /**< Port 5 */
+ IX_UTOPIA_PORT_6, /**< Port 6 */
+ IX_UTOPIA_PORT_7, /**< Port 7 */
+ IX_UTOPIA_PORT_8, /**< Port 8 */
+ IX_UTOPIA_PORT_9, /**< Port 9 */
+ IX_UTOPIA_PORT_10, /**< Port 10 */
+ IX_UTOPIA_PORT_11, /**< Port 11 */
+#endif /* IX_NPE_MPHY */
+ IX_UTOPIA_MAX_PORTS /**< Not a port - just a definition for the
+ * maximum possible ports
+ */
+} IxAtmLogicalPort;
+
+/**
+ * @def IX_ATM_CELL_PAYLOAD_SIZE
+ * @brief Size of a ATM cell payload
+ */
+#define IX_ATM_CELL_PAYLOAD_SIZE (48)
+
+/**
+ * @def IX_ATM_CELL_SIZE
+ * @brief Size of a ATM cell, including header
+ */
+#define IX_ATM_CELL_SIZE (53)
+
+/**
+ * @def IX_ATM_CELL_SIZE_NO_HEC
+ * @brief Size of a ATM cell, excluding HEC byte
+ */
+#define IX_ATM_CELL_SIZE_NO_HEC (IX_ATM_CELL_SIZE - 1)
+
+/**
+ * @def IX_ATM_OAM_CELL_SIZE_NO_HEC
+ * @brief Size of a OAM cell, excluding HEC byte
+ */
+#define IX_ATM_OAM_CELL_SIZE_NO_HEC IX_ATM_CELL_SIZE_NO_HEC
+
+/**
+ * @def IX_ATM_AAL0_48_CELL_PAYLOAD_SIZE
+ * @brief Size of a AAL0 48 Cell payload
+ */
+#define IX_ATM_AAL0_48_CELL_PAYLOAD_SIZE IX_ATM_CELL_PAYLOAD_SIZE
+
+/**
+ * @def IX_ATM_AAL5_CELL_PAYLOAD_SIZE
+ * @brief Size of a AAL5 Cell payload
+ */
+#define IX_ATM_AAL5_CELL_PAYLOAD_SIZE IX_ATM_CELL_PAYLOAD_SIZE
+
+/**
+ * @def IX_ATM_AAL0_52_CELL_SIZE_NO_HEC
+ * @brief Size of a AAL0 52 Cell, excluding HEC byte
+ */
+#define IX_ATM_AAL0_52_CELL_SIZE_NO_HEC IX_ATM_CELL_SIZE_NO_HEC
+
+
+/**
+ * @def IX_ATM_MAX_VPI
+ * @brief Maximum value of an ATM VPI
+ */
+#define IX_ATM_MAX_VPI 255
+
+/**
+ * @def IX_ATM_MAX_VCI
+ * @brief Maximum value of an ATM VCI
+ */
+#define IX_ATM_MAX_VCI 65535
+
+ /**
+ * @def IX_ATM_MAX_NUM_AAL_VCS
+ * @brief Maximum number of active AAL5/AAL0 VCs in the system
+ */
+#define IX_ATM_MAX_NUM_AAL_VCS 32
+
+/**
+ * @def IX_ATM_MAX_NUM_VC
+ * @brief Maximum number of active AAL5/AAL0 VCs in the system
+ * The use of this macro is depreciated, it is retained for
+ * backward compatiblity. For current software release
+ * and beyond the define IX_ATM_MAX_NUM_AAL_VC should be used.
+ */
+#define IX_ATM_MAX_NUM_VC IX_ATM_MAX_NUM_AAL_VCS
+
+
+
+/**
+ * @def IX_ATM_MAX_NUM_OAM_TX_VCS
+ * @brief Maximum number of active OAM Tx VCs in the system,
+ * 1 OAM VC per port
+ */
+#define IX_ATM_MAX_NUM_OAM_TX_VCS IX_UTOPIA_MAX_PORTS
+
+/**
+ * @def IX_ATM_MAX_NUM_OAM_RX_VCS
+ * @brief Maximum number of active OAM Rx VCs in the system,
+ * 1 OAM VC shared accross all ports
+ */
+#define IX_ATM_MAX_NUM_OAM_RX_VCS 1
+
+/**
+ * @def IX_ATM_MAX_NUM_AAL_OAM_TX_VCS
+ * @brief Maximum number of active AAL5/AAL0/OAM Tx VCs in the system
+ */
+#define IX_ATM_MAX_NUM_AAL_OAM_TX_VCS (IX_ATM_MAX_NUM_AAL_VCS + IX_ATM_MAX_NUM_OAM_TX_VCS)
+
+/**
+ * @def IX_ATM_MAX_NUM_AAL_OAM_RX_VCS
+ * @brief Maximum number of active AAL5/AAL0/OAM Rx VCs in the system
+ */
+#define IX_ATM_MAX_NUM_AAL_OAM_RX_VCS (IX_ATM_MAX_NUM_AAL_VCS + IX_ATM_MAX_NUM_OAM_RX_VCS)
+
+/**
+ * @def IX_ATM_IDLE_CELLS_CONNID
+ * @brief VC Id used to indicate idle cells in the returned schedule table.
+ */
+#define IX_ATM_IDLE_CELLS_CONNID 0
+
+
+/**
+ * @def IX_ATM_CELL_HEADER_VCI_GET
+ * @brief get the VCI field from a cell header
+ */
+#define IX_ATM_CELL_HEADER_VCI_GET(cellHeader) \
+ (((cellHeader) >> 4) & IX_OAM_VCI_BITS_MASK);
+
+/**
+ * @def IX_ATM_CELL_HEADER_VPI_GET
+ * @brief get the VPI field from a cell header
+ */
+#define IX_ATM_CELL_HEADER_VPI_GET(cellHeader) \
+ (((cellHeader) >> 20) & IX_OAM_VPI_BITS_MASK);
+
+/**
+ * @def IX_ATM_CELL_HEADER_PTI_GET
+ * @brief get the PTI field from a cell header
+ */
+#define IX_ATM_CELL_HEADER_PTI_GET(cellHeader) \
+ ((cellHeader) >> 1) & IX_OAM_PTI_BITS_MASK;
+
+/**
+ * @typedef IxAtmCellHeader
+ *
+ * @brief ATM Cell Header, does not contain 4 byte HEC, added by NPE-A
+ */
+typedef unsigned int IxAtmCellHeader;
+
+
+/**
+ * @enum IxAtmServiceCategory
+ *
+ * @brief Enumerated type representing available ATM service categories.
+ * For more informatoin on these categories, see "Traffic Management
+ * Specification" v4.1, published by the ATM Forum -
+ * http://www.atmforum.com
+ */
+typedef enum
+{
+ IX_ATM_CBR, /**< Constant Bit Rate */
+ IX_ATM_RTVBR, /**< Real Time Variable Bit Rate */
+ IX_ATM_VBR, /**< Variable Bit Rate */
+ IX_ATM_UBR, /**< Unspecified Bit Rate */
+ IX_ATM_ABR /**< Available Bit Rate (not supported) */
+
+} IxAtmServiceCategory;
+
+/**
+ *
+ * @enum IxAtmRxQueueId
+ *
+ * @brief Rx Queue Type for RX traffic
+ *
+ * IxAtmRxQueueId defines the queues involved for receiving data.
+ *
+ * There are two queues to facilitate prioritisation handling
+ * and processing the 2 queues with different algorithms and
+ * constraints
+ *
+ * e.g. : one queue can carry voice (or time-critical traffic), the
+ * other queue can carry non-voice traffic
+ *
+ */
+typedef enum
+{
+ IX_ATM_RX_A = 0, /**< RX queue A */
+ IX_ATM_RX_B, /**< RX queue B */
+ IX_ATM_MAX_RX_STREAMS /**< Maximum number of RX streams */
+} IxAtmRxQueueId;
+
+/**
+ * @brief Structure describing an ATM traffic contract for a Virtual
+ * Connection (VC).
+ *
+ * Structure is used to specify the requested traffic contract for a
+ * VC to the IxAtmSch component using the @ref ixAtmSchVcModelSetup
+ * interface.
+ *
+ * These parameters are defined by the ATM forum working group
+ * (http://www.atmforum.com).
+ *
+ * @note Typical values for a voice channel 64 Kbit/s
+ * - atmService @a IX_ATM_RTVBR
+ * - pcr 400 (include IP overhead, and AAL5 trailer)
+ * - cdvt 5000000 (5 ms)
+ * - scr = pcr
+ *
+ * @note Typical values for a data channel 800 Kbit/s
+ * - atmService @a IX_ATM_UBR
+ * - pcr 1962 (include IP overhead, and AAL5 trailer)
+ * - cdvt 5000000 (5 ms)
+ *
+ */
+typedef struct
+{
+ IxAtmServiceCategory atmService; /**< ATM service category */
+ unsigned pcr; /**< Peak Cell Rate - cells per second */
+ unsigned cdvt; /**< Cell Delay Variation Tolerance - in nanoseconds */
+ unsigned scr; /**< Sustained Cell Rate - cells per second */
+ unsigned mbs; /**< Max Burst Size - cells */
+ unsigned mcr; /**< Minimum Cell Rate - cells per second */
+ unsigned mfs; /**< Max Frame Size - cells */
+} IxAtmTrafficDescriptor;
+
+/**
+ * @typedef IxAtmConnId
+ *
+ * @brief ATM VC data connection identifier.
+ *
+ * This is is generated by IxAtmdAcc when a successful connection is
+ * made on a VC. The is the ID by which IxAtmdAcc knows an active
+ * VC and should be used in IxAtmdAcc API calls to reference a
+ * specific VC.
+ */
+typedef unsigned int IxAtmConnId;
+
+/**
+ * @typedef IxAtmSchedulerVcId
+ *
+ * @brief ATM VC scheduling connection identifier.
+ *
+ * This id is generated and used by ATM Tx controller, generally
+ * the traffic shaper (e.g. IxAtmSch). The IxAtmdAcc component
+ * will request one of these Ids whenever a data connection on
+ * a Tx VC is requested. This ID will be used in callbacks to
+ * the ATM Transmission Ctrl s/w (e.g. IxAtmm) to reference a
+ * particular VC.
+ */
+typedef int IxAtmSchedulerVcId;
+
+/**
+ * @typedef IxAtmNpeRxVcId
+ *
+ * @brief ATM Rx VC identifier used by the ATM Npe.
+ *
+ * This Id is generated by IxAtmdAcc when a successful data connection
+ * is made on a rx VC.
+ */
+typedef unsigned int IxAtmNpeRxVcId;
+
+/**
+ * @brief ATM Schedule Table entry
+ *
+ * This IxAtmScheduleTableEntry is used by an ATM scheduler to inform
+ * IxAtmdAcc about the data to transmit (in term of cells per VC)
+ *
+ * This structure defines
+ * @li the number of cells to be transmitted (numberOfCells)
+ * @li the VC connection to be used for transmission (connId).
+ *
+ * @note - When the connection Id value is IX_ATM_IDLE_CELLS_CONNID, the
+ * corresponding number of idle cells will be transmitted to the hardware.
+ *
+ */
+typedef struct
+{
+ IxAtmConnId connId; /**< connection Id
+ *
+ * Identifier of VC from which cells are to be transmitted.
+ * When this valus is IX_ATM_IDLE_CELLS_CONNID, this indicates
+ * that the system should transmit the specified number
+ * of idle cells. Unknown connIds result in the transmission
+ * idle cells.
+ */
+ unsigned int numberOfCells; /**< number of cells to transmit
+ *
+ * The number of contiguous cells to schedule from this VC
+ * at this point. The valid range is from 1 to
+ * @a IX_ATM_SCHEDULETABLE_MAXCELLS_PER_ENTRY. This
+ * number can swap over mbufs and pdus. OverSchduling results
+ * in the transmission of idle cells.
+ */
+} IxAtmScheduleTableEntry;
+
+/**
+ * @brief This structure defines a schedule table which gives details
+ * on which data (from which VCs) should be transmitted for a
+ * forthcoming period of time for a particular port and the
+ * order in which that data should be transmitted.
+ *
+ * The schedule table consists of a series of entries each of which
+ * will schedule one or more cells from a particular registered VC.
+ * The total number of cells scheduled and the total number of
+ * entries in the table are also indicated.
+ *
+ */
+typedef struct
+{
+ unsigned tableSize; /**< Number of entries
+ *
+ * Indicates the total number of
+ * entries in the table.
+ */
+ unsigned totalCellSlots; /**< Number of cells
+ *
+ * Indicates the total number of ATM
+ * cells which are scheduled by all the
+ * entries in the table.
+ */
+ IxAtmScheduleTableEntry *table; /**< Pointer to schedule entries
+ *
+ * Pointer to an array
+ * containing tableSize entries
+ */
+} IxAtmScheduleTable;
+
+#endif /* IXATMTYPES_H */
+
+/**
+ * @} defgroup IxAtmTypes
+ */
+
+
diff --git a/cpu/ixp/npe/include/IxAtmdAcc.h b/cpu/ixp/npe/include/IxAtmdAcc.h
new file mode 100644
index 0000000..ae7b243
--- /dev/null
+++ b/cpu/ixp/npe/include/IxAtmdAcc.h
@@ -0,0 +1,1194 @@
+
+/**
+ * @file IxAtmdAcc.h
+ *
+ * @date 07-Nov-2001
+ *
+ * @brief IxAtmdAcc Public API
+ *
+ * This file contains the public API of IxAtmdAcc, related to the
+ * data functions of the component
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/* ------------------------------------------------------
+ Doxygen group definitions
+ ------------------------------------------------------ */
+
+/**
+ *
+ * @defgroup IxAtmdAccAPI IXP400 ATM Driver Access (IxAtmdAcc) API
+ *
+ * @brief The public API for the IXP400 Atm Driver Data component
+ *
+ * IxAtmdAcc is the low level interface by which AAL0/AAL5 and
+ * OAM data gets transmitted to,and received from the Utopia bus.
+ *
+ * For AAL0/AAL5 services transmit and receive connections may
+ * be established independantly for unique combinations of
+ * port,VPI,and VCI.
+ *
+ * Two AAL0 services supporting 48 or 52 byte cell data are provided.
+ * Submitted AAL0 PDUs must be a multiple of the cell data size (48/52).
+ * AAL0_52 is a raw cell service the client must format
+ * the PDU with an ATM cell header (excluding HEC) at the start of
+ * each cell, note that AtmdAcc does not validate the cell headers in
+ * a submitted PDU.
+ *
+ * OAM cells cannot be received over the AAL0 service but instead
+ * are received over a dedicated OAM service.
+ *
+ * For the OAM service an "OAM Tx channel" may be enabled for a port
+ * by establishing a single dedicated OAM Tx connection on that port.
+ * A single "OAM Rx channel" for all ports may be enabled by
+ * establishing a dedicated OAM Rx connection.
+ *
+ * The OAM service allows buffers containing 52 byte OAM F4/F5 cells
+ * to be transmitted and received over the dedicated OAM channels.
+ * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM
+ * service offered by AtmdAcc is a raw cell transport service.
+ * It is assumed that ITU I.610 procedures that make use of this
+ * service are implemented above AtmdAcc.
+ *
+ * Note that the dedicated OAM connections are established on
+ * reserved VPI,VCI, and (in the case of Rx) port values defined below.
+ * These values are used purely to descriminate the dedicated OAM channels
+ * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be
+ * realised for particluar VPI/VCIs by manipulating the VPI,VCI
+ * fields of the ATM cell headers of cells in the buffers passed
+ * to AtmdAcc. Note that AtmdAcc does not validate the cell headers
+ * in a submitted OAM PDU.
+ *
+ *
+ *
+ * This part is related to the User datapath processing
+ *
+ * @{
+ */
+
+#ifndef IXATMDACC_H
+#define IXATMDACC_H
+
+#include "IxAtmTypes.h"
+
+/* ------------------------------------------------------
+ AtmdAcc Data Types definition
+ ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_WARNING
+ *
+ * @brief Warning return code
+ *
+ * This constant is used to tell IxAtmDAcc user about a special case.
+ *
+ */
+#define IX_ATMDACC_WARNING 2
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_BUSY
+ *
+ * @brief Busy return code
+ *
+ * This constant is used to tell IxAtmDAcc user that the request
+ * is correct, but cannot be processed because the IxAtmAcc resources
+ * are already used. The user has to retry its request later
+ *
+ */
+#define IX_ATMDACC_BUSY 3
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_RESOURCES_STILL_ALLOCATED
+ *
+ * @brief Disconnect return code
+ *
+ * This constant is used to tell IxAtmDAcc user that the disconnect
+ * functions are not complete because the resources used by the driver
+ * are not yet released. The user has to retry the disconnect call
+ * later.
+ *
+ */
+#define IX_ATMDACC_RESOURCES_STILL_ALLOCATED 4
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_DEFAULT_REPLENISH_COUNT
+ *
+ * @brief Default resources usage for RxVcFree replenish mechanism
+ *
+ * This constant is used to tell IxAtmDAcc to allocate and use
+ * the minimum of resources for rx free replenish.
+ *
+ * @sa ixAtmdAccRxVcConnect
+ */
+#define IX_ATMDACC_DEFAULT_REPLENISH_COUNT 0
+
+
+/**
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_OAM_TX_VPI
+ *
+ * @brief The reserved value used for the dedicated OAM
+ * Tx connection. This "well known" value is used by atmdAcc and
+ * its clients to dsicriminate the OAM channel, and should be chosen so
+ * that it does not coencide with the VPI value used in an AAL0/AAL5 connection.
+ * Any attempt to connect a service type other than OAM on this VPI will fail.
+ *
+ *
+ */
+#define IX_ATMDACC_OAM_TX_VPI 0
+
+/**
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_OAM_TX_VCI
+ *
+ * @brief The reserved value used for the dedicated OAM
+ * Tx connection. This "well known" value is used by atmdAcc and
+ * its clients to dsicriminate the OAM channel, and should be chosen so
+ * that it does not coencide with the VCI value used in an AAL0/AAL5 connection.
+ * Any attempt to connect a service type other than OAM on this VCI will fail.
+ */
+#define IX_ATMDACC_OAM_TX_VCI 0
+
+
+ /**
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_OAM_RX_PORT
+ *
+ * @brief The reserved dummy PORT used for all dedicated OAM
+ * Rx connections. Note that this is not a real port but must
+ * have a value that lies within the valid range of port values.
+ */
+#define IX_ATMDACC_OAM_RX_PORT IX_UTOPIA_PORT_0
+
+ /**
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_OAM_RX_VPI
+ *
+ * @brief The reserved value value used for the dedicated OAM
+ * Rx connection. This value should be chosen so that it does not
+ * coencide with the VPI value used in an AAL0/AAL5 connection.
+ * Any attempt to connect a service type other than OAM on this VPI will fail.
+ */
+#define IX_ATMDACC_OAM_RX_VPI 0
+
+/**
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_OAM_RX_VCI
+ *
+ * @brief The reserved value value used for the dedicated OAM
+ * Rx connection. This value should be chosen so that it does not
+ * coencide with the VCI value used in an AAL0/AAL5 connection.
+ * Any attempt to connect a service type other than OAM on this VCI will fail.
+ */
+#define IX_ATMDACC_OAM_RX_VCI 0
+
+
+/**
+ * @enum IxAtmdAccPduStatus
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @brief IxAtmdAcc Pdu status :
+ *
+ * IxAtmdAccPduStatus is used during a RX operation to indicate
+ * the status of the received PDU
+ *
+ */
+
+typedef enum
+{
+ IX_ATMDACC_AAL0_VALID = 0, /**< aal0 pdu */
+ IX_ATMDACC_OAM_VALID, /**< OAM pdu */
+ IX_ATMDACC_AAL2_VALID, /**< aal2 pdu @b reserved for future use */
+ IX_ATMDACC_AAL5_VALID, /**< aal5 pdu complete and trailer is valid */
+ IX_ATMDACC_AAL5_PARTIAL, /**< aal5 pdu not complete, trailer is missing */
+ IX_ATMDACC_AAL5_CRC_ERROR, /**< aal5 pdu not complete, crc error/length error */
+ IX_ATMDACC_MBUF_RETURN /**< empty buffer returned to the user */
+} IxAtmdAccPduStatus;
+
+
+/**
+ *
+ * @enum IxAtmdAccAalType
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @brief IxAtmdAcc AAL Service Type :
+ *
+ * IxAtmdAccAalType defines the type of traffic to run on this VC
+ *
+ */
+typedef enum
+{
+ IX_ATMDACC_AAL5, /**< ITU-T AAL5 */
+ IX_ATMDACC_AAL2, /**< ITU-T AAL2 @b reserved for future use */
+ IX_ATMDACC_AAL0_48, /**< AAL0 48 byte payloads (cell header is added by NPE)*/
+ IX_ATMDACC_AAL0_52, /**< AAL0 52 byte cell data (HEC is added by NPE) */
+ IX_ATMDACC_OAM, /**< OAM cell transport service (HEC is added by NPE)*/
+ IX_ATMDACC_MAX_SERVICE_TYPE /**< not a service, used for parameter validation */
+} IxAtmdAccAalType;
+
+/**
+ *
+ * @enum IxAtmdAccClpStatus
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @brief IxAtmdAcc CLP indication
+ *
+ * IxAtmdAccClpStatus defines the CLP status of the current PDU
+ *
+ */
+typedef enum
+{
+ IX_ATMDACC_CLP_NOT_SET = 0, /**< CLP indication is not set */
+ IX_ATMDACC_CLP_SET = 1 /**< CLP indication is set */
+} IxAtmdAccClpStatus;
+
+/**
+ * @typedef IxAtmdAccUserId
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @brief User-supplied Id
+ *
+ * IxAtmdAccUserId is passed through callbacks and allows the
+ * IxAtmdAcc user to identify the source of a call back. The range of
+ * this user-owned Id is [0...2^32-1)].
+ *
+ * The user provides this own Ids on a per-channel basis as a parameter
+ * in a call to @a ixAtmdAccRxVcConnect() or @a ixAtmdAccRxVcConnect()
+ *
+ * @sa ixAtmdAccRxVcConnect
+ * @sa ixAtmdAccTxVcConnect
+ *
+ */
+typedef unsigned int IxAtmdAccUserId;
+
+/* ------------------------------------------------------
+ Part of the IxAtmdAcc interface related to RX traffic
+ ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @brief Rx callback prototype
+ *
+ * IxAtmdAccRxVcRxCallback is the prototype of the Rx callback user
+ * function called once per PDU to pass a receive Pdu to a user on a
+ * partilcular connection. The callback is likely to push the mbufs
+ * to a protocol layer, and recycle the mbufs for a further use.
+ *
+ * @note -This function is called ONLY in the context of
+ * the @a ixAtmdAccRxDispatch() function
+ *
+ * @sa ixAtmdAccRxDispatch
+ * @sa ixAtmdAccRxVcConnect
+ *
+ * @param port @ref IxAtmLogicalPort [in] - the port on which this PDU was received
+ * a logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ * @param userId @ref IxAtmdAccUserId [in] - user Id provided in the call
+ * to @a ixAtmdAccRxVcConnect()
+ * @param status @ref IxAtmdAccPduStatus [in] - an indication about the PDU validity.
+ * In the case of AAL0 the only possibile value is
+ * AAL0_VALID, in this case the client may optionally determine
+ * that an rx timeout occured by checking if the mbuf is
+ * compleletly or only partially filled, the later case
+ * indicating a timeout.
+ * In the case of OAM the only possible value is OAM valid.
+ * The status is set to @a IX_ATMDACC_MBUF_RETURN when
+ * the mbuf is released during a disconnect process.
+ * @param clp @ref IxAtmdAccClpStatus [in] - clp indication for this PDU.
+ * For AAL5/AAL0_48 this information
+ * is set if the clp bit of any rx cell is set
+ * For AAL0-52/OAM the client may inspect the CLP in individual
+ * cell headers in the PDU, and this parameter is set to 0.
+ * @param *mbufPtr @ref IX_OSAL_MBUF [in] - depending on the servive type a pointer to
+ * an mbuf (AAL5/AAL0/OAM) or mbuf chain (AAL5 only),
+ * that comprises the complete PDU data.
+ *
+ * This parameter is guaranteed not to be a null pointer.
+ *
+ */
+typedef void (*IxAtmdAccRxVcRxCallback) (IxAtmLogicalPort port,
+ IxAtmdAccUserId userId,
+ IxAtmdAccPduStatus status,
+ IxAtmdAccClpStatus clp,
+ IX_OSAL_MBUF * mbufPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @brief Callback prototype for free buffer level is low.
+ *
+ * IxAtmdAccRxVcFreeLowCallback is the prototype of the user function
+ * which get called on a per-VC basis, when more mbufs are needed to
+ * continue the ATM data reception. This function is likely to supply
+ * more available mbufs by one or many calls to the replenish function
+ * @a ixAtmdAccRxVcFreeReplenish()
+ *
+ * This function is called when the number of available buffers for
+ * reception is going under the threshold level as defined
+ * in @a ixAtmdAccRxVcFreeLowCallbackRegister()
+ *
+ * This function is called inside an Qmgr dispatch context. No system
+ * resource or interrupt-unsafe feature should be used inside this
+ * callback.
+ *
+ * @sa ixAtmdAccRxVcFreeLowCallbackRegister
+ * @sa IxAtmdAccRxVcFreeLowCallback
+ * @sa ixAtmdAccRxVcFreeReplenish
+ * @sa ixAtmdAccRxVcFreeEntriesQuery
+ * @sa ixAtmdAccRxVcConnect
+ *
+ * @param userId @ref IxAtmdAccUserId [in] - user Id provided in the call
+ * to @a ixAtmdAccRxVcConnect()
+ *
+ * @return None
+ *
+ */
+typedef void (*IxAtmdAccRxVcFreeLowCallback) (IxAtmdAccUserId userId);
+
+/* ------------------------------------------------------
+ Part of the IxAtmdAcc interface related to TX traffic
+ ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @brief Buffer callback prototype.
+ *
+ * This function is called to relinguish ownership of a transmitted
+ * buffer chain to the user.
+ *
+ * @note -In the case of a chained mbuf the AmtdAcc component can
+ * chain many user buffers together and pass ownership to the user in
+ * one function call.
+ *
+ * @param userId @ref IxAtmdAccUserId [in] - user If provided at registration of this
+ * callback.
+ * @param mbufPtr @ref IX_OSAL_MBUF [in] - a pointer to mbufs or chain of mbufs and is
+ * guaranteed not to be a null pointer.
+ *
+ */
+typedef void (*IxAtmdAccTxVcBufferReturnCallback) (IxAtmdAccUserId userId,
+ IX_OSAL_MBUF * mbufPtr);
+
+/* ------------------------------------------------------
+ Part of the IxAtmdAcc interface related to Initialisation
+ ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccInit (void)
+ *
+ * @brief Initialise the IxAtmdAcc Component
+ *
+ * This function initialise the IxAtmdAcc component. This function shall
+ * be called before any other function of the API. Its role is to
+ * initialise all internal resources of the IxAtmdAcc component.
+ *
+ * The ixQmgr component needs to be initialized prior the use of
+ * @a ixAtmdAccInit()
+ *
+ * @param none
+ *
+ * Failing to initilialize the IxAtmdAcc API before any use of it will
+ * result in a failed status.
+ * If the specified component is not present, a success status will still be
+ * returned, however, a warning indicating the NPE to download to is not
+ * present will be issued.
+ *
+ * @return @li IX_SUCCESS initialisation is complete (in case of component not
+ * being present, a warning is clearly indicated)
+ * @return @li IX_FAIL unable to process this request either
+ * because this IxAtmdAcc is already initialised
+ * or some unspecified error has occrred.
+ */
+PUBLIC IX_STATUS ixAtmdAccInit (void);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccShow (void)
+ *
+ * @brief Show IxAtmdAcc configuration on a per port basis
+ *
+ * @param none
+ *
+ * @return none
+ *
+ * @note - Display use printf() and are redirected to stdout
+ */
+PUBLIC void
+ixAtmdAccShow (void);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccStatsShow (void)
+ *
+ * @brief Show all IxAtmdAcc stats
+ *
+ * @param none
+ *
+ * @return none
+ *
+ * @note - Stats display use printf() and are redirected to stdout
+ */
+PUBLIC void
+ixAtmdAccStatsShow (void);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccStatsReset (void)
+ *
+ * @brief Reset all IxAtmdAcc stats
+ *
+ * @param none
+ *
+ * @return none
+ *
+ */
+PUBLIC void
+ixAtmdAccStatsReset (void);
+
+/* ------------------------------------------------------
+ Part of the IxAtmdAcc interface related to RX traffic
+ ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccRxVcConnect (IxAtmLogicalPort port,
+ unsigned int vpi,
+ unsigned int vci,
+ IxAtmdAccAalType aalServiceType,
+ IxAtmRxQueueId rxQueueId,
+ IxAtmdAccUserId userCallbackId,
+ IxAtmdAccRxVcRxCallback rxCallback,
+ unsigned int minimumReplenishCount,
+ IxAtmConnId * connIdPtr,
+ IxAtmNpeRxVcId * npeVcIdPtr )
+ *
+ * @brief Connect to a Aal Pdu receive service for a particular
+ * port/vpi/vci, and service type.
+ *
+ * This function allows a user to connect to an Aal5/Aal0/OAM Pdu receive service
+ * for a particular port/vpi/vci. It registers the callback and allocates
+ * internal resources and a Connection Id to be used in further API calls
+ * related to this VCC.
+ *
+ * The function will setup VC receive service on the specified rx queue.
+ *
+ * This function is blocking and makes use internal locks, and hence
+ * should not be called from an interrupt context.
+ *
+ * On return from @a ixAtmdAccRxVcConnect() with a failure status, the
+ * connection Id parameter is unspecified. Its value cannot be used.
+ * A connId is the reference by which IxAtmdAcc refers to a
+ * connected VC. This identifier is the result of a succesful call
+ * to a connect function. This identifier is invalid after a
+ * sucessful call to a disconnect function.
+ *
+ * Calling this function for the same combination of Vpi, Vci and more
+ * than once without calling @a ixAtmdAccRxVcTryDisconnect() will result in a
+ * failure status.
+ *
+ * If this function returns success the user should supply receive
+ * buffers by calling @a ixAtmdAccRxVcFreeReplenish() and then call
+ * @a ixAtmdAccRxVcEnable() to begin receiving pdus.
+ *
+ * There is a choice of two receive Qs on which the VC pdus could be
+ * receive. The user must associate the VC with one of these. Essentially
+ * having two qs allows more flexible system configuration such as have
+ * high prioriy traffic on one q (e.g. voice) and low priority traffic on
+ * the other (e.g. data). The high priority Q could be serviced in
+ * preference to the low priority Q. One queue may be configured to be
+ * serviced as soon as there is traffic, the other queue may be configured
+ * to be serviced by a polling mechanism running at idle time.
+ *
+ * Two AAL0 services supporting 48 or 52 byte cell data are provided.
+ * Received AAL0 PDUs will be be a multiple of the cell data size (48/52).
+ * AAL0_52 is a raw cell service and includes an ATM cell header
+ * (excluding HEC) at the start of each cell.
+ *
+ * A single "OAM Rx channel" for all ports may be enabled by
+ * establishing a dedicated OAM Rx connection.
+ *
+ * The OAM service allows buffers containing 52 byte OAM F4/F5 cells
+ * to be transmitted and received over the dedicated OAM channels.
+ * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM
+ * service offered by AtmdAcc is a raw cell transport service.
+ * It is assumed that ITU I.610 procedures that make use of this
+ * service are implemented above AtmdAcc.
+ *
+ * Note that the dedicated OAM connections are established on
+ * reserved VPI,VCI, and (in the case of Rx) port values.
+ * These values are used purely to descriminate the dedicated OAM channels
+ * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be
+ * realised for particluar VPI/VCIs by manipulating the VPI,VCI
+ * fields of the ATM cell headers of cells in the buffers passed
+ * to AtmdAcc.
+ *
+ * Calling this function prior to enable the port will fail.
+ *
+ * @sa ixAtmdAccRxDispatch
+ * @sa ixAtmdAccRxVcEnable
+ * @sa ixAtmdAccRxVcDisable
+ * @sa ixAtmdAccRxVcTryDisconnect
+ * @sa ixAtmdAccPortEnable
+ *
+ * @param port @ref IxAtmLogicalPort [in] - VC identification : logical PHY port
+ * [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ * @param vpi unsigned int [in] - VC identification : ATM Vpi [0..255] or IX_ATMDACC_OAM_VPI
+ * @param vci unsigned int [in] - VC identification : ATM Vci [0..65535] or IX_ATMDACC_OAM_VCI
+ * @param aalServiceType @ref IxAtmdAccAalType [in] - type of service: AAL5, AAL0_48, AAL0_52, or OAM
+ * @param rxQueueId @ref IxAtmRxQueueId [in] - this identifieds which of two Qs the VC
+ * should use.when icoming traffic is processed
+ * @param userCallbackId @ref IxAtmdAccUserId [in] - user Id used later as a parameter to
+ * the supplied rxCallback.
+ * @param rxCallback [in] @ref IxAtmdAccRxVxRxCallback - function called when mbufs are received.
+ * This parameter cannot be a null pointer.
+ * @param bufferFreeCallback [in] - function to be called to return
+ * ownership of buffers to IxAtmdAcc user.
+ * @param minimumReplenishCount unsigned int [in] - For AAL5/AAL0 the number of free mbufs
+ * to be used with this channel. Use a high number when the expected traffic
+ * rate on this channel is high, or when the user's mbufs are small, or when
+ * the RxVcFreeLow Notification has to be invoked less often. When this
+ * value is IX_ATMDACC_DEFAULT_REPLENISH_COUNT, the minimum of
+ * resources will be used. Depending on traffic rate, pdu
+ * size and mbuf size, rxfree queue size, polling/interrupt rate, this value may
+ * require to be replaced by a different value in the range 1-128
+ * For OAM the rxFree queue size is fixed by atmdAcc and this parameter is ignored.
+ * @param connIdPtr @ref IxAtmConnId [out] - pointer to a connection Id
+ * This parameter cannot be a null pointer.
+ * @param npeVcIdPtr @ref IxAtmNpeRxVcId [out] - pointer to an npe Vc Id
+ * This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS successful call to IxAtmdAccRxVcConnect
+ * @return @li IX_ATMDACC_BUSY cannot process this request :
+ * no VC is available
+ * @return @li IX_FAIL
+ * parameter error,
+ * VC already in use,
+ * attempt to connect AAL service on reserved OAM VPI/VCI,
+ * attempt to connect OAM service on VPI/VCI other than the reserved OAM VPI/VCI,
+ * port is not initialised,
+ * or some other error occurs during processing.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxVcConnect (IxAtmLogicalPort port,
+ unsigned int vpi,
+ unsigned int vci,
+ IxAtmdAccAalType aalServiceType,
+ IxAtmRxQueueId rxQueueId,
+ IxAtmdAccUserId userCallbackId,
+ IxAtmdAccRxVcRxCallback rxCallback,
+ unsigned int minimumReplenishCount,
+ IxAtmConnId * connIdPtr,
+ IxAtmNpeRxVcId * npeVcIdPtr );
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccRxVcFreeReplenish (IxAtmConnId connId,
+ IX_OSAL_MBUF * mbufPtr)
+ *
+ * @brief Provide free mbufs for data reception on a connection.
+ *
+ * This function provides mbufs for data reception by the hardware. This
+ * function needs to be called by the user on a regular basis to ensure
+ * no packet loss. Providing free buffers is a connection-based feature;
+ * each connection can have different requirements in terms of buffer size
+ * number of buffers, recycling rate. This function could be invoked from
+ * within the context of a @a IxAtmdAccRxVcFreeLowCallback() callback
+ * for a particular VC
+ *
+ * Mbufs provided through this function call can be chained. They will be
+ * unchained internally. A call to this function with chained mbufs or
+ * multiple calls with unchained mbufs are equivalent, but calls with
+ * unchained mbufs are more efficients.
+ *
+ * Mbufs provided to this interface need to be able to hold at least one
+ * full cell payload (48/52 bytes, depending on service type).
+ * Chained buffers with a size less than the size supported by the hardware
+ * will be returned through the rx callback provided during the connect step.
+ *
+ * Failing to invoke this function prior to enabling the RX traffic
+ * can result in packet loss.
+ *
+ * This function is not reentrant for the same connId.
+ *
+ * This function does not use system resources and can be
+ * invoked from an interrupt context.
+ *
+ * @note - Over replenish is detected, and extra mbufs are returned through
+ * the rx callback provided during the connect step.
+ *
+ * @note - Mbuf provided to the replenish function should have a length greater or
+ * equal to 48/52 bytes according to service type.
+ *
+ * @note - The memory cache of mMbuf payload should be invalidated prior to Mbuf
+ * submission. Flushing the Mbuf headers is handled by IxAtmdAcc.
+ *
+ * @note - When a chained mbuf is provided, this function process the mbufs
+ * up to the hardware limit and invokes the user-supplied callback
+ * to release extra buffers.
+ *
+ * @sa ixAtmdAccRxVcFreeLowCallbackRegister
+ * @sa IxAtmdAccRxVcFreeLowCallback
+ * @sa ixAtmdAccRxVcConnect
+ *
+ * @param connId @ref IxAtmConnId [in] - connection Id as returned from a succesfull call to
+ * @a IxAtmdAccRxVcConnect()
+ * @param mbufPtr @ref IX_OSAL_MBUF [in] - pointer to a mbuf structure to be used for data
+ * reception. The mbuf pointed to by this parameter can be chained
+ * to an other mbuf.
+ *
+ * @return @li IX_SUCCESS successful call to @a ixAtmdAccRxVcFreeReplenish()
+ * and the mbuf is now ready to use for incoming traffic.
+ * @return @li IX_ATMDACC_BUSY cannot process this request because
+ * the max number of outstanding free buffers has been reached
+ * or the internal resources have exhausted for this VC.
+ * The user is responsible for retrying this request later.
+ * @return @li IX_FAIL cannot process this request because of parameter
+ * errors or some unspecified internal error has occurred.
+ *
+ * @note - It is not always guaranteed the replenish step to be as fast as the
+ * hardware is consuming Rx Free mbufs. There is nothing in IxAtmdAcc to
+ * guarantee that replenish reaches the rxFree threshold level. If the
+ * threshold level is not reached, the next rxFree low notification for
+ * this channel will not be triggered.
+ * The preferred ways to replenish can be as follows (depending on
+ * applications and implementations) :
+ * @li Replenish in a rxFree low notification until the function
+ * ixAtmdAccRxVcFreeReplenish() returns IX_ATMDACC_BUSY
+ * @li Query the queue level using @sa ixAtmdAccRxVcFreeEntriesQuery, then
+ * , replenish using @a ixAtmdAccRxVcFreeReplenish(), then query the queue
+ * level again, and replenish if the threshold is still not reached.
+ * @li Trigger replenish from an other event source and use rxFree starvation
+ * to throttle the Rx traffic.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxVcFreeReplenish (IxAtmConnId connId,
+ IX_OSAL_MBUF * mbufPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccRxVcFreeLowCallbackRegister (IxAtmConnId connId,
+ unsigned int numberOfMbufs,
+ IxAtmdAccRxVcFreeLowCallback callback)
+ *
+ * @brief Configure the RX Free threshold value and register a callback
+ * to handle threshold notifications.
+ *
+ * The function ixAtmdAccRxVcFreeLowCallbackRegister sets the threshold value for
+ * a particular RX VC. When the number of buffers reaches this threshold
+ * the callback is invoked.
+ *
+ * This function should be called once per VC before RX traffic is
+ * enabled.This function will fail if the curent level of the free buffers
+ * is equal or less than the threshold value.
+ *
+ * @sa ixAtmdAccRxVcFreeLowCallbackRegister
+ * @sa IxAtmdAccRxVcFreeLowCallback
+ * @sa ixAtmdAccRxVcFreeReplenish
+ * @sa ixAtmdAccRxVcFreeEntriesQuery
+ * @sa ixAtmdAccRxVcConnect
+ *
+ * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call
+ * to @a IxAtmdAccRxVcConnect()
+ * @param numberOfMbufs unsigned int [in] - threshold number of buffers. This number
+ * has to be a power of 2, one of the values 0,1,2,4,8,16,32....
+ * The maximum value cannot be more than half of the rxFree queue
+ * size (which can be retrieved using @a ixAtmdAccRxVcFreeEntriesQuery()
+ * before any use of the @a ixAtmdAccRxVcFreeReplenish() function)
+ * @param callback @ref IxAtmdAccRxVcFreeLowCallback [in] - function telling the user that the number of
+ * free buffers has reduced to the threshold value.
+ *
+ * @return @li IX_SUCCESS Threshold set successfully.
+ * @return @li IX_FAIL parameter error or the current number of free buffers
+ * is less than or equal to the threshold supplied or some
+ * unspecified error has occrred.
+ *
+ * @note - the callback will be called when the threshold level will drop from
+ * exactly (numberOfMbufs + 1) to (numberOfMbufs).
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxVcFreeLowCallbackRegister (IxAtmConnId connId,
+ unsigned int numberOfMbufs,
+ IxAtmdAccRxVcFreeLowCallback callback);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccRxVcFreeEntriesQuery (IxAtmConnId connId,
+ unsigned int *numberOfMbufsPtr)
+ *
+ * @brief Get the number of rx mbufs the system can accept to replenish the
+ * the rx reception mechanism on a particular channel
+ *
+ * The ixAtmdAccRxVcFreeEntriesQuery function is used to retrieve the current
+ * number of available mbuf entries for reception, on a per-VC basis. This
+ * function can be used to know the number of mbufs which can be provided
+ * using @a ixAtmdAccRxVcFreeReplenish().
+ *
+ * This function can be used from a timer context, or can be associated
+ * with a threshold event, or can be used inside an active polling
+ * mechanism which is under user control.
+ *
+ * This function is reentrant and does not use system resources and can
+ * be invoked from an interrupt context.
+ *
+ * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call
+ * to @a IxAtmdAccRxVcConnect()
+ * @param numberOfMbufsPtr unsigned int [out] - Pointer to the number of available entries.
+ * . This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS the current number of mbufs not yet used for incoming traffic
+ * @return @li IX_FAIL invalid parameter
+ *
+ * @sa ixAtmdAccRxVcFreeReplenish
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxVcFreeEntriesQuery (IxAtmConnId connId,
+ unsigned int *numberOfMbufsPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccRxVcEnable (IxAtmConnId connId)
+ *
+ * @brief Start the RX service on a VC.
+ *
+ * This functions kicks-off the traffic reception for a particular VC.
+ * Once invoked, incoming PDUs will be made available by the hardware
+ * and are eventually directed to the @a IxAtmdAccRxVcRxCallback() callback
+ * registered for the connection.
+ *
+ * If the traffic is already running, this function returns IX_SUCCESS.
+ * This function can be invoked many times.
+ *
+ * IxAtmdAccRxVcFreeLowCallback event will occur only after
+ * @a ixAtmdAccRxVcEnable() function is invoked.
+ *
+ * Before using this function, the @a ixAtmdAccRxVcFreeReplenish() function
+ * has to be used to replenish the RX Free queue. If not, incoming traffic
+ * may be discarded.and in the case of interrupt driven reception the
+ * @a IxAtmdAccRxVcFreeLowCallback() callback may be invoked as a side effect
+ * during a replenish action.
+ *
+ * This function is not reentrant and should not be used inside an
+ * interrupt context.
+ *
+ * For an VC connection this function can be called after a call to
+ * @a ixAtmdAccRxVcDisable() and should not be called after
+ * @a ixAtmdAccRxVcTryDisconnect()
+ *
+ * @sa ixAtmdAccRxVcDisable
+ * @sa ixAtmdAccRxVcConnect
+ * @sa ixAtmdAccRxVcFreeReplenish
+ *
+ * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call
+ * to @a IxAtmdAccRxVcConnect()
+ *
+ * @return @li IX_SUCCESS successful call to ixAtmdAccRxVcEnable
+ * @return @li IX_ATMDACC_WARNING the channel is already enabled
+ * @return @li IX_FAIL invalid parameters or some unspecified internal
+ * error occured.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxVcEnable (IxAtmConnId connId);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccRxVcDisable (IxAtmConnId connId)
+ *
+ * @brief Stop the RX service on a VC.
+ *
+ * This functions stops the traffic reception for a particular VC connection.
+ *
+ * Once invoked, incoming Pdus are discarded by the hardware. Any Pdus
+ * pending will be freed to the user
+ *
+ * Hence once this function returns no more receive callbacks will be
+ * called for that VC. However, buffer free callbacks will be invoked
+ * until such time as all buffers supplied by the user have been freed
+ * back to the user
+ *
+ * Calling this function doe not invalidate the connId.
+ * @a ixAtmdAccRxVcEnable() can be invoked to enable Pdu reception again.
+ *
+ * If the traffic is already stopped, this function returns IX_SUCCESS.
+ *
+ * This function is not reentrant and should not be used inside an
+ * interrupt context.
+ *
+ * @sa ixAtmdAccRxVcConnect
+ * @sa ixAtmdAccRxVcEnable
+ * @sa ixAtmdAccRxVcDisable
+ *
+ * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to @a
+ * IxAtmdAccRxVcConnect()
+ *
+ * @return @li IX_SUCCESS successful call to @a ixAtmdAccRxVcDisable().
+ * @return @li IX_ATMDACC_WARNING the channel is already disabled
+ * @return @li IX_FAIL invalid parameters or some unspecified internal error occured
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxVcDisable (IxAtmConnId connId);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccRxVcTryDisconnect (IxAtmConnId connId)
+ *
+ * @brief Disconnect a VC from the RX service.
+ *
+ * This function deregisters the VC and guarantees that all resources
+ * associated with this VC are free. After its execution, the connection
+ * Id is not available.
+ *
+ * This function will fail until such time as all resources allocated to
+ * the VC connection have been freed. The user is responsible to delay and
+ * call again this function many times until a success status is returned.
+ *
+ * This function needs internal locks and should not be called from an
+ * interrupt context
+ *
+ * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to
+ * @a IxAtmdAccRxVcConnect()
+ *
+ * @return @li IX_SUCCESS successful call to ixAtmdAccRxVcDisable
+ * @return @li IX_ATMDACC_RESOURCES_STILL_ALLOCATED not all resources
+ * associated with the connection have been freed.
+ * @return @li IX_FAIL cannot process this request because of a parameter
+ * error
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxVcTryDisconnect (IxAtmConnId connId);
+
+/* ------------------------------------------------------
+ Part of the IxAtmdAcc interface related to TX traffic
+ ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccTxVcConnect (IxAtmLogicalPort port,
+ unsigned int vpi,
+ unsigned int vci,
+ IxAtmdAccAalType aalServiceType,
+ IxAtmdAccUserId userId,
+ IxAtmdAccTxVcBufferReturnCallback bufferFreeCallback,
+ IxAtmConnId * connIdPtr)
+ *
+ * @brief Connect to a Aal Pdu transmit service for a particular
+ * port/vpi/vci and service type.
+ *
+ * This function allows a user to connect to an Aal5/Aal0/OAM Pdu transmit service
+ * for a particular port/vpi/vci. It registers the callback and allocates
+ * internal resources and a Connection Id to be used in further API calls
+ * related to this VC.
+ *
+ * The function will setup VC transmit service on the specified on the
+ * specified port. A connId is the reference by which IxAtmdAcc refers to a
+ * connected VC. This identifier is the result of a succesful call
+ * to a connect function. This identifier is invalid after a
+ * sucessful call to a disconnect function.
+ *
+ * This function needs internal locks, and hence should not be called
+ * from an interrupt context.
+ *
+ * On return from @a ixAtmdAccTxVcConnect() with a failure status, the
+ * connection Id parameter is unspecified. Its value cannot be used.
+ *
+ * Calling this function for the same combination of port, Vpi, Vci and
+ * more than once without calling @a ixAtmdAccTxVcTryDisconnect() will result
+ * in a failure status.
+ *
+ * Two AAL0 services supporting 48 or 52 byte cell data are provided.
+ * Submitted AAL0 PDUs must be a multiple of the cell data size (48/52).
+ * AAL0_52 is a raw cell service the client must format
+ * the PDU with an ATM cell header (excluding HEC) at the start of
+ * each cell, note that AtmdAcc does not validate the cell headers in
+ * a submitted PDU.
+ *
+ * For the OAM service an "OAM Tx channel" may be enabled for a port
+ * by establishing a single dedicated OAM Tx connection on that port.
+ *
+ * The OAM service allows buffers containing 52 byte OAM F4/F5 cells
+ * to be transmitted and received over the dedicated OAM channels.
+ * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM
+ * service offered by AtmdAcc is a raw cell transport service.
+ * It is assumed that ITU I.610 procedures that make use of this
+ * service are implemented above AtmdAcc.
+ *
+ * Note that the dedicated OAM connections are established on
+ * reserved VPI,VCI, and (in the case of Rx) port values.
+ * These values are used purely to descriminate the dedicated OAM channels
+ * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be
+ * realised for particluar VPI/VCIs by manipulating the VPI,VCI
+ * fields of the ATM cell headers of cells in the buffers passed
+ * to AtmdAcc.
+ *
+ * Calling this function before enabling the port will fail.
+ *
+ * @sa ixAtmdAccTxVcTryDisconnect
+ * @sa ixAtmdAccPortTxScheduledModeEnable
+ * @sa ixAtmdAccPortEnable
+ *
+ * @param port @ref IxAtmLogicalPort [in] - VC identification : logical PHY port
+ * [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ * @param vpi unsigned int [in] - VC identification : ATM Vpi [0..255] or IX_ATMDACC_OAM_VPI
+ * @param vci unsigned int [in] - VC identification : ATM Vci [0..65535] or IX_ATMDACC_OAM_VCI
+ * @param aalServiceType @ref IxAtmdAccAalType [in] - type of service AAL5, AAL0_48, AAL0_52, or OAM
+ * @param userId @ref IxAtmdAccUserId [in] - user id to be used later during callbacks related
+ * to this channel
+ * @param bufferFreeCallback @ref IxAtmdAccTxVcBufferReturnCallback [in] - function called when mbufs
+ * transmission is complete. This parameter cannot be a null
+ * pointer.
+ * @param connIdPtr @ref IxAtmConnId [out] - Pointer to a connection Id.
+ * This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS successful call to @a IxAtmdAccRxVcConnect().
+ * @return @li IX_ATMDACC_BUSY cannot process this request
+ * because no VC is available
+ * @return @li IX_FAIL
+ * parameter error,
+ * VC already in use,
+ * attempt to connect AAL service on reserved OAM VPI/VCI,
+ * attempt to connect OAM service on VPI/VCI other than the reserved OAM VPI/VCI,
+ * port is not initialised,
+ * or some other error occurs during processing.
+ *
+ * @note - Unscheduled mode is not supported in ixp425 1.0. Therefore, the
+ * function @a ixAtmdAccPortTxScheduledModeEnable() need to be called
+ * for this port before any establishing a Tx Connection
+ */
+PUBLIC IX_STATUS ixAtmdAccTxVcConnect (IxAtmLogicalPort port,
+ unsigned int vpi,
+ unsigned int vci,
+ IxAtmdAccAalType aalServiceType,
+ IxAtmdAccUserId userId,
+ IxAtmdAccTxVcBufferReturnCallback bufferFreeCallback,
+ IxAtmConnId * connIdPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccTxVcPduSubmit (IxAtmConnId connId,
+ IX_OSAL_MBUF * mbufPtr,
+ IxAtmdAccClpStatus clp,
+ unsigned int numberOfCells)
+ *
+ * @brief Submit a Pdu for transmission on connection.
+ *
+ * A data user calls this function to submit an mbufs containing a Pdu
+ * to be transmitted. The buffer supplied can be chained and the Pdu it
+ * contains must be complete.
+ *
+ * The transmission behavior of this call depends on the operational mode
+ * of the port on which the connection is made.
+ *
+ * In unscheduled mode the mbuf will be submitted to the hardware
+ * immediately if sufficent resource is available. Otherwise the function
+ * will return failure.
+ *
+ * In scheduled mode the buffer is queued internally in IxAtmdAcc. The cell
+ * demand is made known to the traffic shaping entity. Cells from the
+ * buffers are MUXed onto the port some time later as dictated by the
+ * traffic shaping entity. The traffic shaping entity does this by sending
+ * transmit schedules to IxAtmdAcc via @a ixAtmdAccPortTxProcess() function call.
+ *
+ * Note that the dedicated OAM channel is scheduled just like any
+ * other channel. This means that any OAM traffic relating to an
+ * active AAL0/AAL5 connection will be scheduled independantly of the
+ * AAL0/AAL5 traffic for that connection.
+ *
+ * When transmission is complete, the TX Done mechanism will give the
+ * owmnership of these buffers back to the customer. The tx done mechanism
+ * must be in operation before transmission is attempted.
+ *
+ * For AAL0/OAM submitted AAL0 PDUs must be a multiple of the cell data
+ * size (48/52). AAL0_52 and OAM are raw cell services, and the client
+ * must format the PDU with an ATM cell header (excluding HEC) at the
+ * start of each cell, note that AtmdAcc does not validate the cell headers in
+ * a submitted PDU.
+ *
+ *
+ * @sa IxAtmdAccTxVcBufferReturnCallback
+ * @sa ixAtmdAccTxDoneDispatch
+ *
+ * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to
+ * @a ixAtmdAccTxVcConnect()
+ * @param mbufPtr @ref IX_OSAL_MBUF [in] - pointer to a chained structure of mbufs to transmit.
+ * This parameter cannot be a null pointer.
+ * @param clp @ref IxAtmdAccClpStatus [in] - clp indication for this PDU. All cells of this pdu
+ * will be sent with the clp bit set
+ * @param numberOfCells unsigned int [in] - number of cells in the PDU.
+ *
+ * @return @li IX_SUCCESS successful call to @a ixAtmdAccTxVcPduSubmit()
+ * The pdu pointed by the mbufPtr parameter will be
+ * transmitted
+ * @return @li IX_ATMDACC_BUSY unable to process this request because
+ * internal resources are all used. The caller is responsible
+ * for retrying this request later.
+ * @return @li IX_FAIL unable to process this request because of error
+ * in the parameters (wrong connId supplied,
+ * or wrong mbuf pointer supplied), the total length of all buffers
+ * in the chain should be a multiple of the cell size
+ * ( 48/52 depending on the service type ),
+ * or unspecified error during processing
+ *
+ * @note - This function in not re-entrant for the same VC (e.g. : two
+ * thread cannot send PDUs for the same VC). But two threads can
+ * safely call this function with a different connection Id
+ *
+ * @note - In unscheduled mode, this function is not re-entrant on a per
+ * port basis. The size of pdus is limited to 8Kb.
+ *
+ * @note - 0-length mbufs should be removed from the chain before submission.
+ * The total length of the pdu (sdu + padding +trailer) has to be
+ * updated in the header of the first mbuf of a chain of mbufs.
+ *
+ * @note - Aal5 trailer information (UUI, CPI, SDU length) has to be supplied
+ * before submission.
+ *
+ * @note - The payload memory cache should be flushed, if needed, prior to
+ * transmission. Mbuf headers are flushed by IxAtmdAcc
+ *
+ * @note - This function does not use system resources and can be used
+ * inside an interrupt context
+ */
+PUBLIC IX_STATUS ixAtmdAccTxVcPduSubmit (IxAtmConnId connId,
+ IX_OSAL_MBUF * mbufPtr,
+ IxAtmdAccClpStatus clp,
+ unsigned int numberOfCells);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccTxVcTryDisconnect (IxAtmConnId connId)
+ *
+ * @brief Disconnect from a Aal Pdu transmit service for a particular
+ * port/vpi/vci.
+ *
+ * This function deregisters the VC and guarantees that all resources
+ * associated with this VC are free. After its execution, the connection
+ * Id is not available.
+ *
+ * This function will fail until such time as all resources allocated to
+ * the VC connection have been freed. The user is responsible to delay
+ * and call again this function many times until a success status is
+ * returned.
+ *
+ * After its execution, the connection Id is not available.
+ *
+ * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to
+ * @a ixAtmdAccTxVcConnect()
+ *
+ * @return @li IX_SUCCESS successful call to @a ixAtmdAccTxVcTryDisconnect()
+ * @return @li IX_ATMDACC_RESOURCES_STILL_ALLOCATED not all resources
+ * associated with the connection have been freed. This condition will
+ * disappear after Tx and TxDone is complete for this channel.
+ * @return @li IX_FAIL unable to process this request because of errors
+ * in the parameters (wrong connId supplied)
+ *
+ * @note - This function needs internal locks and should not be called
+ * from an interrupt context
+ *
+ * @note - If the @a IX_ATMDACC_RESOURCES_STILL_ALLOCATED error does not
+ * clear after a while, this may be linked to a previous problem
+ * of cell overscheduling. Diabling the port and retry a disconnect
+ * will free the resources associated with this channel.
+ *
+ * @sa ixAtmdAccPortTxProcess
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccTxVcTryDisconnect (IxAtmConnId connId);
+
+#endif /* IXATMDACC_H */
+
+/**
+ * @} defgroup IxAtmdAccAPI
+ */
+
+
diff --git a/cpu/ixp/npe/include/IxAtmdAccCtrl.h b/cpu/ixp/npe/include/IxAtmdAccCtrl.h
new file mode 100644
index 0000000..e223049
--- /dev/null
+++ b/cpu/ixp/npe/include/IxAtmdAccCtrl.h
@@ -0,0 +1,1958 @@
+
+/**
+ * @file IxAtmdAccCtrl.h
+ *
+ * @date 20-Mar-2002
+ *
+ * @brief IxAtmdAcc Public API
+ *
+ * This file contains the public API of IxAtmdAcc, related to the
+ * control functions of the component.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/* ------------------------------------------------------
+ Doxygen group definitions
+ ------------------------------------------------------ */
+
+/**
+ *
+ * @defgroup IxAtmdAccCtrlAPI IXP400 ATM Driver Access (IxAtmdAcc) Control API
+ *
+ * @brief The public API for the IXP400 Atm Driver Control component
+ *
+ * IxAtmdAcc is the low level interface by which AAL PDU get transmitted
+ * to,and received from the Utopia bus
+ *
+ * This part is related to the Control configuration
+ *
+ * @{
+ */
+
+#ifndef IXATMDACCCTRL_H
+#define IXATMDACCCTRL_H
+
+#include "IxAtmdAcc.h"
+
+/* ------------------------------------------------------
+ AtmdAccCtrl Data Types definition
+ ------------------------------------------------------ */
+
+/**
+*
+* @ingroup IxAtmdAccCtrlAPI
+*
+* @def IX_ATMDACC_PORT_DISABLE_IN_PROGRESS
+*
+* @brief Port enable return code
+*
+* This constant is used to tell IxAtmDAcc user that the port disable
+* functions are not complete. The user can call ixAtmdAccPortDisableComplete()
+* to find out when the disable has finished. The port enable can then proceed.
+*
+*/
+#define IX_ATMDACC_PORT_DISABLE_IN_PROGRESS 5
+
+/**
+*
+* @ingroup IxAtmdAccCtrlAPI
+*
+* @def IX_ATMDACC_ALLPDUS
+*
+* @brief All PDUs
+*
+* This constant is used to tell IxAtmDAcc to process all PDUs from
+* the RX queue or the TX Done
+*
+* @sa IxAtmdAccRxDispatcher
+* @sa IxAtmdAccTxDoneDispatcher
+*
+*/
+#define IX_ATMDACC_ALLPDUS 0xffffffff
+
+/* ------------------------------------------------------
+ Part of the IxAtmdAcc interface related to RX traffic
+ ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @brief Callback prototype for notification of available PDUs for
+ * an Rx Q.
+ *
+ * This a protoype for a function which is called when there is at
+ * least one Pdu available for processing on a particular Rx Q.
+ *
+ * This function should call @a ixAtmdAccRxDispatch() with
+ * the aprropriate number of parameters to read and process the Rx Q.
+ *
+ * @sa ixAtmdAccRxDispatch
+ * @sa ixAtmdAccRxVcConnect
+ * @sa ixAtmdAccRxDispatcherRegister
+ *
+ * @param rxQueueId @ref IxAtmRxQueueId [in] indicates which RX queue to has Pdus to process.
+ * @param numberOfPdusToProcess unsigned int [in] indicates the minimum number of
+ * PDUs available to process all PDUs from the queue.
+ * @param reservedPtr unsigned int* [out] pointer to a int location which can
+ * be written to, but does not retain written values. This is
+ * provided to make this prototype compatible
+ * with @a ixAtmdAccRxDispatch()
+ *
+ * @return @li int - ignored.
+ *
+ */
+typedef IX_STATUS (*IxAtmdAccRxDispatcher) (IxAtmRxQueueId rxQueueId,
+ unsigned int numberOfPdusToProcess,
+ unsigned int *reservedPtr);
+
+/* ------------------------------------------------------
+ Part of the IxAtmdAcc interface related to TX traffic
+ ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @brief Callback prototype for transmitted mbuf when threshold level is
+ * crossed.
+ *
+ * IxAtmdAccTxDoneDispatcher is the prototype of the user function
+ * which get called when pdus are completely transmitted. This function
+ * is likely to call the @a ixAtmdAccTxDoneDispatch() function.
+ *
+ * This function is called when the number of available pdus for
+ * reception is crossing the threshold level as defined
+ * in @a ixAtmdAccTxDoneDispatcherRegister()
+ *
+ * This function is called inside an Qmgr dispatch context. No system
+ * resource or interrupt-unsafe feature should be used inside this
+ * callback.
+ *
+ * Transmitted buffers recycling implementation is a sytem-wide mechanism
+ * and needs to be set before any traffic is started. If this threshold
+ * mechanism is not used, the user is responsible for polling the
+ * transmitted buffers with @a ixAtmdAccTxDoneDispatch()
+ * and @a ixAtmdAccTxDoneLevelQuery() functions.
+ *
+ * @sa ixAtmdAccTxDoneDispatcherRegister
+ * @sa ixAtmdAccTxDoneDispatch
+ * @sa ixAtmdAccTxDoneLevelQuery
+ *
+ * @param numberOfPdusToProcess unsigned int [in] - The current number of pdus currently
+ * available for recycling
+ * @param *reservedPtr unsigned int [out] - pointer to a int location which can be
+ * written to but does not retain written values. This is provided
+ * to make this prototype compatible
+ * with @a ixAtmdAccTxDoneDispatch()
+ *
+ * @return @li IX_SUCCESS This is provided to make
+ * this prototype compatible with @a ixAtmdAccTxDoneDispatch()
+ * @return @li IX_FAIL invalid parameters or some unspecified internal
+ * error occured. This is provided to make
+ * this prototype compatible with @a ixAtmdAccTxDoneDispatch()
+ *
+ */
+typedef IX_STATUS (*IxAtmdAccTxDoneDispatcher) (unsigned int numberOfPdusToProcess,
+ unsigned int *reservedPtr);
+
+/**
+*
+* @ingroup IxAtmdAccCtrlAPI
+*
+* @brief Notification that the threshold number of scheduled cells
+* remains in a port's transmit Q.
+*
+* The is the prototype for of the user notification function which
+* gets called on a per-port basis, when the number of remaining
+* scheduled cells to be transmitted decreases to the threshold level.
+* The number of cells passed as a parameter can be used for scheduling
+* purposes as the maximum number of cells that can be passed in a
+* schedule table to the @a ixAtmdAccPortTxProcess() function.
+*
+* @sa ixAtmdAccPortTxCallbackRegister
+* @sa ixAtmdAccPortTxProcess
+* @sa ixAtmdAccPortTxFreeEntriesQuery
+*
+* @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+* @param numberOfAvailableCells unsigned int [in] - number of available
+* cell entries.for the port
+*
+* @note - This functions shall not use system resources when used
+* inside an interrupt context.
+*
+*/
+typedef void (*IxAtmdAccPortTxLowCallback) (IxAtmLogicalPort port,
+ unsigned int numberOfAvailableCells);
+
+/**
+*
+* @ingroup IxAtmdAccCtrlAPI
+*
+* @brief Prototype to submit cells for transmission
+*
+* IxAtmdAccTxVcDemandUpdateCallback is the prototype of the callback
+* function used by AtmD to notify an ATM Scheduler that the user of
+* a VC has submitted cells for transmission.
+*
+* @sa IxAtmdAccTxVcDemandUpdateCallback
+* @sa IxAtmdAccTxVcDemandClearCallback
+* @sa IxAtmdAccTxSchVcIdGetCallback
+* @sa ixAtmdAccPortTxScheduledModeEnable
+*
+* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be updated
+* is established
+* @param vcId int [in] - Identifies the VC to be updated. This is the value
+* returned by the @a IxAtmdAccTxSchVcIdGetCallback() call .
+* @param numberOfCells unsigned int [in] - Indicates how many ATM cells should be added
+* to the queue for this VC.
+*
+* @return @li IX_SUCCESS the function is registering the cell demand for
+* this VC.
+* @return @li IX_FAIL the function cannot register cell for this VC : the
+* scheduler maybe overloaded or misconfigured
+*
+*/
+typedef IX_STATUS (*IxAtmdAccTxVcDemandUpdateCallback) (IxAtmLogicalPort port,
+ int vcId,
+ unsigned int numberOfCells);
+
+/**
+*
+* @ingroup IxAtmdAccCtrlAPI
+*
+* @brief prototype to remove all currently queued cells from a
+* registered VC
+*
+* IxAtmdAccTxVcDemandClearCallback is the prototype of the function
+* to remove all currently queued cells from a registered VC. The
+* pending cell count for the specified VC is reset to zero. After the
+* use of this callback, the scheduler shall not schedule more cells
+* for this VC.
+*
+* This callback function is called during a VC disconnection
+* @a ixAtmdAccTxVcTryDisconnect()
+*
+* @sa IxAtmdAccTxVcDemandUpdateCallback
+* @sa IxAtmdAccTxVcDemandClearCallback
+* @sa IxAtmdAccTxSchVcIdGetCallback
+* @sa ixAtmdAccPortTxScheduledModeEnable
+* @sa ixAtmdAccTxVcTryDisconnect
+*
+* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be cleared
+* is established
+* @param vcId int [in] - Identifies the VC to be cleared. This is the value
+* returned by the @a IxAtmdAccTxSchVcIdGetCallback() call .
+*
+* @return none
+*
+*/
+typedef void (*IxAtmdAccTxVcDemandClearCallback) (IxAtmLogicalPort port,
+ int vcId);
+
+/**
+*
+* @ingroup IxAtmdAccCtrlAPI
+*
+* @brief prototype to get a scheduler vc id
+*
+* IxAtmdAccTxSchVcIdGetCallback is the prototype of the function to get
+* a scheduler vcId
+*
+* @sa IxAtmdAccTxVcDemandUpdateCallback
+* @sa IxAtmdAccTxVcDemandClearCallback
+* @sa IxAtmdAccTxSchVcIdGetCallback
+* @sa ixAtmdAccPortTxScheduledModeEnable
+*
+* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM logical port on which the VC is
+* established
+* @param vpi unsigned int [in] - For AAL0/AAL5 specifies the ATM vpi on which the
+* VC is established.
+* For OAM specifies the dedicated "OAM Tx channel" VPI.
+* @param vci unsigned int [in] - For AAL0/AAL5 specifies the ATM vci on which the
+* VC is established.
+* For OAM specifies the dedicated "OAM Tx channel" VCI.
+* @param connId @ref IxAtmConnId [in] - specifies the IxAtmdAcc connection Id already
+* associated with this VC
+* @param vcId int* [out] - pointer to a vcId
+*
+* @return @li IX_SUCCESS the function is returning a Scheduler vcId for this
+* VC
+* @return @li IX_FAIL the function cannot process scheduling for this VC.
+* the contents of vcId is unspecified
+*
+*/
+typedef IX_STATUS (*IxAtmdAccTxSchVcIdGetCallback) (IxAtmLogicalPort port,
+ unsigned int vpi,
+ unsigned int vci,
+ IxAtmConnId connId,
+ int *vcId);
+
+/* ------------------------------------------------------
+ Part of the IxAtmdAcc interface related to RX traffic
+ ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccRxDispatcherRegister (
+ IxAtmRxQueueId queueId,
+ IxAtmdAccRxDispatcher callback)
+ *
+ * @brief Register a notification callback to be invoked when there is
+ * at least one entry on a particular Rx queue.
+ *
+ * This function registers a callback to be invoked when there is at
+ * least one entry in a particular queue. The registered callback is
+ * called every time when the hardware adds one or more pdus to the
+ * specified Rx queue.
+ *
+ * This function cannot be used when a Rx Vc using this queue is
+ * already existing.
+ *
+ * @note -The callback function can be the API function
+ * @a ixAtmdAccRxDispatch() : every time the threhold level
+ * of the queue is reached, the ixAtmdAccRxDispatch() is
+ * invoked to remove all entries from the queue.
+ *
+ * @sa ixAtmdAccRxDispatch
+ * @sa IxAtmdAccRxDispatcher
+ *
+ * @param queueId @ref IxAtmRxQueueId [in] RX queue identification
+ * @param callback @ref IxAtmdAccRxDispatcher [in] function triggering the delivery of incoming
+ * traffic. This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS Successful call to @a ixAtmdAccRxDispatcherRegister()
+ * @return @li IX_FAIL error in the parameters, or there is an
+ * already active RX VC for this queue or some unspecified
+ * internal error occurred.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxDispatcherRegister (
+ IxAtmRxQueueId queueId,
+ IxAtmdAccRxDispatcher callback);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccRxDispatch (IxAtmRxQueueId rxQueueId,
+ unsigned int numberOfPdusToProcess,
+ unsigned int *numberOfPdusProcessedPtr)
+ *
+ *
+ * @brief Control function which executes Rx processing for a particular
+ * Rx stream.
+ *
+ * The @a IxAtmdAccRxDispatch() function is used to process received Pdus
+ * available from one of the two incoming RX streams. When this function
+ * is invoked, the incoming traffic (up to the number of PDUs passed as
+ * a parameter) will be transferred to the IxAtmdAcc users through the
+ * callback @a IxAtmdAccRxVcRxCallback(), as registered during the
+ * @a ixAtmdAccRxVcConnect() call.
+ *
+ * The user receive callbacks will be executed in the context of this
+ * function.
+ *
+ * Failing to use this function on a regular basis when there is traffic
+ * will block incoming traffic and can result in Pdus being dropped by
+ * the hardware.
+ *
+ * This should be used to control when received pdus are handed off from
+ * the hardware to Aal users from a particluar stream. The function can
+ * be used from a timer context, or can be registered as a callback in
+ * response to an rx stream threshold event, or can be used inside an
+ * active polling mechanism which is under user control.
+ *
+ * @note - The signature of this function is directly compatible with the
+ * callback prototype which can be register with @a ixAtmdAccRxDispatcherRegister().
+ *
+ * @sa ixAtmdAccRxDispatcherRegister
+ * @sa IxAtmdAccRxVcRxCallback
+ * @sa ixAtmdAccRxVcFreeEntriesQuery
+ *
+ * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which RX queue to process.
+ * @param numberOfPdusToProcess unsigned int [in] - indicates the maxiumum number of PDU to
+ * remove from the RX queue. A value of IX_ATMDACC_ALLPDUS indicates
+ * to process all PDUs from the queue. This includes at least the PDUs
+ * in the queue when the fuction is invoked. Because of real-time
+ * constraints, there is no guarantee thatthe queue will be empty
+ * when the function exits. If this parameter is greater than the
+ * number of entries of the queues, the function will succeed
+ * and the parameter numberOfPdusProcessedPtr will reflect the exact
+ * number of PDUs processed.
+ * @param *numberOfPdusProcessedPtr unsigned int [out] - indicates the actual number of PDU
+ * processed during this call. This parameter cannot be a null
+ * pointer.
+ *
+ * @return @li IX_SUCCESS the number of PDUs as indicated in
+ * numberOfPdusProcessedPtr are removed from the RX queue and the VC callback
+ * are called.
+ * @return @li IX_FAIL invalid parameters or some unspecified internal
+ * error occured.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxDispatch (IxAtmRxQueueId rxQueueId,
+ unsigned int numberOfPdusToProcess,
+ unsigned int *numberOfPdusProcessedPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccRxLevelQuery (IxAtmRxQueueId rxQueueId,
+ unsigned int *numberOfPdusPtr)
+ *
+ * @brief Query the number of entries in a particular RX queue.
+ *
+ * This function is used to retrieve the number of pdus received by
+ * the hardware and ready for distribution to users.
+ *
+ * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which of two RX queues to query.
+ * @param numberOfPdusPtr unsigned int* [out] - Pointer to store the number of available
+ * PDUs in the RX queue. This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS the value in numberOfPdusPtr specifies the
+ * number of incoming pdus waiting in this queue
+ * @return @li IX_FAIL an error occurs during processing.
+ * The value in numberOfPdusPtr is unspecified.
+ *
+ * @note - This function is reentrant, doesn't use system resources
+ * and can be used from an interrupt context.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxLevelQuery (IxAtmRxQueueId rxQueueId,
+ unsigned int *numberOfPdusPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccRxQueueSizeQuery (IxAtmRxQueueId rxQueueId,
+ unsigned int *numberOfPdusPtr)
+ *
+ * @brief Query the size of a particular RX queue.
+ *
+ * This function is used to retrieve the number of pdus the system is
+ * able to queue when reception is complete.
+ *
+ * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which of two RX queues to query.
+ * @param numberOfPdusPtr unsigned int* [out] - Pointer to store the number of pdus
+ * the system is able to queue in the RX queue. This parameter
+ * cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS the value in numberOfPdusPtr specifies the
+ * number of pdus the system is able to queue.
+ * @return @li IX_FAIL an error occurs during processing.
+ * The value in numberOfPdusPtr is unspecified.
+ *
+ * @note - This function is reentrant, doesn't use system resources
+ * and can be used from an interrupt context.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxQueueSizeQuery (IxAtmRxQueueId rxQueueId,
+ unsigned int *numberOfPdusPtr);
+
+/* ------------------------------------------------------
+ Part of the IxAtmdAcc interface related to TX traffic
+ ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccPortTxFreeEntriesQuery (IxAtmLogicalPort port,
+ unsigned int *numberOfCellsPtr)
+ *
+ * @brief Get the number of available cells the system can accept for
+ * transmission.
+ *
+ * The function is used to retrieve the number of cells that can be
+ * queued for transmission to the hardware.
+ *
+ * This number is based on the worst schedule table where one cell
+ * is stored in one schedule table entry, depending on the pdus size
+ * and mbuf size and fragmentation.
+ *
+ * This function doesn't use system resources and can be used from a
+ * timer context, or can be associated with a threshold event, or can
+ * be used inside an active polling mechanism
+ *
+ * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ * @param numberOfCellsPtr unsigned int* [out] - number of available cells.
+ * This parameter cannot be a null pointer.
+ *
+ * @sa ixAtmdAccPortTxProcess
+ *
+ * @return @li IX_SUCCESS numberOfCellsPtr contains the number of cells that can be scheduled
+ * for this port.
+ * @return @li IX_FAIL error in the parameters, or some processing error
+ * occured.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccPortTxFreeEntriesQuery (IxAtmLogicalPort port,
+ unsigned int *numberOfCellsPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccPortTxCallbackRegister (IxAtmLogicalPort port,
+ unsigned int numberOfCells,
+ IxAtmdAccPortTxLowCallback callback)
+ *
+ * @brief Configure the Tx port threshold value and register a callback to handle
+ * threshold notifications.
+ *
+ * This function sets the threshold in cells
+ *
+ * @sa ixAtmdAccPortTxCallbackRegister
+ * @sa ixAtmdAccPortTxProcess
+ * @sa ixAtmdAccPortTxFreeEntriesQuery
+ *
+ * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ * @param numberOfCells unsigned int [in] - threshold value which triggers the callback
+ * invocation, This number has to be one of the
+ * values 0,1,2,4,8,16,32 ....
+ * The maximum value cannot be more than half of the txVc queue
+ * size (which can be retrieved using @a ixAtmdAccPortTxFreeEntriesQuery()
+ * before any Tx traffic is sent for this port)
+ * @param callback @ref IxAtmdAccPortTxLowCallback [in] - callback function to invoke when the threshold
+ * level is reached.
+ * This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS Successful call to @a ixAtmdAccPortTxCallbackRegister()
+ * @return @li IX_FAIL error in the parameters, Tx channel already set for this port
+ * threshold level is not correct or within the range regarding the
+ * queue size:or unspecified error during processing:
+ *
+ * @note - This callback function get called when the threshold level drops from
+ * (numberOfCells+1) cells to (numberOfCells) cells
+ *
+ * @note - This function should be called during system initialisation,
+ * outside an interrupt context
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccPortTxCallbackRegister (IxAtmLogicalPort port,
+ unsigned int numberOfCells,
+ IxAtmdAccPortTxLowCallback callback);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccPortTxScheduledModeEnable (IxAtmLogicalPort port,
+ IxAtmdAccTxVcDemandUpdateCallback vcDemandUpdateCallback,
+ IxAtmdAccTxVcDemandClearCallback vcDemandClearCallback,
+ IxAtmdAccTxSchVcIdGetCallback vcIdGetCallback)
+ *
+ * @brief Put the port into Scheduled Mode
+ *
+ * This function puts the specified port into scheduled mode of
+ * transmission which means an external s/w entity controls the
+ * transmission of cells on this port. This faciltates traffic shaping on
+ * the port.
+ *
+ * Any buffers submitted on a VC for this port will be queued in IxAtmdAcc.
+ * The transmission of these buffers to and by the hardware will be driven
+ * by a transmit schedule submitted regulary in calls to
+ * @a ixAtmdAccPortTxProcess() by traffic shaping entity.
+ *
+ * The transmit schedule is expected to be dynamic in nature based on
+ * the demand in cells for each VC on the port. Hence the callback
+ * parameters provided to this function allow IxAtmdAcc to inform the
+ * shaping entity of demand changes for each VC on the port.
+ *
+ * By default a port is in Unscheduled Mode so if this function is not
+ * called, transmission of data is done without sheduling rules, on a
+ * first-come, first-out basis.
+ *
+ * Once a port is put in scheduled mode it cannot be reverted to
+ * un-scheduled mode. Note that unscheduled mode is not supported
+ * in ixp425 1.0
+ *
+ * @note - This function should be called before any VCs have be
+ * connected on a port. Otherwise this function call will return failure.
+ *
+ * @note - This function uses internal locks and should not be called from
+ * an interrupt context
+ *
+ * @sa IxAtmdAccTxVcDemandUpdateCallback
+ * @sa IxAtmdAccTxVcDemandClearCallback
+ * @sa IxAtmdAccTxSchVcIdGetCallback
+ * @sa ixAtmdAccPortTxProcess
+ *
+ * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ * @param vcDemandUpdateCallback @ref IxAtmdAccTxVcDemandUpdateCallback [in] - callback function used to update
+ * the number of outstanding cells for transmission. This parameter
+ * cannot be a null pointer.
+ * @param vcDemandClearCallback @ref IxAtmdAccTxVcDemandClearCallback [in] - callback function used to remove all
+ * clear the number of outstanding cells for a VC. This parameter
+ * cannot be a null pointer.
+ * @param vcIdGetCallback @ref IxAtmdAccTxSchVcIdGetCallback [in] - callback function used to exchange vc
+ * Identifiers between IxAtmdAcc and the entity supplying the
+ * transmit schedule. This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS scheduler registration is complete and the port
+ * is now in scheduled mode.
+ * @return @li IX_FAIL failed (wrong parameters, or traffic is already
+ * enabled on this port, possibly without ATM shaping)
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccPortTxScheduledModeEnable (IxAtmLogicalPort port,
+ IxAtmdAccTxVcDemandUpdateCallback vcDemandUpdateCallback,
+ IxAtmdAccTxVcDemandClearCallback vcDemandClearCallback,
+ IxAtmdAccTxSchVcIdGetCallback vcIdGetCallback);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccPortTxProcess (IxAtmLogicalPort port,
+ IxAtmScheduleTable* scheduleTablePtr)
+ *
+ * @brief Transmit queue cells to the H/W based on the supplied schedule
+ * table.
+ *
+ * This function @a ixAtmdAccPortTxProcess() process the schedule
+ * table provided as a parameter to the function. As a result cells are
+ * sent to the underlaying hardware for transmission.
+ *
+ * The schedule table is executed in its entirety or not at all. So the
+ * onus is on the caller not to submit a table containing more cells than
+ * can be transmitted at that point. The maximum numbers that can be
+ * transmitted is guaranteed to be the number of cells as returned by the
+ * function @a ixAtmdAccPortTxFreeEntriesQuery().
+ *
+ * When the scheduler is invoked on a threshold level, IxAtmdAcc gives the
+ * minimum number of cells (to ensure the callback will fire again later)
+ * and the maximum number of cells that @a ixAtmdAccPortTxProcess()
+ * will be able to process (assuming the ATM scheduler is able
+ * to produce the worst-case schedule table, i.e. one entry per cell).
+ *
+ * When invoked ouside a threshold level, the overall number of cells of
+ * the schedule table should be less than the number of cells returned
+ * by the @a ixAtmdAccPortTxFreeEntriesQuery() function.
+ *
+ * After invoking the @a ixAtmdAccPortTxProcess() function, it is the
+ * user choice to query again the queue level with the function
+ * @a ixAtmdAccPortTxFreeEntriesQuery() and, depending on a new cell
+ * number, submit an other schedule table.
+ *
+ * IxAtmdAcc will check that the number of cells in the schedule table
+ * is compatible with the current transmit level. If the
+ *
+ * Obsolete or invalid connection Id will be silently discarded.
+ *
+ * This function is not reentrant for the same port.
+ *
+ * This functions doesn't use system resources and can be used inside an
+ * interrupt context.
+ *
+ * This function is used as a response to the hardware requesting more
+ * cells to transmit.
+ *
+ * @sa ixAtmdAccPortTxScheduledModeEnable
+ * @sa ixAtmdAccPortTxFreeEntriesQuery
+ * @sa ixAtmdAccPortTxCallbackRegister
+ * @sa ixAtmdAccPortEnable
+ *
+ * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ * @param scheduleTablePtr @ref IxAtmScheduleTable* [in] - pointer to a scheduler update table. The
+ * content of this table is not modified by this function. This
+ * parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS the schedule table process is complete
+ * and cells are transmitted to the hardware
+ * @return @li IX_ATMDACC_WARNING : Traffic will be dropped: the schedule table exceed
+ * the hardware capacity If this error is ignored, further traffic
+ * and schedule will work correctly.
+ * Overscheduling does not occur when the schedule table does
+ * not contain more entries that the number of free entries returned
+ * by @a ixAtmdAccPortTxFreeEntriesQuery().
+ * However, Disconnect attempts just after this error will fail permanently
+ * with the error code @a IX_ATMDACC_RESOURCES_STILL_ALLOCATED, and it is
+ * necessary to disable the port to make @a ixAtmdAccTxVcTryDisconnect()
+ * successful.
+ * @return @li IX_FAIL a wrong parameter is supplied, or the format of
+ * the schedule table is invalid, or the port is not Enabled, or
+ * an internal severe error occured. No cells is transmitted to the hardware
+ *
+ * @note - If the failure is linked to an overschedule of data cells
+ * the result is an inconsistency in the output traffic (one or many
+ * cells may be missing and the traffic contract is not respected).
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccPortTxProcess (IxAtmLogicalPort port,
+ IxAtmScheduleTable* scheduleTablePtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccTxDoneDispatch (unsigned int numberOfPdusToProcess,
+ unsigned int *numberOfPdusProcessedPtr)
+ *
+ * @brief Process a number of pending transmit done pdus from the hardware.
+ *
+ * As a by-product of Atm transmit operation buffers which transmission
+ * is complete need to be recycled to users. This function is invoked
+ * to service the oustanding list of transmitted buffers and pass them
+ * to VC users.
+ *
+ * Users are handed back pdus by invoking the free callback registered
+ * during the @a ixAtmdAccTxVcConnect() call.
+ *
+ * There is a single Tx done stream servicing all active Atm Tx ports
+ * which can contain a maximum of 64 entries. If this stream fills port
+ * transmission will stop so this function must be call sufficently
+ * frequently to ensure no disruption to the transmit operation.
+ *
+ * This function can be used from a timer context, or can be associated
+ * with a TxDone level threshold event (see @a ixAtmdAccTxDoneDispatcherRegister() ),
+ * or can be used inside an active polling mechanism under user control.
+ *
+ * For ease of use the signature of this function is compatible with the
+ * TxDone threshold event callback prototype.
+ *
+ * This functions can be used inside an interrupt context.
+ *
+ * @sa ixAtmdAccTxDoneDispatcherRegister
+ * @sa IxAtmdAccTxVcBufferReturnCallback
+ * @sa ixAtmdAccTxDoneLevelQuery
+ *
+ * @param numberOfPdusToProcess unsigned int [in] - maxiumum number of pdus to remove
+ * from the TX Done queue
+ * @param *numberOfPdusProcessedPtr unsigned int [out] - number of pdus removed from
+ * the TX Done queue. This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS the number of pdus as indicated in
+ * numberOfPdusToProcess are removed from the TX Done hardware
+ * and passed to the user through the Tx Done callback registered
+ * during a call to @a ixAtmdAccTxVcConnect()
+ * @return @li IX_FAIL invalid parameters or numberOfPdusProcessedPtr is
+ * a null pointer or some unspecified internal error occured.
+ *
+ */
+PUBLIC IX_STATUS
+ixAtmdAccTxDoneDispatch (unsigned int numberOfPdusToProcess,
+ unsigned int *numberOfPdusProcessedPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccTxDoneLevelQuery (unsigned int *numberOfPdusPtr)
+ *
+ * @brief Query the current number of transmit pdus ready for
+ * recycling.
+ *
+ * This function is used to get the number of transmitted pdus which
+ * the hardware is ready to hand back to user.
+ *
+ * This function can be used from a timer context, or can be associated
+ * with a threshold event, on can be used inside an active polling
+ * mechanism
+ *
+ * @sa ixAtmdAccTxDoneDispatch
+ *
+ * @param *numberOfPdusPtr unsigned int [out] - Pointer to the number of pdus transmitted
+ * at the time of this function call, and ready for recycling
+ * This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS numberOfPdusPtr contains the number of pdus
+ * ready for recycling at the time of this function call
+ *
+ * @return @li IX_FAIL wrong parameter (null pointer as parameter).or
+ * unspecified rocessing error occurs..The value in numberOfPdusPtr
+ * is unspecified.
+ *
+ */
+PUBLIC IX_STATUS
+ixAtmdAccTxDoneLevelQuery (unsigned int *numberOfPdusPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccTxDoneQueueSizeQuery (unsigned int *numberOfPdusPtr)
+ *
+ * @brief Query the TxDone queue size.
+ *
+ * This function is used to get the number of pdus which
+ * the hardware is able to store after transmission is complete
+ *
+ * The returned value can be used to set a threshold and enable
+ * a callback to be notified when the number of pdus is going over
+ * the threshold.
+ *
+ * @sa ixAtmdAccTxDoneDispatcherRegister
+ *
+ * @param *numberOfPdusPtr unsigned int [out] - Pointer to the number of pdus the system
+ * is able to queue after transmission
+ *
+ * @return @li IX_SUCCESS numberOfPdusPtr contains the the number of
+ * pdus the system is able to queue after transmission
+ * @return @li IX_FAIL wrong parameter (null pointer as parameter).or
+ * unspecified rocessing error occurs..The value in numberOfPdusPtr
+ * is unspecified.
+ *
+ * @note - This function is reentrant, doesn't use system resources
+ * and can be used from an interrupt context.
+ */
+PUBLIC IX_STATUS
+ixAtmdAccTxDoneQueueSizeQuery (unsigned int *numberOfPdusPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccTxDoneDispatcherRegister (unsigned int numberOfPdus,
+ IxAtmdAccTxDoneDispatcher notificationCallback)
+ *
+ * @brief Configure the Tx Done stream threshold value and register a
+ * callback to handle threshold notifications.
+ *
+ * This function sets the threshold level in term of number of pdus at
+ * which the supplied notification function should be called.
+ *
+ * The higher the threshold value is, the less events will be necessary
+ * to process transmitted buffers.
+ *
+ * Transmitted buffers recycling implementation is a sytem-wide mechanism
+ * and needs to be set prior any traffic is started. If this threshold
+ * mechanism is not used, the user is responsible for polling the
+ * transmitted buffers thanks to @a ixAtmdAccTxDoneDispatch() and
+ * @a ixAtmdAccTxDoneLevelQuery() functions.
+ *
+ * This function should be called during system initialisation outside
+ * an interrupt context
+ *
+ * @sa ixAtmdAccTxDoneDispatcherRegister
+ * @sa ixAtmdAccTxDoneDispatch
+ * @sa ixAtmdAccTxDoneLevelQuery
+ *
+ * @param numberOfPdus unsigned int [in] - The number of TxDone pdus which triggers the
+ * callback invocation This number has to be a power of 2, one of the
+ * values 0,1,2,4,8,16,32 ...
+ * The maximum value cannot be more than half of the txDone queue
+ * size (which can be retrieved using @a ixAtmdAccTxDoneQueueSizeQuery())
+ * @param notificationCallback @ref IxAtmdAccTxDoneDispatcher [in] - The function to invoke. (This
+ * parameter can be @a ixAtmdAccTxDoneDispatch()).This
+ * parameter ust not be a null pointer.
+ *
+ * @return @li IX_SUCCESS Successful call to ixAtmdAccTxDoneDispatcherRegister
+ * @return @li IX_FAIL error in the parameters:
+ *
+ * @note - The notificationCallback will be called exactly when the threshold level
+ * will increase from (numberOfPdus) to (numberOfPdus+1)
+ *
+ * @note - If there is no Tx traffic, there is no guarantee that TxDone Pdus will
+ * be released to the user (when txDone level is permanently under the threshold
+ * level. One of the preffered way to return resources to the user is to use
+ * a mix of txDone notifications, used together with a slow
+ * rate timer and an exclusion mechanism protecting from re-entrancy
+ *
+ * @note - The TxDone threshold will only hand back buffers when the threshold level is
+ * crossed. Setting this threshold to a great number reduce the interrupt rate
+ * and the cpu load, but also increase the number of outstanding mbufs and has
+ * a system wide impact when these mbufs are needed by other components.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccTxDoneDispatcherRegister (unsigned int numberOfPdus,
+ IxAtmdAccTxDoneDispatcher notificationCallback);
+
+/* ------------------------------------------------------
+ Part of the IxAtmdAcc interface related to Utopia config
+ ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @defgroup IxAtmdAccUtopiaCtrlAPI IXP400 ATM Driver Access (IxAtmdAcc) Utopia Control API
+ *
+ * @brief The public API for the IXP400 Atm Driver Control component
+ *
+ * IxAtmdAcc is the low level interface by which AAL PDU get
+ * transmitted to,and received from the Utopia bus
+ *
+ * This part is related to the UTOPIA configuration.
+ *
+ * @{
+ */
+
+/**
+ *
+ * @brief Utopia configuration
+ *
+ * This structure is used to set the Utopia parameters
+ * @li contains the values of Utopia registers, to be set during initialisation
+ * @li contains debug commands for NPE, to be used during development steps
+ *
+ * @note - the exact description of all parameters is done in the Utopia reference
+ * documents.
+ *
+ */
+typedef struct
+{
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtTxConfig_
+ * @brief Utopia Tx Config Register
+ */
+ struct UtTxConfig_
+ {
+
+ unsigned int reserved_1:1; /**< [31] These bits are always 0.*/
+ unsigned int txInterface:1; /**< [30] Utopia Transmit Interface. The following encoding
+ * is used to set the Utopia Transmit interface as ATM master
+ * or PHY slave:
+ * @li 1 - PHY
+ * @li 0 - ATM
+ */
+ unsigned int txMode:1; /**< [29] Utopia Transmit Mode. The following encoding is used
+ * to set the Utopia Transmit mode to SPHY or MPHY:
+ * @li 1 - SPHY
+ * @li 0 - MPHY
+ */
+ unsigned int txOctet:1; /**< [28] Utopia Transmit cell transfer protocol. Used to set
+ * the Utopia cell transfer protocol to Octet-level handshaking.
+ * Note this is only applicable in SPHY mode.
+ * @li 1 - Octet-handshaking enabled
+ * @li 0 - Cell-handshaking enabled
+ */
+ unsigned int txParity:1; /**< [27] Utopia Transmit parity enabled when set. TxEvenParity
+ * defines the parity format odd/even.
+ * @li 1 - Enable Parity generation.
+ * @li 0 - ut_op_prty held low.
+ */
+ unsigned int txEvenParity:1; /**< [26] Utopia Transmit Parity Mode
+ * @li 1 - Even Parity Generated.
+ * @li 0 - Odd Parity Generated.
+ */
+ unsigned int txHEC:1; /**< [25] Header Error Check Insertion Mode. Specifies if the transmit
+ * cell header check byte is calculated and inserted when set.
+ * @li 1 - Generate HEC.
+ * @li 0 - Disable HEC generation.
+ */
+ unsigned int txCOSET:1; /**< [24] If enabled the HEC is Exclusive-ORÆed with the value 0x55 before
+ * being presented on the Utopia bus.
+ * @li 1 - Enable HEC ExOR with value 0x55
+ * @li 0 - Use generated HEC value.
+ */
+
+ unsigned int reserved_2:1; /**< [23] These bits are always 0
+ */
+ unsigned int txCellSize:7; /**< [22:16] Transmit expected cell size. Configures the cell size
+ * for the transmit module: Values between 52-64 are valid.
+ */
+ unsigned int reserved_3:3; /**< [15:13] These bits are always 0 */
+ unsigned int txAddrRange:5; /**< [12:8] When configured as an ATM master in MPHY mode this
+ * register specifies the upper limit of the PHY polling logical
+ * range. The number of active PHYs are TxAddrRange + 1.
+ */
+ unsigned int reserved_4:3; /**< [7:5] These bits are always 0 */
+ unsigned int txPHYAddr:5; /**< [4:0] When configured as a slave in an MPHY system this register
+ * specifies the physical address of the PHY.
+ */
+ }
+
+ utTxConfig; /**< Tx config Utopia register */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtTxStatsConfig_
+ * @brief Utopia Tx stats Register
+ */
+ struct UtTxStatsConfig_
+ {
+
+ unsigned int vpi:12; /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0]
+ @li Note: if VCStatsTxGFC is set to 0 the GFC field is ignored in test. */
+
+ unsigned int vci:16; /**< [19:4] ATM VCI [15:0] or PHY Address[4] */
+
+ unsigned int pti:3; /**< [3:1] ATM PTI [2:0] or PHY Address[3:1]
+ @li Note: if VCStatsTxPTI is set to 0 the PTI field is ignored in test.
+ @li Note: if VCStatsTxEnb is set to 0 only the transmit PHY port
+ address as defined by this register is used for ATM statistics [4:0]. */
+
+ unsigned int clp:1; /**< [0] ATM CLP or PHY Address [0]
+ @li Note: if VCStatsTxCLP is set to 0 the CLP field is ignored in test.
+ @li Note: if VCStatsTxEnb is set to 0 only the transmit PHY port
+ address as defined by this register is used for ATM statistics [4:0]. */
+ }
+
+ utTxStatsConfig; /**< Tx stats config Utopia register */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtTxDefineIdle_
+ * @brief Utopia Tx idle cells Register
+ */
+ struct UtTxDefineIdle_
+ {
+
+ unsigned int vpi:12; /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0]
+ @li Note: if VCIdleTxGFC is set to 0 the GFC field is ignored in test. */
+
+ unsigned int vci:16; /**< [19:4] ATM VCI [15:0] */
+
+ unsigned int pti:3; /**< [3:1] ATM PTI PTI [2:0]
+ @li Note: if VCIdleTxPTI is set to 0 the PTI field is ignored in test.*/
+
+ unsigned int clp:1; /**< [0] ATM CLP [0]
+ @li Note: if VCIdleTxCLP is set to 0 the CLP field is ignored in test.*/
+ }
+
+ utTxDefineIdle; /**< Tx idle cell config Utopia register */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtTxEnableFields_
+ * @brief Utopia Tx ienable fields Register
+ */
+ struct UtTxEnableFields_
+ {
+
+ unsigned int defineTxIdleGFC:1; /**< [31] This register is used to include or exclude the GFC
+ field of the ATM header when testing for Idle cells.
+ @li 1 - GFC field is valid.
+ @li 0 - GFC field ignored.*/
+
+ unsigned int defineTxIdlePTI:1; /**< [30] This register is used to include or exclude the PTI
+ field of the ATM header when testing for Idle cells.
+ @li 1 - PTI field is valid
+ @li 0 - PTI field ignored.*/
+
+ unsigned int defineTxIdleCLP:1; /**< [29] This register is used to include or
+ exclude the CLP field of the ATM header when testing for Idle cells.
+ @li 1 - CLP field is valid.
+ @li 0 - CLP field ignored. */
+
+ unsigned int phyStatsTxEnb:1; /**< [28] This register is used to enable or disable ATM
+ statistics gathering based on the specified PHY address as defined
+ in TxStatsConfig register.
+ @li 1 - Enable statistics for specified transmit PHY address.
+ @li 0 - Disable statistics for specified transmit PHY address. */
+
+ unsigned int vcStatsTxEnb:1; /**< [27] This register is used to change the ATM
+ statistics-gathering mode from the specified logical PHY address
+ to a specific VPI/VCI address.
+ @li 1 - Enable statistics for specified VPI/VCI address.
+ @li 0 - Disable statistics for specified VPI/VCI address */
+
+ unsigned int vcStatsTxGFC:1; /**< [26] This register is used to include or exclude the GFC
+ field of the ATM header when ATM VPI/VCI statistics are enabled.
+ GFC is only available at the UNI and uses the first 4-bits of
+ the VPI field.
+ @li 1 - GFC field is valid
+ @li 0 - GFC field ignored.*/
+
+ unsigned int vcStatsTxPTI:1; /**< [25] This register is used to include or exclude the PTI
+ field of the ATM header when ATM VPI/VCI statistics are enabled.
+ @li 1 - PTI field is valid
+ @li 0 - PTI field ignored.*/
+
+ unsigned int vcStatsTxCLP:1; /**< [24] This register is used to include or exclude the CLP
+ field of the ATM header when ATM VPI/VCI statistics are enabled.
+ @li 1 - CLP field is valid
+ @li 0 - CLP field ignored. */
+
+ unsigned int reserved_1:3; /**< [23-21] These bits are always 0 */
+
+ unsigned int txPollStsInt:1; /**< [20] Enable the assertion of the ucp_tx_poll_sts condition
+ where there is a change in polling status.
+ @li 1 - ucp_tx_poll_sts asserted whenever there is a change in status
+ @li 0 - ucp_tx_poll_sts asserted if ANY transmit PHY is available
+ */
+ unsigned int txCellOvrInt:1; /**< [19] Enable TxCellCount overflow CBI Transmit Status condition
+ assertion.
+ @li 1 - If TxCellCountOvr is set assert the Transmit Status Condition.
+ @li 0 - No CBI Transmit Status condition assertion */
+
+ unsigned int txIdleCellOvrInt:1; /**< [18] Enable TxIdleCellCount overflow Transmit Status Condition
+ @li 1 - If TxIdleCellCountOvr is set assert the Transmit Status Condition
+ @li 0 - No CBI Transmit Status condition assertion..*/
+
+ unsigned int enbIdleCellCnt:1; /**< [17] Enable Transmit Idle Cell Count.
+ @li 1 - Enable count of Idle cells transmitted.
+ @li 0 - No count is maintained. */
+
+ unsigned int enbTxCellCnt:1; /**< [16] Enable Transmit Valid Cell Count of non-idle/non-error cells
+ @li 1 - Enable count of valid cells transmitted- non-idle/non-error
+ @li 0 - No count is maintained.*/
+
+ unsigned int reserved_2:16; /**< [15:0] These bits are always 0 */
+ } utTxEnableFields; /**< Tx enable Utopia register */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtTxTransTable0_
+ * @brief Utopia Tx translation table Register
+ */
+ struct UtTxTransTable0_
+ {
+
+ unsigned int phy0:5; /**< [31-27] Tx Mapping value of logical phy 0 */
+
+ unsigned int phy1:5; /**< [26-22] Tx Mapping value of logical phy 1 */
+
+ unsigned int phy2:5; /**< [21-17] Tx Mapping value of logical phy 2 */
+
+ unsigned int reserved_1:1; /**< [16] These bits are always 0.*/
+
+ unsigned int phy3:5; /**< [15-11] Tx Mapping value of logical phy 3 */
+
+ unsigned int phy4:5; /**< [10-6] Tx Mapping value of logical phy 4 */
+
+ unsigned int phy5:5; /**< [5-1] Tx Mapping value of logical phy 5 */
+
+ unsigned int reserved_2:1; /**< [0] These bits are always 0 */
+ } utTxTransTable0; /**< Tx translation table */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtTxTransTable1_
+ * @brief Utopia Tx translation table Register
+ */
+ struct UtTxTransTable1_
+ {
+
+ unsigned int phy6:5; /**< [31-27] Tx Mapping value of logical phy 6 */
+
+ unsigned int phy7:5; /**< [26-22] Tx Mapping value of logical phy 7 */
+
+ unsigned int phy8:5; /**< [21-17] Tx Mapping value of logical phy 8 */
+
+ unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */
+
+ unsigned int phy9:5; /**< [15-11] Tx Mapping value of logical phy 3 */
+
+ unsigned int phy10:5; /**< [10-6] Tx Mapping value of logical phy 4 */
+
+ unsigned int phy11:5; /**< [5-1] Tx Mapping value of logical phy 5 */
+
+ unsigned int reserved_2:1; /**< [0] These bits are always 0 */
+ } utTxTransTable1; /**< Tx translation table */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtTxTransTable2_
+ * @brief Utopia Tx translation table Register
+ */
+ struct UtTxTransTable2_
+ {
+
+ unsigned int phy12:5; /**< [31-27] Tx Mapping value of logical phy 6 */
+
+ unsigned int phy13:5; /**< [26-22] Tx Mapping value of logical phy 7 */
+
+ unsigned int phy14:5; /**< [21-17] Tx Mapping value of logical phy 8 */
+
+ unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */
+
+ unsigned int phy15:5; /**< [15-11] Tx Mapping value of logical phy 3 */
+
+ unsigned int phy16:5; /**< [10-6] Tx Mapping value of logical phy 4 */
+
+ unsigned int phy17:5; /**< [5-1] Tx Mapping value of logical phy 5 */
+
+ unsigned int reserved_2:1; /**< [0] These bits are always 0 */
+ } utTxTransTable2; /**< Tx translation table */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtTxTransTable3_
+ * @brief Utopia Tx translation table Register
+ */
+ struct UtTxTransTable3_
+ {
+
+ unsigned int phy18:5; /**< [31-27] Tx Mapping value of logical phy 6 */
+
+ unsigned int phy19:5; /**< [26-22] Tx Mapping value of logical phy 7 */
+
+ unsigned int phy20:5; /**< [21-17] Tx Mapping value of logical phy 8 */
+
+ unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */
+
+ unsigned int phy21:5; /**< [15-11] Tx Mapping value of logical phy 3 */
+
+ unsigned int phy22:5; /**< [10-6] Tx Mapping value of logical phy 4 */
+
+ unsigned int phy23:5; /**< [5-1] Tx Mapping value of logical phy 5 */
+
+ unsigned int reserved_2:1; /**< [0] These bits are always 0 */
+ } utTxTransTable3; /**< Tx translation table */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtTxTransTable4_
+ * @brief Utopia Tx translation table Register
+ */
+ struct UtTxTransTable4_
+ {
+
+ unsigned int phy24:5; /**< [31-27] Tx Mapping value of logical phy 6 */
+
+ unsigned int phy25:5; /**< [26-22] Tx Mapping value of logical phy 7 */
+
+ unsigned int phy26:5; /**< [21-17] Tx Mapping value of logical phy 8 */
+
+ unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */
+
+ unsigned int phy27:5; /**< [15-11] Tx Mapping value of logical phy 3 */
+
+ unsigned int phy28:5; /**< [10-6] Tx Mapping value of logical phy 4 */
+
+ unsigned int phy29:5; /**< [5-1] Tx Mapping value of logical phy 5 */
+
+ unsigned int reserved_2:1; /**< [0] These bits are always 0 */
+ } utTxTransTable4; /**< Tx translation table */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtTxTransTable5_
+ * @brief Utopia Tx translation table Register
+ */
+ struct UtTxTransTable5_
+ {
+
+ unsigned int phy30:5; /**< [31-27] Tx Mapping value of logical phy 6 */
+
+ unsigned int reserved_1:27; /**< [26-0] These bits are always 0 */
+
+ } utTxTransTable5; /**< Tx translation table */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtRxConfig_
+ * @brief Utopia Rx config Register
+ */
+ struct UtRxConfig_
+ {
+
+ unsigned int rxInterface:1; /**< [31] Utopia Receive Interface. The following encoding is used
+ to set the Utopia Receive interface as ATM master or PHY slave:
+ @li 1 - PHY
+ @li 0 - ATM */
+
+ unsigned int rxMode:1; /**< [30] Utopia Receive Mode. The following encoding is used to set
+ the Utopia Receive mode to SPHY or MPHY:
+ @li 1 - SPHY
+ @li 0 - MPHY */
+
+ unsigned int rxOctet:1; /**< [29] Utopia Receive cell transfer protocol. Used to set the Utopia
+ cell transfer protocol to Octet-level handshaking. Note this is only
+ applicable in SPHY mode.
+ @li 1 - Octet-handshaking enabled
+ @li 0 - Cell-handshaking enabled */
+
+ unsigned int rxParity:1; /**< [28] Utopia Receive Parity Checking enable.
+ @li 1 - Parity checking enabled
+ @li 0 - Parity checking disabled */
+
+ unsigned int rxEvenParity:1;/**< [27] Utopia Receive Parity Mode
+ @li 1 - Check for Even Parity
+ @li 0 - Check for Odd Parity.*/
+
+ unsigned int rxHEC:1; /**< [26] RxHEC Header Error Check Mode. Enables/disables cell header
+ error checking on the received cell header.
+ @li 1 - HEC checking enabled
+ @li 0 - HEC checking disabled */
+
+ unsigned int rxCOSET:1; /**< [25] If enabled the HEC is Exclusive-ORÆed with the value 0x55
+ before being tested with the received HEC.
+ @li 1 - Enable HEC ExOR with value 0x55.
+ @li 0 - Use generated HEC value.*/
+
+ unsigned int rxHECpass:1; /**< [24] Specifies if the incoming cell HEC byte should be transferred
+ after optional processing to the NPE2 Coprocessor Bus Interface or
+ if it should be discarded.
+ @li 1 - HEC maintained 53-byte/UDC cell sent to NPE2.
+ @li 0 - HEC discarded 52-byte/UDC cell sent to NPE2 coprocessor.*/
+
+ unsigned int reserved_1:1; /**< [23] These bits are always 0 */
+
+ unsigned int rxCellSize:7; /**< [22:16] Receive cell size. Configures the receive cell size.
+ Values between 52-64 are valid */
+
+ unsigned int rxHashEnbGFC:1; /**< [15] Specifies if the VPI field [11:8]/GFC field should be
+ included in the Hash data input or if the bits should be padded
+ with 1Æb0.
+ @li 1 - VPI [11:8]/GFC field valid and used in Hash residue calculation.
+ @li 0 - VPI [11:8]/GFC field padded with 1Æb0 */
+
+ unsigned int rxPreHash:1; /**< [14] Enable Pre-hash value generation. Specifies if the
+ incoming cell data should be pre-hashed to allow VPI/VCI header look-up
+ in a hash table.
+ @li 1 - Pre-hashing enabled
+ @li 0 - Pre-hashing disabled */
+
+ unsigned int reserved_2:1; /**< [13] These bits are always 0 */
+
+ unsigned int rxAddrRange:5; /**< [12:8] In ATM master, MPHY mode,
+ * this register specifies the upper
+ * limit of the PHY polling logical range. The number of active PHYs are
+ * RxAddrRange + 1.
+ */
+ unsigned int reserved_3:3; /**< [7-5] These bits are always 0 .*/
+ unsigned int rxPHYAddr:5; /**< [4:0] When configured as a slave in an MPHY system this register
+ * specifies the physical address of the PHY.
+ */
+ } utRxConfig; /**< Rx config Utopia register */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtRxStatsConfig_
+ * @brief Utopia Rx stats config Register
+ */
+ struct UtRxStatsConfig_
+ {
+
+ unsigned int vpi:12; /**< [31:20] ATM VPI VPI [11:0] OR GFC [3:0] and VPI [7:0]
+ @li Note: if VCStatsRxGFC is set to 0 the GFC field is ignored in test. */
+
+ unsigned int vci:16; /**< [19:4] VCI [15:0] or PHY Address [4] */
+
+ unsigned int pti:3; /**< [3:1] PTI [2:0] or or PHY Address [3:1]
+ @li Note: if VCStatsRxPTI is set to 0 the PTI field is ignored in test.
+ @li Note: if VCStatsRxEnb is set to 0 only the PHY port address is used
+ for statistics gathering.. */
+
+ unsigned int clp:1; /**< [0] CLP [0] or PHY Address [0]
+ @li Note: if VCStatsRxCLP is set to 0 the CLP field is ignored in test.
+ @li Note: if VCStatsRxEnb is set to 0 only the PHY port address is used
+ for statistics gathering.. */
+ } utRxStatsConfig; /**< Rx stats config Utopia register */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtRxDefineIdle_
+ * @brief Utopia Rx idle cells config Register
+ */
+ struct UtRxDefineIdle_
+ {
+
+ unsigned int vpi:12; /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0]
+ @li Note: if VCIdleRxGFC is set to 0 the GFC field is ignored in test. */
+
+ unsigned int vci:16; /**< [19:4] ATM VCI [15:0] */
+
+ unsigned int pti:3; /**< [3:1] ATM PTI PTI [2:0]
+ @li Note: if VCIdleRxPTI is set to 0 the PTI field is ignored in test.*/
+
+ unsigned int clp:1; /**< [0] ATM CLP [0]
+ @li Note: if VCIdleRxCLP is set to 0 the CLP field is ignored in test.*/
+ } utRxDefineIdle; /**< Rx idle cell config Utopia register */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtRxEnableFields_
+ * @brief Utopia Rx enable Register
+ */
+ struct UtRxEnableFields_
+ {
+
+ unsigned int defineRxIdleGFC:1;/**< [31] This register is used to include or exclude the GFC
+ field of the ATM header when testing for Idle cells.
+ @li 1 - GFC field is valid.
+ @li 0 - GFC field ignored.*/
+
+ unsigned int defineRxIdlePTI:1;/**< [30] This register is used to include or exclude the PTI
+ field of the ATM header when testing for Idle cells.
+ @li 1 - PTI field is valid.
+ @li 0 - PTI field ignored.*/
+
+ unsigned int defineRxIdleCLP:1;/**< [29] This register is used to include or exclude the CLP
+ field of the ATM header when testing for Idle cells.
+ @li 1 - CLP field is valid.
+ @li 0 - CLP field ignored.*/
+
+ unsigned int phyStatsRxEnb:1;/**< [28] This register is used to enable or disable ATM statistics
+ gathering based on the specified PHY address as defined in RxStatsConfig
+ register.
+ @li 1 - Enable statistics for specified receive PHY address.
+ @li 0 - Disable statistics for specified receive PHY address.*/
+
+ unsigned int vcStatsRxEnb:1;/**< [27] This register is used to enable or disable ATM statistics
+ gathering based on a specific VPI/VCI address.
+ @li 1 - Enable statistics for specified VPI/VCI address.
+ @li 0 - Disable statistics for specified VPI/VCI address.*/
+
+ unsigned int vcStatsRxGFC:1;/**< [26] This register is used to include or exclude the GFC field
+ of the ATM header when ATM VPI/VCI statistics are enabled. GFC is only
+ available at the UNI and uses the first 4-bits of the VPI field.
+ @li 1 - GFC field is valid.
+ @li 0 - GFC field ignored. */
+
+ unsigned int vcStatsRxPTI:1;/**< [25] This register is used to include or exclude the PTI field
+ of the ATM header when ATM VPI/VCI statistics are enabled.
+ @li 1 - PTI field is valid.
+ @li 0 - PTI field ignored.*/
+
+ unsigned int vcStatsRxCLP:1;/**< [24] This register is used to include or exclude the CLP field
+ of the ATM header when ATM VPI/VCI statistics are enabled.
+ @li 1 - CLP field is valid.
+ @li 0 - CLP field ignored. */
+
+ unsigned int discardHecErr:1;/**< [23] Discard cells with an invalid HEC.
+ @li 1 - Discard cells with HEC errors
+ @li 0 - Cells with HEC errors are passed */
+
+ unsigned int discardParErr:1;/**< [22] Discard cells containing parity errors.
+ @li 1 - Discard cells with parity errors
+ @li 0 - Cells with parity errors are passed */
+
+ unsigned int discardIdle:1; /**< [21] Discard Idle Cells based on DefineIdle register values
+ @li 1 - Discard IDLE cells
+ @li 0 - IDLE cells passed */
+
+ unsigned int enbHecErrCnt:1;/**< [20] Enable Receive HEC Error Count.
+ @li 1 - Enable count of received cells containing HEC errors
+ @li 0 - No count is maintained. */
+
+ unsigned int enbParErrCnt:1;/**< [19] Enable Parity Error Count
+ @li 1 - Enable count of received cells containing Parity errors
+ @li 0 - No count is maintained. */
+
+ unsigned int enbIdleCellCnt:1;/**< [18] Enable Receive Idle Cell Count.
+ @li 1 - Enable count of Idle cells received.
+ @li 0 - No count is maintained.*/
+
+ unsigned int enbSizeErrCnt:1;/**< [17] Enable Receive Size Error Count.
+ @li 1 - Enable count of received cells of incorrect size
+ @li 0 - No count is maintained. */
+
+ unsigned int enbRxCellCnt:1;/**< [16] Enable Receive Valid Cell Count of non-idle/non-error cells.
+ @li 1 - Enable count of valid cells received - non-idle/non-error
+ @li 0 - No count is maintained. */
+
+ unsigned int reserved_1:3; /**< [15:13] These bits are always 0 */
+
+ unsigned int rxCellOvrInt:1; /**< [12] Enable CBI Utopia Receive Status Condition if the RxCellCount
+ register overflows.
+ @li 1 - CBI Receive Status asserted.
+ @li 0 - No CBI Receive Status asserted.*/
+
+ unsigned int invalidHecOvrInt:1; /**< [11] Enable CBI Receive Status Condition if the InvalidHecCount
+ register overflows.
+ @li 1 - CBI Receive Condition asserted.
+ @li 0 - No CBI Receive Condition asserted */
+
+ unsigned int invalidParOvrInt:1; /**< [10] Enable CBI Receive Status Condition if the InvalidParCount
+ register overflows
+ @li 1 - CBI Receive Condition asserted.
+ @li 0 - No CBI Receive Condition asserted */
+
+ unsigned int invalidSizeOvrInt:1; /**< [9] Enable CBI Receive Status Condition if the InvalidSizeCount
+ register overflows.
+ @li 1 - CBI Receive Status Condition asserted.
+ @li¸0 - No CBI Receive Status asserted */
+
+ unsigned int rxIdleOvrInt:1; /**< [8] Enable CBI Receive Status Condition if the RxIdleCount overflows.
+ @li 1 - CBI Receive Condition asserted.
+ @li 0 - No CBI Receive Condition asserted */
+
+ unsigned int reserved_2:3; /**< [7:5] These bits are always 0 */
+
+ unsigned int rxAddrMask:5; /**< [4:0] This register is used as a mask to allow the user to increase
+ the PHY receive address range. The register should be programmed with
+ the address-range limit, i.e. if set to 0x3 the address range increases
+ to a maximum of 4 addresses. */
+ } utRxEnableFields; /**< Rx enable Utopia register */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtRxTransTable0_
+ * @brief Utopia Rx translation table Register
+ */
+ struct UtRxTransTable0_
+ {
+
+ unsigned int phy0:5; /**< [31-27] Rx Mapping value of logical phy 0 */
+
+ unsigned int phy1:5; /**< [26-22] Rx Mapping value of logical phy 1 */
+
+ unsigned int phy2:5; /**< [21-17] Rx Mapping value of logical phy 2 */
+
+ unsigned int reserved_1:1; /**< [16] These bits are always 0 */
+
+ unsigned int phy3:5; /**< [15-11] Rx Mapping value of logical phy 3 */
+
+ unsigned int phy4:5; /**< [10-6] Rx Mapping value of logical phy 4 */
+
+ unsigned int phy5:5; /**< [5-1] Rx Mapping value of logical phy 5 */
+
+ unsigned int reserved_2:1; /**< [0] These bits are always 0 */
+ }
+
+ utRxTransTable0; /**< Rx translation table */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtRxTransTable1_
+ * @brief Utopia Rx translation table Register
+ */
+ struct UtRxTransTable1_
+ {
+
+ unsigned int phy6:5; /**< [31-27] Rx Mapping value of logical phy 6 */
+
+ unsigned int phy7:5; /**< [26-22] Rx Mapping value of logical phy 7 */
+
+ unsigned int phy8:5; /**< [21-17] Rx Mapping value of logical phy 8 */
+
+ unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */
+
+ unsigned int phy9:5; /**< [15-11] Rx Mapping value of logical phy 3 */
+
+ unsigned int phy10:5; /**< [10-6] Rx Mapping value of logical phy 4 */
+
+ unsigned int phy11:5; /**< [5-1] Rx Mapping value of logical phy 5 */
+
+ unsigned int reserved_2:1; /**< [0] These bits are always 0 */
+ }
+
+ utRxTransTable1; /**< Rx translation table */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtRxTransTable2_
+ * @brief Utopia Rx translation table Register
+ */
+ struct UtRxTransTable2_
+ {
+
+ unsigned int phy12:5; /**< [31-27] Rx Mapping value of logical phy 6 */
+
+ unsigned int phy13:5; /**< [26-22] Rx Mapping value of logical phy 7 */
+
+ unsigned int phy14:5; /**< [21-17] Rx Mapping value of logical phy 8 */
+
+ unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */
+
+ unsigned int phy15:5; /**< [15-11] Rx Mapping value of logical phy 3 */
+
+ unsigned int phy16:5; /**< [10-6] Rx Mapping value of logical phy 4 */
+
+ unsigned int phy17:5; /**< [5-1] Rx Mapping value of logical phy 5 */
+
+ unsigned int reserved_2:1; /**< [0] These bits are always 0 */
+ } utRxTransTable2; /**< Rx translation table */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtRxTransTable3_
+ * @brief Utopia Rx translation table Register
+ */
+ struct UtRxTransTable3_
+ {
+
+ unsigned int phy18:5; /**< [31-27] Rx Mapping value of logical phy 6 */
+
+ unsigned int phy19:5; /**< [26-22] Rx Mapping value of logical phy 7 */
+
+ unsigned int phy20:5; /**< [21-17] Rx Mapping value of logical phy 8 */
+
+ unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */
+
+ unsigned int phy21:5; /**< [15-11] Rx Mapping value of logical phy 3 */
+
+ unsigned int phy22:5; /**< [10-6] Rx Mapping value of logical phy 4 */
+
+ unsigned int phy23:5; /**< [5-1] Rx Mapping value of logical phy 5 */
+
+ unsigned int reserved_2:1; /**< [0] These bits are always 0 */
+ } utRxTransTable3; /**< Rx translation table */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtRxTransTable4_
+ * @brief Utopia Rx translation table Register
+ */
+ struct UtRxTransTable4_
+ {
+
+ unsigned int phy24:5; /**< [31-27] Rx Mapping value of logical phy 6 */
+
+ unsigned int phy25:5; /**< [26-22] Rx Mapping value of logical phy 7 */
+
+ unsigned int phy26:5; /**< [21-17] Rx Mapping value of logical phy 8 */
+
+ unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */
+
+ unsigned int phy27:5; /**< [15-11] Rx Mapping value of logical phy 3 */
+
+ unsigned int phy28:5; /**< [10-6] Rx Mapping value of logical phy 4 */
+
+ unsigned int phy29:5; /**< [5-1] Rx Mapping value of logical phy 5 */
+
+ unsigned int reserved_2:1; /**< [0] These bits are always 0 */
+ } utRxTransTable4; /**< Rx translation table */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtRxTransTable5_
+ * @brief Utopia Rx translation table Register
+ */
+ struct UtRxTransTable5_
+ {
+
+ unsigned int phy30:5; /**< [31-27] Rx Mapping value of logical phy 6 */
+
+ unsigned int reserved_1:27; /**< [26-0] These bits are always 0 */
+
+ } utRxTransTable5; /**< Rx translation table */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtSysConfig_
+ * @brief NPE setup Register
+ */
+ struct UtSysConfig_
+ {
+
+ unsigned int reserved_1:2; /**< [31-30] These bits are always 0 */
+ unsigned int txEnbFSM:1; /**< [29] Enables the operation ofthe Utopia Transmit FSM
+ * @li 1 - FSM enabled
+ * @li 0 - FSM inactive
+ */
+ unsigned int rxEnbFSM:1; /**< [28] Enables the operation ofthe Utopia Revieve FSM
+ * @li 1 - FSM enabled
+ * @li 0 - FSM inactive
+ */
+ unsigned int disablePins:1; /**< [27] Disable Utopia interface I/O pins forcing the signals to an
+ * inactive state. Note that this bit is set on reset and must be
+ * de-asserted
+ * @li 0 - Normal data transfer
+ * @li 1 - Utopia interface pins are forced inactive
+ */
+ unsigned int tstLoop:1; /**< [26] Test Loop Back Enable.
+ * @li Note: For loop back to function RxMode and Tx Mode must both be set
+ * to single PHY mode.
+ * @li 0 - Loop back
+ * @li 1 - Normal operating mode
+ */
+
+ unsigned int txReset:1; /**< [25] Resets the Utopia Coprocessor transmit module to a known state.
+ * @li Note: All transmit configuration and status registers will be reset
+ * to their reset values.
+ * @li 0 - Normal operating mode¸
+ * @li 1 - Reset transmit modules
+ */
+
+ unsigned int rxReset:1; /**< [24] Resets the Utopia Coprocessor receive module to a known state.
+ * @li Note: All receive configuration and status registers will be reset
+ * to their reset values.
+ * @li 0 - Normal operating mode
+ * @li 1 - Reset receive modules
+ */
+
+ unsigned int reserved_2:24; /**< [23-0] These bits are always 0 */
+ } utSysConfig; /**< NPE debug config */
+
+}
+IxAtmdAccUtopiaConfig;
+
+/**
+*
+* @brief Utopia status
+*
+* This structure is used to set/get the Utopia status parameters
+* @li contains debug cell counters, to be accessed during a read operation
+*
+* @note - the exact description of all parameters is done in the Utopia reference
+* documents.
+*
+*/
+typedef struct
+{
+
+ unsigned int utTxCellCount; /**< count of cells transmitted */
+
+ unsigned int utTxIdleCellCount; /**< count of idle cells transmitted */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtTxCellConditionStatus_
+ * @brief Utopia Tx Status Register
+ */
+ struct UtTxCellConditionStatus_
+ {
+
+ unsigned int reserved_1:2; /**< [31:30] These bits are always 0 */
+ unsigned int txFIFO2Underflow:1; /**< [29] This bit is set if 64-byte
+ * Transmit FIFO2 indicates a FIFO underflow
+ * error condition.
+ */
+ unsigned int txFIFO1Underflow:1; /**< [28] This bit is set if
+ * 64-byte Transmit FIFO1 indicates a FIFO
+ * underflow error condition.
+ */
+ unsigned int txFIFO2Overflow:1; /**< [27] This bit is set if 64-byte
+ * Transmit FIFO2 indicates a FIFO overflow
+ * error condition.
+ */
+ unsigned int txFIFO1Overflow:1; /**< [26] This bit is set if 64-byte
+ * Transmit FIFO1 indicates a FIFO overflow
+ * error condition.
+ */
+ unsigned int txIdleCellCountOvr:1; /**< [25] This bit is set if the
+ * TxIdleCellCount register overflows.
+ */
+ unsigned int txCellCountOvr:1; /**< [24] This bit is set if the
+ * TxCellCount register overflows
+ */
+ unsigned int reserved_2:24; /**< [23:0] These bits are always 0 */
+ } utTxCellConditionStatus; /**< Tx cells condition status */
+
+ unsigned int utRxCellCount; /**< count of cell received */
+ unsigned int utRxIdleCellCount; /**< count of idle cell received */
+ unsigned int utRxInvalidHECount; /**< count of invalid cell
+ * received because of HEC errors
+ */
+ unsigned int utRxInvalidParCount; /**< count of invalid cell received
+ * because of parity errors
+ */
+ unsigned int utRxInvalidSizeCount; /**< count of invalid cell
+ * received because of cell
+ * size errors
+ */
+
+ /**
+ * @ingroup IxAtmdAccUtopiaCtrlAPI
+ * @struct UtRxCellConditionStatus_
+ * @brief Utopia Rx Status Register
+ */
+ struct UtRxCellConditionStatus_
+ {
+
+ unsigned int reserved_1:3; /**< [31:29] These bits are always 0.*/
+ unsigned int rxCellCountOvr:1; /**< [28] This bit is set if the RxCellCount register overflows. */
+ unsigned int invalidHecCountOvr:1; /**< [27] This bit is set if the InvalidHecCount register overflows.*/
+ unsigned int invalidParCountOvr:1; /**< [26] This bit is set if the InvalidParCount register overflows.*/
+ unsigned int invalidSizeCountOvr:1; /**< [25] This bit is set if the InvalidSizeCount register overflows.*/
+ unsigned int rxIdleCountOvr:1; /**< [24] This bit is set if the RxIdleCount register overflows.*/
+ unsigned int reserved_2:4; /**< [23:20] These bits are always 0 */
+ unsigned int rxFIFO2Underflow:1; /**< [19] This bit is set if 64-byte Receive FIFO2
+ * indicates a FIFO underflow error condition.
+ */
+ unsigned int rxFIFO1Underflow:1; /**< [18] This bit is set if 64-byte Receive
+ * FIFO1 indicates a FIFO underflow error condition
+ . */
+ unsigned int rxFIFO2Overflow:1; /**< [17] This bit is set if 64-byte Receive FIFO2
+ * indicates a FIFO overflow error condition.
+ */
+ unsigned int rxFIFO1Overflow:1; /**< [16] This bit is set if 64-byte Receive FIFO1
+ * indicates a FIFO overflow error condition.
+ */
+ unsigned int reserved_3:16; /**< [15:0] These bits are always 0. */
+ } utRxCellConditionStatus; /**< Rx cells condition status */
+
+} IxAtmdAccUtopiaStatus;
+
+/**
+ * @} defgroup IxAtmdAccUtopiaCtrlAPI
+ */
+
+ /**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccUtopiaConfigSet (const IxAtmdAccUtopiaConfig *
+ ixAtmdAccUtopiaConfigPtr)
+ *
+ * @brief Send the configuration structure to the Utopia interface
+ *
+ * This function downloads the @a IxAtmdAccUtopiaConfig structure to
+ * the Utopia and has the following effects
+ * @li setup the Utopia interface
+ * @li initialise the NPE
+ * @li reset the Utopia cell counters and status registers to known values
+ *
+ * This action has to be done once at initialisation. A lock is preventing
+ * the concurrent use of @a ixAtmdAccUtopiaStatusGet() and
+ * @A ixAtmdAccUtopiaConfigSet()
+ *
+ * @param *ixAtmdAccNPEConfigPtr @ref IxAtmdAccUtopiaConfig [in] - pointer to a structure to download to
+ * Utopia. This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS successful download
+ * @return @li IX_FAIL error in the parameters, or configuration is not
+ * complete or failed
+ *
+ * @sa ixAtmdAccUtopiaStatusGet
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccUtopiaConfigSet (const IxAtmdAccUtopiaConfig *
+ ixAtmdAccUtopiaConfigPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccUtopiaStatusGet (IxAtmdAccUtopiaStatus *
+ ixAtmdAccUtopiaStatus)
+ *
+ * @brief Get the Utopia interface configuration.
+ *
+ * This function reads the Utopia registers and the Cell counts
+ * and fills the @a IxAtmdAccUtopiaStatus structure
+ *
+ * A lock is preventing the concurrent
+ * use of @a ixAtmdAccUtopiaStatusGet() and @A ixAtmdAccUtopiaConfigSet()
+ *
+ * @param ixAtmdAccUtopiaStatus @ref IxAtmdAccUtopiaStatus [out] - pointer to structure to be updated from internal
+ * hardware counters. This parameter cannot be a NULL pointer.
+ *
+ * @return @li IX_SUCCESS successful read
+ * @return @li IX_FAIL error in the parameters null pointer, or
+ * configuration read is not complete or failed
+ *
+ * @sa ixAtmdAccUtopiaConfigSet
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccUtopiaStatusGet (IxAtmdAccUtopiaStatus *
+ ixAtmdAccUtopiaStatus);
+
+/**
+ *
+ * @ingroup IxAtmdAcc
+ *
+ * @fn ixAtmdAccPortEnable (IxAtmLogicalPort port)
+ *
+ * @brief enable a PHY logical port
+ *
+ * This function enables the transmission over one port. It should be
+ * called before accessing any resource from this port and before the
+ * establishment of a VC.
+ *
+ * When a port is enabled, the cell transmission to the Utopia interface
+ * is started. If there is no traffic already running, idle cells are
+ * sent over the interface.
+ *
+ * This function can be called multiple times.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ *
+ * @return @li IX_SUCCESS enable is complete
+ * @return @li IX_ATMDACC_WARNING port already enabled
+ * @return @li IX_FAIL enable failed, wrong parameter, or cannot
+ * initialise this port (the port is maybe already in use,
+ * or there is a hardware issue)
+ *
+ * @note - This function needs internal locks and should not be
+ * called from an interrupt context
+ *
+ * @sa ixAtmdAccPortDisable
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccPortEnable (IxAtmLogicalPort port);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccPortDisable (IxAtmLogicalPort port)
+ *
+ * @brief disable a PHY logical port
+ *
+ * This function disable the transmission over one port.
+ *
+ * When a port is disabled, the cell transmission to the Utopia interface
+ * is stopped.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ *
+ * @return @li IX_SUCCESS disable is complete
+ * @return @li IX_ATMDACC_WARNING port already disabled
+ * @return @li IX_FAIL disable failed, wrong parameter .
+ *
+ * @note - This function needs internal locks and should not be called
+ * from an interrupt context
+ *
+ * @note - The response from hardware is done through the txDone mechanism
+ * to ensure the synchrnisation with tx resources. Therefore, the
+ * txDone mechanism needs to be serviced to make a PortDisable complete.
+ *
+ * @sa ixAtmdAccPortEnable
+ * @sa ixAtmdAccPortDisableComplete
+ * @sa ixAtmdAccTxDoneDispatch
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccPortDisable (IxAtmLogicalPort port);
+
+/**
+*
+* @ingroup IxAtmdAccCtrlAPI
+*
+* @fn ixAtmdAccPortDisableComplete (IxAtmLogicalPort port)
+*
+* @brief disable a PHY logical port
+*
+* This function indicates if the port disable for a port has completed. This
+* function will return TRUE if the port has never been enabled.
+*
+* @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+*
+* @return @li TRUE disable is complete
+* @return @li FALSE disable failed, wrong parameter .
+*
+* @note - This function needs internal locks and should not be called
+* from an interrupt context
+*
+* @sa ixAtmdAccPortEnable
+* @sa ixAtmdAccPortDisable
+*
+*/
+PUBLIC BOOL ixAtmdAccPortDisableComplete (IxAtmLogicalPort port);
+
+#endif /* IXATMDACCCTRL_H */
+
+/**
+ * @} defgroup IxAtmdAccCtrlAPI
+ */
+
+
diff --git a/cpu/ixp/npe/include/IxAtmm.h b/cpu/ixp/npe/include/IxAtmm.h
new file mode 100644
index 0000000..fcf523f
--- /dev/null
+++ b/cpu/ixp/npe/include/IxAtmm.h
@@ -0,0 +1,795 @@
+/**
+ * @file IxAtmm.h
+ *
+ * @date 3-DEC-2001
+ *
+ * @brief Header file for the IXP400 ATM Manager component (IxAtmm)
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+/**
+ * @defgroup IxAtmm IXP400 ATM Manager (IxAtmm) API
+ *
+ * @brief IXP400 ATM Manager component Public API
+ *
+ * @{
+ */
+
+#ifndef IXATMM_H
+#define IXATMM_H
+
+/*
+ * Put the user defined include files required
+ */
+#include "IxAtmSch.h"
+#include "IxOsalTypes.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/**
+ * @def IX_ATMM_RET_ALREADY_INITIALIZED
+ *
+ * @brief Component has already been initialized
+ */
+#define IX_ATMM_RET_ALREADY_INITIALIZED 2
+
+/**
+ * @def IX_ATMM_RET_INVALID_PORT
+ *
+ * @brief Specified port does not exist or is out of range */
+#define IX_ATMM_RET_INVALID_PORT 3
+
+/**
+ * @def IX_ATMM_RET_INVALID_VC_DESCRIPTOR
+ *
+ * @brief The VC description does not adhere to ATM standards */
+#define IX_ATMM_RET_INVALID_VC_DESCRIPTOR 4
+
+/**
+ * @def IX_ATMM_RET_VC_CONFLICT
+ *
+ * @brief The VPI/VCI values supplied are either reserved, or they
+ * conflict with a previously registered VC on this port */
+#define IX_ATMM_RET_VC_CONFLICT 5
+
+/**
+ * @def IX_ATMM_RET_PORT_CAPACITY_IS_FULL
+ *
+ * @brief The virtual connection cannot be established on the port
+ * because the remaining port capacity is not sufficient to
+ * support it */
+#define IX_ATMM_RET_PORT_CAPACITY_IS_FULL 6
+
+/**
+ * @def IX_ATMM_RET_NO_SUCH_VC
+ *
+ * @brief No registered VC, as described by the supplied VCI/VPI or
+ * VC identifier values, exists on this port */
+#define IX_ATMM_RET_NO_SUCH_VC 7
+
+/**
+ * @def IX_ATMM_RET_INVALID_VC_ID
+ *
+ * @brief The specified VC identifier is out of range. */
+#define IX_ATMM_RET_INVALID_VC_ID 8
+
+/**
+ * @def IX_ATMM_RET_INVALID_PARAM_PTR
+ *
+ * @brief A pointer parameter was NULL. */
+#define IX_ATMM_RET_INVALID_PARAM_PTR 9
+
+/**
+ * @def IX_ATMM_UTOPIA_SPHY_ADDR
+ *
+ * @brief The phy address when in SPHY mode */
+#define IX_ATMM_UTOPIA_SPHY_ADDR 31
+
+/**
+ * @def IX_ATMM_THREAD_PRI_HIGH
+ *
+ * @brief The value of high priority thread */
+#define IX_ATMM_THREAD_PRI_HIGH 90
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/** @brief Definition for use in the @ref IxAtmmVc structure.
+ * Indicates the direction of a VC */
+typedef enum
+{
+ IX_ATMM_VC_DIRECTION_TX=0, /**< Atmm Vc direction transmit*/
+ IX_ATMM_VC_DIRECTION_RX, /**< Atmm Vc direction receive*/
+ IX_ATMM_VC_DIRECTION_INVALID /**< Atmm Vc direction invalid*/
+} IxAtmmVcDirection;
+
+/** @brief Definition for use with @ref IxAtmmVcChangeCallback
+ * callback. Indicates that the event type represented by the
+ * callback for this VC. */
+typedef enum
+{
+ IX_ATMM_VC_CHANGE_EVENT_REGISTER=0, /**< Atmm Vc event register*/
+ IX_ATMM_VC_CHANGE_EVENT_DEREGISTER, /**< Atmm Vc event de-register*/
+ IX_ATMM_VC_CHANGE_EVENT_INVALID /**< Atmm Vc event invalid*/
+} IxAtmmVcChangeEvent;
+
+/** @brief Definitions for use with @ref ixAtmmUTOPIAInit interface to
+ * indicate that UTOPIA loopback should be enabled or disabled
+ * on initialisation. */
+typedef enum
+{
+ IX_ATMM_UTOPIA_LOOPBACK_DISABLED=0, /**< Atmm Utopia loopback mode disabled*/
+ IX_ATMM_UTOPIA_LOOPBACK_ENABLED, /**< Atmm Utopia loopback mode enabled*/
+ IX_ATMM_UTOPIA_LOOPBACK_INVALID /**< Atmm Utopia loopback mode invalid*/
+} IxAtmmUtopiaLoopbackMode;
+
+/** @brief This structure describes the required attributes of a
+ * virtual connection.
+*/
+typedef struct {
+ unsigned vpi; /**< VPI value of this virtual connection */
+ unsigned vci; /**< VCI value of this virtual connection. */
+ IxAtmmVcDirection direction; /**< VC direction */
+
+ /** Traffic descriptor of this virtual connection. This structure
+ * is defined by the @ref IxAtmSch component. */
+ IxAtmTrafficDescriptor trafficDesc;
+} IxAtmmVc;
+
+
+/** @brief Definitions for use with @ref ixAtmmUtopiaInit interface to
+ * indicate that UTOPIA multi-phy/single-phy mode is used.
+ */
+typedef enum
+{
+ IX_ATMM_MPHY_MODE = 0, /**< Atmm phy mode mphy*/
+ IX_ATMM_SPHY_MODE, /**< Atmm phy mode sphy*/
+ IX_ATMM_PHY_MODE_INVALID /**< Atmm phy mode invalid*/
+} IxAtmmPhyMode;
+
+
+/** @brief Structure contains port-specific information required to
+ * initialize IxAtmm, and specifically, the IXP400 UTOPIA
+ * Level-2 device. */
+typedef struct {
+ unsigned reserved_1:11; /**< [31:21] Should be zero */
+ unsigned UtopiaTxPhyAddr:5; /**< [20:16] Address of the
+ * transmit (Tx) PHY for this
+ * port on the 5-bit UTOPIA
+ * Level-2 address bus */
+ unsigned reserved_2:11; /**< [15:5] Should be zero */
+ unsigned UtopiaRxPhyAddr:5; /**< [4:0] Address of the receive
+ * (Rx) PHY for this port on the
+ * 5-bit UTOPIA Level-2
+ * address bus */
+} IxAtmmPortCfg;
+
+/** @brief Callback type used with @ref ixAtmmVcChangeCallbackRegister interface
+ * Defines a callback type which will be used to notify registered
+ * users of registration/deregistration events on a particular port
+ *
+ * @param eventType @ref IxAtmmVcChangeEvent [in] - Event indicating
+ * whether the VC supplied has been added or
+ * removed
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Specifies the port on which the event has
+ * occurred
+ *
+ * @param vcChanged @ref IxAtmmVc* [in] - Pointer to a structure which gives
+ * details of the VC which has been added
+ * or removed on the port
+ */
+typedef void (*IxAtmmVcChangeCallback) (IxAtmmVcChangeEvent eventType,
+ IxAtmLogicalPort port,
+ const IxAtmmVc* vcChanged);
+
+/*
+ * Variable declarations global to this file only. Externs are followed by
+ * static variables.
+ */
+
+/*
+ * Extern function prototypes
+ */
+
+/*
+ * Function declarations
+ */
+
+
+/**
+ * @ingroup IxAtmm
+ *
+ * @fn ixAtmmInit (void)
+ *
+ * @brief Interface to initialize the IxAtmm software component. Can
+ * be called once only.
+ *
+ * Must be called before any other IxAtmm API is called.
+ *
+ * @param "none"
+ *
+ * @return @li IX_SUCCESS : IxAtmm has been successfully initialized.
+ * Calls to other IxAtmm interfaces may now be performed.
+ * @return @li IX_FAIL : IxAtmm has already been initialized.
+ */
+PUBLIC IX_STATUS
+ixAtmmInit (void);
+
+/**
+ * @ingroup IxAtmm
+ *
+ * @fn ixAtmmUtopiaInit (unsigned numPorts,
+ IxAtmmPhyMode phyMode,
+ IxAtmmPortCfg portCfgs[],
+ IxAtmmUtopiaLoopbackMode loopbackMode)
+ *
+ * @brief Interface to initialize the UTOPIA Level-2 ATM coprocessor
+ * for the specified number of physical ports. The function
+ * must be called before the ixAtmmPortInitialize interface
+ * can operate successfully.
+ *
+ * @param numPorts unsigned [in] - Indicates the total number of logical
+ * ports that are active on the device. Up to 12 ports are
+ * supported.
+ *
+ * @param phyMode @ref IxAtmmPhyMode [in] - Put the Utopia coprocessor in SPHY
+ * or MPHY mode.
+ *
+ * @param portCfgs[] @ref IxAtmmPortCfg [in] - Pointer to an array of elements
+ * detailing the UTOPIA specific port characteristics. The
+ * length of the array must be equal to the number of ports
+ * activated. ATM ports are referred to by the relevant
+ * offset in this array in all subsequent IxAtmm interface
+ * calls.
+ *
+ * @param loopbackMode @ref IxAtmmUtopiaLoopbackMode [in] - Value must be one of
+ * @ref IX_ATMM_UTOPIA_LOOPBACK_ENABLED or @ref
+ * IX_ATMM_UTOPIA_LOOPBACK_DISABLED indicating whether
+ * loopback should be enabled on the device. Loopback can
+ * only be supported on a single PHY, therefore the numPorts
+ * parameter must be 1 if loopback is enabled.
+ *
+ * @return @li IX_SUCCESS : Indicates that the UTOPIA device has been
+ * successfully initialized for the supplied ports.
+ * @return @li IX_ATMM_RET_ALREADY_INITIALIZED : The UTOPIA device has
+ * already been initialized.
+ * @return @li IX_FAIL : The supplied parameters are invalid or have been
+ * rejected by the UTOPIA-NPE device.
+ *
+ * @warning
+ * This interface may only be called once.
+ * Port identifiers are assumed to range from 0 to (numPorts - 1) in all
+ * instances.
+ * In all subsequent calls to interfaces supplied by IxAtmm, the specified
+ * port value is expected to represent the offset in the portCfgs array
+ * specified in this interface. i.e. The first port in this array will
+ * subsequently be represented as port 0, the second port as port 1,
+ * and so on.*/
+PUBLIC IX_STATUS
+ixAtmmUtopiaInit (unsigned numPorts,
+ IxAtmmPhyMode phyMode,
+ IxAtmmPortCfg portCfgs[],
+ IxAtmmUtopiaLoopbackMode loopbackMode);
+
+
+/**
+ * @ingroup IxAtmm
+ *
+ * @fn ixAtmmPortInitialize (IxAtmLogicalPort port,
+ unsigned txPortRate,
+ unsigned rxPortRate)
+ *
+ * @brief The interface is called following @ref ixAtmmUtopiaInit ()
+ * and before calls to any other IxAtmm interface. It serves
+ * to activate the registered ATM port with IxAtmm.
+ *
+ * The transmit and receive port rates are specified in bits per
+ * second. This translates to ATM cells per second according to the
+ * following formula: CellsPerSecond = portRate / (53*8) The
+ * IXP400 device supports only 53 byte cells. The client shall make
+ * sure that the off-chip physical layer device has already been
+ * initialized.
+ *
+ * IxAtmm will configure IxAtmdAcc and IxAtmSch to enable scheduling
+ * on the port.
+ *
+ * This interface must be called once for each active port in the
+ * system. The first time the interface is invoked, it will configure
+ * the mechanism by which the handling of transmit, transmit-done and
+ * receive are driven with the IxAtmdAcc component.
+ *
+ * This function is reentrant.
+ *
+ * @note The minimum tx rate that will be accepted is 424 bit/s which equates
+ * to 1 cell (53 bytes) per second.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Identifies the port which is to be
+ * initialized.
+ *
+ * @param txPortRate unsigned [in] - Value specifies the
+ * transmit port rate for this port in
+ * bits/second. This value is used by the ATM Scheduler
+ * component is evaluating VC access requests for the port.
+ *
+ * @param rxPortRate unsigned [in] - Value specifies the
+ * receive port rate for this port in bits/second.
+ *
+ * @return @li IX_SUCCESS : The specificed ATM port has been successfully
+ * initialized. IxAtmm is ready to accept VC registrations on
+ * this port.
+ *
+ * @return @li IX_ATMM_RET_ALREADY_INITIALIZED : ixAtmmPortInitialize has
+ * already been called successfully on this port. The current
+ * call is rejected.
+ *
+ * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
+ * input is not valid. The request is rejected.
+ *
+ * @return @li IX_FAIL : IxAtmm could not initialize the port because the
+ * inputs are not understood.
+ *
+ * @sa ixAtmmPortEnable, ixAtmmPortDisable
+ *
+ */
+PUBLIC IX_STATUS
+ixAtmmPortInitialize (IxAtmLogicalPort port,
+ unsigned txPortRate,
+ unsigned rxPortRate);
+
+/**
+ * @ingroup IxAtmm
+ *
+ * @fn ixAtmmPortModify (IxAtmLogicalPort port,
+ unsigned txPortRate,
+ unsigned rxPortRate)
+ *
+ * @brief A client may call this interface to change the existing
+ * port rate (expressed in bits/second) on an established ATM
+ * port.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Identifies the port which is to be
+ * initialized.
+ *
+ * @param txPortRate unsigned [in] - Value specifies the``
+ * transmit port rate for this port in
+ * bits/second. This value is used by the ATM Scheduler
+ * component is evaluating VC access requests for the port.
+ *
+ * @param rxPortRate unsigned [in] - Value specifies the
+ * receive port rate for this port in
+ * bits/second.
+ *
+ * @return @li IX_SUCCESS : The indicated ATM port rates have been
+ * successfully modified.
+ *
+ * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
+ * input is not valid. The request is rejected.
+ *
+ * @return @li IX_FAIL : IxAtmm could not update the port because the
+ * inputs are not understood, or the interface was called before
+ * the port was initialized. */
+PUBLIC IX_STATUS
+ixAtmmPortModify (IxAtmLogicalPort port,
+ unsigned txPortRate,
+ unsigned rxPortRate);
+
+/**
+ * @ingroup IxAtmm
+ *
+ * @fn ixAtmmPortQuery (IxAtmLogicalPort port,
+ unsigned *txPortRate,
+ unsigned *rxPortRate);
+
+ *
+ * @brief The client may call this interface to request details on
+ * currently registered transmit and receive rates for an ATM
+ * port.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Value identifies the port from which the
+ * rate details are requested.
+ *
+ * @param *txPortRate unsigned [out] - Pointer to a value
+ * which will be filled with the value of the transmit port
+ * rate specified in bits/second.
+ *
+ * @param *rxPortRate unsigned [out] - Pointer to a value
+ * which will be filled with the value of the receive port
+ * rate specified in bits/second.
+ *
+ * @return @li IX_SUCCESS : The information requested on the specified
+ * port has been successfully supplied in the output.
+ *
+ * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
+ * input is not valid. The request is rejected.
+ *
+ * @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was
+ * NULL.
+ *
+ * @return @li IX_FAIL : IxAtmm could not update the port because the
+ * inputs are not understood, or the interface was called before
+ * the port was initialized. */
+PUBLIC IX_STATUS
+ixAtmmPortQuery (IxAtmLogicalPort port,
+ unsigned *txPortRate,
+ unsigned *rxPortRate);
+
+/**
+ * @ingroup IxAtmm
+ *
+ * @fn ixAtmmPortEnable(IxAtmLogicalPort port)
+ *
+ * @brief The client call this interface to enable transmit for an ATM
+ * port. At initialisation, all the ports are disabled.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Value identifies the port
+ *
+ * @return @li IX_SUCCESS : Transmission over this port is started.
+ *
+ * @return @li IX_FAIL : The port parameter is not valid, or the
+ * port is already enabled
+ *
+ * @note - When a port is disabled, Rx and Tx VC Connect requests will fail
+ *
+ * @note - This function uses system resources and should not be used
+ * inside an interrupt context.
+ *
+ * @sa ixAtmmPortDisable */
+PUBLIC IX_STATUS
+ixAtmmPortEnable(IxAtmLogicalPort port);
+
+/**
+ * @ingroup IxAtmm
+ *
+ * @fn ixAtmmPortDisable(IxAtmLogicalPort port)
+ *
+ * @brief The client call this interface to disable transmit for an ATM
+ * port. At initialisation, all the ports are disabled.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Value identifies the port
+ *
+ * @return @li IX_SUCCESS : Transmission over this port is stopped.
+ *
+ * @return @li IX_FAIL : The port parameter is not valid, or the
+ * port is already disabled
+ *
+ * @note - When a port is disabled, Rx and Tx VC Connect requests will fail
+ *
+ * @note - This function call does not stop RX traffic. It is supposed
+ * that this function is invoked when a serious problem
+ * is detected (e.g. physical layer broken). Then, the RX traffic
+ * is not passing.
+ *
+ * @note - This function is blocking until the hw acknowledge that the
+ * transmission is stopped.
+ *
+ * @note - This function uses system resources and should not be used
+ * inside an interrupt context.
+ *
+ * @sa ixAtmmPortEnable */
+PUBLIC IX_STATUS
+ixAtmmPortDisable(IxAtmLogicalPort port);
+
+/**
+ * @ingroup IxAtmm
+ *
+ * @fn ixAtmmVcRegister (IxAtmLogicalPort port,
+ IxAtmmVc *vcToAdd,
+ IxAtmSchedulerVcId *vcId)
+ *
+ * @brief This interface is used to register an ATM Virtual
+ * Connection on the specified ATM port.
+ *
+ * Each call to this interface registers a unidirectional virtual
+ * connection with the parameters specified. If a bi-directional VC
+ * is needed, the function should be called twice (once for each
+ * direction, Tx & Rx) where the VPI and VCI and port parameters in
+ * each call are identical.
+ *
+ * With the addition of each new VC to a port, a series of
+ * callback functions are invoked by the IxAtmm component to notify
+ * possible external components of the change. The callback functions
+ * are registered using the @ref ixAtmmVcChangeCallbackRegister interface.
+ *
+ * The IxAtmSch component is notified of the registration of transmit
+ * VCs.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Identifies port on which the specified VC is
+ * to be registered.
+ *
+ * @param *vcToAdd @ref IxAtmmVc [in] - Pointer to an @ref IxAtmmVc structure
+ * containing a description of the VC to be registered. The
+ * client shall fill the vpi, vci and direction and relevant
+ * trafficDesc members of this structure before calling this
+ * function.
+ *
+ * @param *vcId @ref IxAtmSchedulerVcId [out] - Pointer to an integer value which is filled
+ * with the per-port unique identifier value for this VC.
+ * This identifier will be required when a request is
+ * made to deregister or change this VC. VC identifiers
+ * for transmit VCs will have a value between 0-43,
+ * i.e. 32 data Tx VCs + 12 OAM Tx Port VCs.
+ * Receive VCs will have a value between 44-66,
+ * i.e. 32 data Rx VCs + 1 OAM Rx VC.
+ *
+ * @return @li IX_SUCCESS : The VC has been successfully registered on
+ * this port. The VC is ready for a client to configure IxAtmdAcc
+ * for receive and transmit operations on the VC.
+ * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
+ * input is not valid or has not been initialized. The request
+ * is rejected.
+ * @return @li IX_ATMM_RET_INVALID_VC_DESCRIPTOR : The descriptor
+ * pointed to by vcToAdd is invalid. The registration request
+ * is rejected.
+ * @return @li IX_ATMM_RET_VC_CONFLICT : The VC requested conflicts with
+ * reserved VPI and/or VCI values or with another VC already activated
+ * on this port.
+ * @return @li IX_ATMM_RET_PORT_CAPACITY_IS_FULL : The VC cannot be
+ * registered in the port becuase the port capacity is
+ * insufficient to support the requested ATM traffic contract.
+ * The registration request is rejected.
+ * @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was
+ * NULL.
+ *
+ * @warning IxAtmm has no capability of signaling or negotiating a virtual
+ * connection. Negotiation of the admission of the VC to the network
+ * is beyond the scope of this function. This is assumed to be
+ * performed by the calling client, if appropriate,
+ * before or after this function is called.
+ */
+PUBLIC IX_STATUS
+ixAtmmVcRegister (IxAtmLogicalPort port,
+ IxAtmmVc *vcToAdd,
+ IxAtmSchedulerVcId *vcId);
+
+/**
+ * @ingroup IxAtmm
+ *
+ * @fn ixAtmmVcDeregister (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId)
+ *
+ * @brief Function called by a client to deregister a VC from the
+ * system.
+ *
+ * With the removal of each new VC from a port, a series of
+ * registered callback functions are invoked by the IxAtmm component
+ * to notify possible external components of the change. The callback
+ * functions are registered using the @ref ixAtmmVcChangeCallbackRegister.
+ *
+ * The IxAtmSch component is notified of the removal of transmit VCs.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Identifies port on which the VC to be
+ * removed is currently registered.
+ *
+ * @param vcId @ref IxAtmSchedulerVcId [in] - VC identifier value of the VC to
+ * be deregistered. This value was supplied to the client when
+ the VC was originally registered. This value can also be
+ queried from the IxAtmm component through the @ref ixAtmmVcQuery
+ * interface.
+ *
+ * @return @li IX_SUCCESS : The specified VC has been successfully
+ * removed from this port.
+ * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
+ * input is not valid or has not been initialized. The request
+ * is rejected.
+ * @return @li IX_FAIL : There is no registered VC associated with the
+ * supplied identifier registered on this port. */
+PUBLIC IX_STATUS
+ixAtmmVcDeregister (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId);
+
+/**
+ * @ingroup IxAtmm
+ *
+ * @fn ixAtmmVcQuery (IxAtmLogicalPort port,
+ unsigned vpi,
+ unsigned vci,
+ IxAtmmVcDirection direction,
+ IxAtmSchedulerVcId *vcId,
+ IxAtmmVc *vcDesc)
+ *
+ * @brief This interface supplies information about an active VC on a
+ * particular port when supplied with the VPI, VCI and
+ * direction of that VC.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Identifies port on which the VC to be
+ * queried is currently registered.
+ *
+ * @param vpi unsigned [in] - ATM VPI value of the requested VC.
+ *
+ * @param vci unsigned [in] - ATM VCI value of the requested VC.
+ *
+ * @param direction @ref IxAtmmVcDirection [in] - One of @ref
+ * IX_ATMM_VC_DIRECTION_TX or @ref IX_ATMM_VC_DIRECTION_RX
+ * indicating the direction (Tx or Rx) of the requested VC.
+ *
+ * @param *vcId @ref IxAtmSchedulerVcId [out] - Pointer to an integer value which will be
+ * filled with the VC identifier value for the requested
+ * VC (as returned by @ref ixAtmmVcRegister), if it
+ * exists on this port.
+ *
+ * @param *vcDesc @ref IxAtmmVc [out] - Pointer to an @ref IxAtmmVc structure
+ * which will be filled with the specific details of the
+ * requested VC, if it exists on this port.
+ *
+ * @return @li IX_SUCCESS : The specified VC has been found on this port
+ * and the requested details have been returned.
+ * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
+ * input is not valid or has not been initialized. The request
+ * is rejected.
+ * @return @li IX_ATMM_RET_NO_SUCH_VC : No VC exists on the specified
+ * port which matches the search criteria (VPI, VCI, direction)
+ * given. No data is returned.
+ * @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was
+ * NULL.
+ *
+ */
+PUBLIC IX_STATUS
+ixAtmmVcQuery (IxAtmLogicalPort port,
+ unsigned vpi,
+ unsigned vci,
+ IxAtmmVcDirection direction,
+ IxAtmSchedulerVcId *vcId,
+ IxAtmmVc *vcDesc);
+
+
+/**
+ * @ingroup IxAtmm
+ *
+ * @fn ixAtmmVcIdQuery (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId, IxAtmmVc *vcDesc)
+ *
+ * @brief This interface supplies information about an active VC on a
+ * particular port when supplied with a vcId for that VC.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Identifies port on which the VC to be
+ * queried is currently registered.
+ *
+ * @param vcId @ref IxAtmSchedulerVcId [in] - Value returned by @ref ixAtmmVcRegister which
+ * uniquely identifies the requested VC on this port.
+ *
+ * @param *vcDesc @ref IxAtmmVc [out] - Pointer to an @ref IxAtmmVc structure
+ * which will be filled with the specific details of the
+ * requested VC, if it exists on this port.
+ *
+ * @return @li IX_SUCCESS : The specified VC has been found on this port
+ * and the requested details have been returned.
+ * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
+ * input is not valid or has not been initialized. The request
+ * is rejected.
+ * @return @li IX_ATMM_RET_NO_SUCH_VC : No VC exists on the specified
+ * port which matches the supplied identifier. No data is
+ * returned.
+ * @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was
+ * NULL.
+ */
+PUBLIC IX_STATUS
+ixAtmmVcIdQuery (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId, IxAtmmVc *vcDesc);
+
+/**
+ * @ingroup IxAtmm
+ *
+ * @fn ixAtmmVcChangeCallbackRegister (IxAtmmVcChangeCallback callback)
+ *
+ * @brief This interface is invoked to supply a function to IxAtmm
+ * which will be called to notify the client if a new VC is
+ * registered with IxAtmm or an existing VC is removed.
+ *
+ * The callback, when invoked, will run within the context of the call
+ * to @ref ixAtmmVcRegister or @ref ixAtmmVcDeregister which caused
+ * the change of state.
+ *
+ * A maximum of 32 calbacks may be registered in with IxAtmm.
+ *
+ * @param callback @ref IxAtmmVcChangeCallback [in] - Callback which complies
+ * with the @ref IxAtmmVcChangeCallback definition. This
+ * function will be invoked by IxAtmm with the appropiate
+ * parameters for the relevant VC when any VC has been
+ * registered or deregistered with IxAtmm.
+ *
+ * @return @li IX_SUCCESS : The specified callback has been registered
+ * successfully with IxAtmm and will be invoked when appropriate.
+ * @return @li IX_FAIL : Either the supplied callback is invalid, or
+ * IxAtmm has already registered 32 and connot accommodate
+ * any further registrations of this type. The request is
+ * rejected.
+ *
+ * @warning The client must not call either the @ref
+ * ixAtmmVcRegister or @ref ixAtmmVcDeregister interfaces
+ * from within the supplied callback function. */
+PUBLIC IX_STATUS ixAtmmVcChangeCallbackRegister (IxAtmmVcChangeCallback callback);
+
+
+/**
+ * @ingroup IxAtmm
+ *
+ * @fn ixAtmmVcChangeCallbackDeregister (IxAtmmVcChangeCallback callback)
+ *
+ * @brief This interface is invoked to deregister a previously supplied
+ * callback function.
+ *
+ * @param callback @ref IxAtmmVcChangeCallback [in] - Callback which complies
+ * with the @ref IxAtmmVcChangeCallback definition. This
+ * function will removed from the table of callbacks.
+ *
+ * @return @li IX_SUCCESS : The specified callback has been deregistered
+ * successfully from IxAtmm.
+ * @return @li IX_FAIL : Either the supplied callback is invalid, or
+ * is not currently registered with IxAtmm.
+ */
+PUBLIC IX_STATUS
+ixAtmmVcChangeCallbackDeregister (IxAtmmVcChangeCallback callback);
+
+/**
+ * @ingroup IxAtmm
+ *
+ * @fn ixAtmmUtopiaStatusShow (void)
+ *
+ * @brief Display utopia status counters
+ *
+ * @param "none"
+ *
+ * @return @li IX_SUCCESS : Show function was successful
+ * @return @li IX_FAIL : Internal failure
+ */
+PUBLIC IX_STATUS
+ixAtmmUtopiaStatusShow (void);
+
+/**
+ * @ingroup IxAtmm
+ *
+ * @fn ixAtmmUtopiaCfgShow (void)
+ *
+ * @brief Display utopia information(config registers and status registers)
+ *
+ * @param "none"
+ *
+ * @return @li IX_SUCCESS : Show function was successful
+ * @return @li IX_FAIL : Internal failure
+ */
+PUBLIC IX_STATUS
+ixAtmmUtopiaCfgShow (void);
+
+#endif
+/* IXATMM_H */
+
+/** @} */
diff --git a/cpu/ixp/npe/include/IxDmaAcc.h b/cpu/ixp/npe/include/IxDmaAcc.h
new file mode 100644
index 0000000..53d2625
--- /dev/null
+++ b/cpu/ixp/npe/include/IxDmaAcc.h
@@ -0,0 +1,260 @@
+/**
+ * @file IxDmaAcc.h
+ *
+ * @date 15 October 2002
+ *
+ * @brief API of the IXP400 DMA Access Driver Component (IxDma)
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/*---------------------------------------------------------------------
+ Doxygen group definitions
+ ---------------------------------------------------------------------*/
+
+#ifndef IXDMAACC_H
+#define IXDMAACC_H
+
+#include "IxOsal.h"
+#include "IxNpeDl.h"
+/**
+ * @defgroup IxDmaTypes IXP400 DMA Types (IxDmaTypes)
+ * @brief The common set of types used in the DMA component
+ * @{
+ */
+
+/**
+ * @ingroup IxDmaTypes
+ * @enum IxDmaReturnStatus
+ * @brief Dma return status definitions
+ */
+typedef enum
+{
+ IX_DMA_SUCCESS = IX_SUCCESS, /**< DMA Transfer Success */
+ IX_DMA_FAIL = IX_FAIL, /**< DMA Transfer Fail */
+ IX_DMA_INVALID_TRANSFER_WIDTH, /**< Invalid transfer width */
+ IX_DMA_INVALID_TRANSFER_LENGTH, /**< Invalid transfer length */
+ IX_DMA_INVALID_TRANSFER_MODE, /**< Invalid transfer mode */
+ IX_DMA_INVALID_ADDRESS_MODE, /**< Invalid address mode */
+ IX_DMA_REQUEST_FIFO_FULL /**< DMA request queue is full */
+} IxDmaReturnStatus;
+
+/**
+ * @ingroup IxDmaTypes
+ * @enum IxDmaTransferMode
+ * @brief Dma transfer mode definitions
+ * @note Copy and byte swap, and copy and reverse modes only support multiples of word data length.
+ */
+typedef enum
+{
+ IX_DMA_COPY_CLEAR = 0, /**< copy and clear source*/
+ IX_DMA_COPY, /**< copy */
+ IX_DMA_COPY_BYTE_SWAP, /**< copy and byte swap (endian) */
+ IX_DMA_COPY_REVERSE, /**< copy and reverse */
+ IX_DMA_TRANSFER_MODE_INVALID /**< Invalid transfer mode */
+} IxDmaTransferMode;
+
+/**
+ * @ingroup IxDmaTypes
+ * @enum IxDmaAddressingMode
+ * @brief Dma addressing mode definitions
+ * @note Fixed source address to fixed destination address addressing mode is not supported.
+ */
+typedef enum
+{
+ IX_DMA_INC_SRC_INC_DST = 0, /**< Incremental source address to incremental destination address */
+ IX_DMA_INC_SRC_FIX_DST, /**< Incremental source address to incremental destination address */
+ IX_DMA_FIX_SRC_INC_DST, /**< Incremental source address to incremental destination address */
+ IX_DMA_FIX_SRC_FIX_DST, /**< Incremental source address to incremental destination address */
+ IX_DMA_ADDRESSING_MODE_INVALID /**< Invalid Addressing Mode */
+} IxDmaAddressingMode;
+
+/**
+ * @ingroup IxDmaTypes
+ * @enum IxDmaTransferWidth
+ * @brief Dma transfer width definitions
+ * @Note Fixed addresses (either source or destination) do not support burst transfer width.
+ */
+typedef enum
+{
+ IX_DMA_32_SRC_32_DST = 0, /**< 32-bit src to 32-bit dst */
+ IX_DMA_32_SRC_16_DST, /**< 32-bit src to 16-bit dst */
+ IX_DMA_32_SRC_8_DST, /**< 32-bit src to 8-bit dst */
+ IX_DMA_16_SRC_32_DST, /**< 16-bit src to 32-bit dst */
+ IX_DMA_16_SRC_16_DST, /**< 16-bit src to 16-bit dst */
+ IX_DMA_16_SRC_8_DST, /**< 16-bit src to 8-bit dst */
+ IX_DMA_8_SRC_32_DST, /**< 8-bit src to 32-bit dst */
+ IX_DMA_8_SRC_16_DST, /**< 8-bit src to 16-bit dst */
+ IX_DMA_8_SRC_8_DST, /**< 8-bit src to 8-bit dst */
+ IX_DMA_8_SRC_BURST_DST, /**< 8-bit src to burst dst - Not supported for fixed destination address */
+ IX_DMA_16_SRC_BURST_DST, /**< 16-bit src to burst dst - Not supported for fixed destination address */
+ IX_DMA_32_SRC_BURST_DST, /**< 32-bit src to burst dst - Not supported for fixed destination address */
+ IX_DMA_BURST_SRC_8_DST, /**< burst src to 8-bit dst - Not supported for fixed source address */
+ IX_DMA_BURST_SRC_16_DST, /**< burst src to 16-bit dst - Not supported for fixed source address */
+ IX_DMA_BURST_SRC_32_DST, /**< burst src to 32-bit dst - Not supported for fixed source address*/
+ IX_DMA_BURST_SRC_BURST_DST, /**< burst src to burst dst - Not supported for fixed source and destination address
+*/
+ IX_DMA_TRANSFER_WIDTH_INVALID /**< Invalid transfer width */
+} IxDmaTransferWidth;
+
+/**
+ * @ingroup IxDmaTypes
+ * @enum IxDmaNpeId
+ * @brief NpeId numbers to identify NPE A, B or C
+ */
+typedef enum
+{
+ IX_DMA_NPEID_NPEA = 0, /**< Identifies NPE A */
+ IX_DMA_NPEID_NPEB, /**< Identifies NPE B */
+ IX_DMA_NPEID_NPEC, /**< Identifies NPE C */
+ IX_DMA_NPEID_MAX /**< Total Number of NPEs */
+} IxDmaNpeId;
+/* @} */
+/**
+ * @defgroup IxDmaAcc IXP400 DMA Access Driver (IxDmaAcc) API
+ *
+ * @brief The public API for the IXP400 IxDmaAcc component
+ *
+ * @{
+ */
+
+/**
+ * @ingroup IxDmaAcc
+ * @brief DMA Request Id type
+ */
+typedef UINT32 IxDmaAccRequestId;
+
+/**
+ * @ingroup IxDmaAcc
+ * @def IX_DMA_REQUEST_FULL
+ * @brief DMA request queue is full
+ * This constant is a return value used to tell the user that the IxDmaAcc
+ * queue is full.
+ *
+ */
+#define IX_DMA_REQUEST_FULL 16
+
+/**
+ * @ingroup IxDmaAcc
+ * @brief DMA completion notification
+ * This function is called to notify a client that the DMA has been completed
+ * @param status @ref IxDmaReturnStatus [out] - reporting to client
+ *
+ */
+typedef void (*IxDmaAccDmaCompleteCallback) (IxDmaReturnStatus status);
+
+/**
+ * @ingroup IxDmaAcc
+ *
+ * @fn ixDmaAccInit(IxNpeDlNpeId npeId)
+ *
+ * @brief Initialise the DMA Access component
+ * This function will initialise the DMA Access component internals
+ * @param npeId @ref IxNpeDlNpeId [in] - NPE to use for Dma Transfer
+ * @return @li IX_SUCCESS succesfully initialised the component
+ * @return @li IX_FAIL Initialisation failed for some unspecified
+ * internal reason.
+ */
+PUBLIC IX_STATUS
+ixDmaAccInit(IxNpeDlNpeId npeId);
+
+/**
+ * @ingroup IxDmaAcc
+ *
+ * @fn ixDmaAccDmaTransfer(
+ IxDmaAccDmaCompleteCallback callback,
+ UINT32 SourceAddr,
+ UINT32 DestinationAddr,
+ UINT16 TransferLength,
+ IxDmaTransferMode TransferMode,
+ IxDmaAddressingMode AddressingMode,
+ IxDmaTransferWidth TransferWidth)
+ *
+ * @brief Perform DMA transfer
+ * This function will perform DMA transfer between devices within the
+ * IXP400 memory map.
+ * @note The following are restrictions for IxDmaAccDmaTransfer:
+ * @li The function is non re-entrant.
+ * @li The function assumes host devices are operating in big-endian mode.
+ * @li Fixed address does not suport burst transfer width
+ * @li Fixed source address to fixed destinatiom address mode is not suported
+ * @li The incrementing source address for expansion bus will not support a burst transfer width and copy and clear mode
+ *
+ * @param callback @ref IxDmaAccDmaCompleteCallback [in] - function pointer to be stored and called when the DMA transfer is completed. This cannot be NULL.
+ * @param SourceAddr UINT32 [in] - Starting address of DMA source. Must be a valid IXP400 memory map address.
+ * @param DestinationAddr UINT32 [in] - Starting address of DMA destination. Must be a valid IXP400 memory map address.
+ * @param TransferLength UINT16 [in] - The size of DMA data transfer. The range must be from 1-64Kbyte
+ * @param TransferMode @ref IxDmaTransferMode [in] - The DMA transfer mode
+ * @param AddressingMode @ref IxDmaAddressingMode [in] - The DMA addressing mode
+ * @param TransferWidth @ref IxDmaTransferWidth [in] - The DMA transfer width
+ *
+ * @return @li IX_DMA_SUCCESS Notification that the DMA request is succesful
+ * @return @li IX_DMA_FAIL IxDmaAcc not yet initialised or some internal error has occured
+ * @return @li IX_DMA_INVALID_TRANSFER_WIDTH Transfer width is nit valid
+ * @return @li IX_DMA_INVALID_TRANSFER_LENGTH Transfer length outside of valid range
+ * @return @li IX_DMA_INVALID_TRANSFER_MODE Transfer Mode not valid
+ * @return @li IX_DMA_REQUEST_FIFO_FULL IxDmaAcc request queue is full
+ */
+PUBLIC IxDmaReturnStatus
+ixDmaAccDmaTransfer(
+ IxDmaAccDmaCompleteCallback callback,
+ UINT32 SourceAddr,
+ UINT32 DestinationAddr,
+ UINT16 TransferLength,
+ IxDmaTransferMode TransferMode,
+ IxDmaAddressingMode AddressingMode,
+ IxDmaTransferWidth TransferWidth);
+/**
+ * @ingroup IxDmaAcc
+ *
+ * @fn ixDmaAccShow(void)
+ *
+ * @brief Display some component information for debug purposes
+ * Show some internal operation information relating to the DMA service.
+ * At a minimum the following will show.
+ * - the number of the DMA pend (in queue)
+ * @param None
+ * @return @li None
+ */
+PUBLIC IX_STATUS
+ixDmaAccShow(void);
+
+#endif /* IXDMAACC_H */
+
diff --git a/cpu/ixp/npe/include/IxEthAcc.h b/cpu/ixp/npe/include/IxEthAcc.h
new file mode 100644
index 0000000..b424648
--- /dev/null
+++ b/cpu/ixp/npe/include/IxEthAcc.h
@@ -0,0 +1,2512 @@
+/** @file IxEthAcc.h
+ *
+ * @brief this file contains the public API of @ref IxEthAcc component
+ *
+ * Design notes:
+ * The IX_OSAL_MBUF address is to be specified on bits [31-5] and must
+ * be cache aligned (bits[4-0] cleared)
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ *
+ */
+
+#ifndef IxEthAcc_H
+#define IxEthAcc_H
+
+#include <IxOsBuffMgt.h>
+#include <IxTypes.h>
+
+/**
+ * @defgroup IxEthAcc IXP400 Ethernet Access (IxEthAcc) API
+ *
+ * @brief ethAcc is a library that does provides access to the internal IXP400 10/100Bt Ethernet MACs.
+ *
+ *@{
+ */
+
+/**
+ * @ingroup IxEthAcc
+ * @brief Definition of the Ethernet Access status
+ */
+typedef enum /* IxEthAccStatus */
+{
+ IX_ETH_ACC_SUCCESS = IX_SUCCESS, /**< return success*/
+ IX_ETH_ACC_FAIL = IX_FAIL, /**< return fail*/
+ IX_ETH_ACC_INVALID_PORT, /**< return invalid port*/
+ IX_ETH_ACC_PORT_UNINITIALIZED, /**< return uninitialized*/
+ IX_ETH_ACC_MAC_UNINITIALIZED, /**< return MAC uninitialized*/
+ IX_ETH_ACC_INVALID_ARG, /**< return invalid arg*/
+ IX_ETH_TX_Q_FULL, /**< return tx queue is full*/
+ IX_ETH_ACC_NO_SUCH_ADDR /**< return no such address*/
+} IxEthAccStatus;
+
+/**
+ * @ingroup IxEthAcc
+ * @enum IxEthAccPortId
+ * @brief Definition of the IXP400 Mac Ethernet device.
+ */
+typedef enum
+{
+ IX_ETH_PORT_1 = 0, /**< Ethernet Port 1 */
+ IX_ETH_PORT_2 = 1 /**< Ethernet port 2 */
+ ,IX_ETH_PORT_3 = 2 /**< Ethernet port 3 */
+} IxEthAccPortId;
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETH_ACC_NUMBER_OF_PORTS
+ *
+ * @brief Definition of the number of ports
+ *
+ */
+#ifdef __ixp46X
+#define IX_ETH_ACC_NUMBER_OF_PORTS (3)
+#else
+#define IX_ETH_ACC_NUMBER_OF_PORTS (2)
+#endif
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_IEEE803_MAC_ADDRESS_SIZE
+ *
+ * @brief Definition of the size of the MAC address
+ *
+ */
+#define IX_IEEE803_MAC_ADDRESS_SIZE (6)
+
+
+/**
+ *
+ * @brief Definition of the IEEE 802.3 Ethernet MAC address structure.
+ *
+ * The data should be packed with bytes xx:xx:xx:xx:xx:xx
+ * @note
+ * The data must be packed in network byte order.
+ */
+typedef struct
+{
+ UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< MAC address */
+} IxEthAccMacAddr;
+
+/**
+ * @ingroup IxEthAcc
+ * @def IX_ETH_ACC_NUM_TX_PRIORITIES
+ * @brief Definition of the number of transmit priorities
+ *
+ */
+#define IX_ETH_ACC_NUM_TX_PRIORITIES (8)
+
+/**
+ * @ingroup IxEthAcc
+ * @enum IxEthAccTxPriority
+ * @brief Definition of the relative priority used to transmit a frame
+ *
+ */
+typedef enum
+{
+ IX_ETH_ACC_TX_PRIORITY_0 = 0, /**<Lowest Priority submission */
+ IX_ETH_ACC_TX_PRIORITY_1 = 1, /**<submission prority of 1 (0 is lowest)*/
+ IX_ETH_ACC_TX_PRIORITY_2 = 2, /**<submission prority of 2 (0 is lowest)*/
+ IX_ETH_ACC_TX_PRIORITY_3 = 3, /**<submission prority of 3 (0 is lowest)*/
+ IX_ETH_ACC_TX_PRIORITY_4 = 4, /**<submission prority of 4 (0 is lowest)*/
+ IX_ETH_ACC_TX_PRIORITY_5 = 5, /**<submission prority of 5 (0 is lowest)*/
+ IX_ETH_ACC_TX_PRIORITY_6 = 6, /**<submission prority of 6 (0 is lowest)*/
+ IX_ETH_ACC_TX_PRIORITY_7 = 7, /**<Highest priority submission */
+
+ IX_ETH_ACC_TX_DEFAULT_PRIORITY = IX_ETH_ACC_TX_PRIORITY_0 /**< By default send all
+ packets with lowest priority */
+} IxEthAccTxPriority;
+
+/**
+ * @ingroup IxEthAcc
+ * @enum IxEthAccRxFrameType
+ * @brief Identify the type of a frame.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ * @sa IX_ETHACC_NE_LINKMASK
+ */
+typedef enum
+{
+ IX_ETHACC_RX_LLCTYPE = 0x00, /**< 802.3 - 8802, with LLC/SNAP */
+ IX_ETHACC_RX_ETHTYPE = 0x10, /**< 802.3 (Ethernet) without LLC/SNAP */
+ IX_ETHACC_RX_STATYPE = 0x20, /**< 802.11, AP <=> STA */
+ IX_ETHACC_RX_APTYPE = 0x30 /**< 802.11, AP <=> AP */
+} IxEthAccRxFrameType;
+
+/**
+ * @ingroup IxEthAcc
+ * @enum IxEthAccDuplexMode
+ * @brief Definition to provision the duplex mode of the MAC.
+ *
+ */
+typedef enum
+{
+ IX_ETH_ACC_FULL_DUPLEX, /**< Full duplex operation of the MAC */
+ IX_ETH_ACC_HALF_DUPLEX /**< Half duplex operation of the MAC */
+} IxEthAccDuplexMode;
+
+
+/**
+ * @ingroup IxEthAcc
+ * @struct IxEthAccNe
+ * @brief Definition of service-specific informations.
+ *
+ * This structure defines the Ethernet service-specific informations
+ * and enable QoS and VLAN features.
+ */
+typedef struct
+{
+ UINT32 ixReserved_next; /**< reserved for chaining */
+ UINT32 ixReserved_lengths; /**< reserved for buffer lengths */
+ UINT32 ixReserved_data; /**< reserved for buffer pointer */
+ UINT8 ixDestinationPortId; /**< Destination portId for this packet, if known by NPE */
+ UINT8 ixSourcePortId; /**< Source portId for this packet */
+ UINT16 ixFlags; /**< BitField of option for this frame */
+ UINT8 ixQoS; /**< QoS class of the frame */
+ UINT8 ixReserved; /**< reserved */
+ UINT16 ixVlanTCI; /**< Vlan TCI */
+ UINT8 ixDestMac[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< Destination MAC address */
+ UINT8 ixSourceMac[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< Source MAC address */
+} IxEthAccNe;
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_PORT_UNKNOWN
+ *
+ * @brief Contents of the field @a IX_ETHACC_NE_DESTPORTID when no
+ * destination port can be found by the NPE for this frame.
+ *
+ */
+#define IX_ETHACC_NE_PORT_UNKNOWN (0xff)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_DESTMAC
+ *
+ * @brief The location of the destination MAC address in the Mbuf header.
+ *
+ */
+#define IX_ETHACC_NE_DESTMAC(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixDestMac
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_SOURCEMAC
+ *
+ * @brief The location of the source MAC address in the Mbuf header.
+ *
+ */
+#define IX_ETHACC_NE_SOURCEMAC(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixSourceMac
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_VLANTCI
+ *
+ * @brief The VLAN Tag Control Information associated with this frame
+ *
+ * The VLAN Tag Control Information associated with this frame. On Rx
+ * path, this field is extracted from the packet header.
+ * On Tx path, the value of this field is inserted in the frame when
+ * the port is configured to insert or replace vlan tags in the
+ * egress frames.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ */
+#define IX_ETHACC_NE_VLANTCI(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixVlanTCI
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_SOURCEPORTID
+ *
+ * @brief The port where this frame came from.
+ *
+ * The port where this frame came from. This field is set on receive
+ * with the port information. This field is ignored on Transmit path.
+ */
+#define IX_ETHACC_NE_SOURCEPORTID(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixSourcePortId
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_DESTPORTID
+ *
+ * @brief The destination port where this frame should be sent.
+ *
+ * The destination port where this frame should be sent.
+ *
+ * @li In the transmit direction, this field contains the destination port
+ * and is ignored unless @a IX_ETHACC_NE_FLAG_DST is set.
+ *
+ * @li In the receive direction, this field contains the port where the
+ * destination MAC addresses has been learned. If the destination
+ * MAC address is unknown, then this value is set to the reserved value
+ * @a IX_ETHACC_NE_PORT_UNKNOWN
+ *
+ */
+#define IX_ETHACC_NE_DESTPORTID(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixDestinationPortId
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_QOS
+ *
+ * @brief QualityOfService class (QoS) for this received frame.
+ *
+ */
+#define IX_ETHACC_NE_QOS(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixQoS
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_FLAGS
+ *
+ * @brief Bit Mask of the different flags associated with a frame
+ *
+ * The flags are the bit-oring combination
+ * of the following different fields :
+ *
+ * @li IP flag (Rx @a IX_ETHACC_NE_IPMASK)
+ * @li Spanning Tree flag (Rx @a IX_ETHACC_NE_STMASK)
+ * @li Link layer type (Rx and Tx @a IX_ETHACC_NE_LINKMASK)
+ * @li VLAN Tagged Frame (Rx @a IX_ETHACC_NE_VLANMASK)
+ * @li New source MAC address (Rx @a IX_ETHACC_NE_NEWSRCMASK)
+ * @li Multicast flag (Rx @a IX_ETHACC_NE_MCASTMASK)
+ * @li Broadcast flag (Rx @a IX_ETHACC_NE_BCASTMASK)
+ * @li Destination port flag (Tx @a IX_ETHACC_NE_PORTMASK)
+ * @li Tag/Untag Tx frame (Tx @a IX_ETHACC_NE_TAGMODEMASK)
+ * @li Overwrite destination port (Tx @a IX_ETHACC_NE_PORTOVERMASK)
+ * @li Filtered frame (Rx @a IX_ETHACC_NE_STMASK)
+ * @li VLAN Enabled (Rx and Tx @a IX_ETHACC_NE_VLANENABLEMASK)
+ */
+#define IX_ETHACC_NE_FLAGS(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixFlags
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_BCASTMASK
+ *
+ * @brief This mask defines if a received frame is a broadcast frame.
+ *
+ * This mask defines if a received frame is a broadcast frame.
+ * The BCAST flag is set when the destination MAC address of
+ * a frame is broadcast.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ *
+ */
+#define IX_ETHACC_NE_BCASTMASK (0x1)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_MCASTMASK
+ *
+ * @brief This mask defines if a received frame is a multicast frame.
+ *
+ * This mask defines if a received frame is a multicast frame.
+ * The MCAST flag is set when the destination MAC address of
+ * a frame is multicast.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ *
+ */
+#define IX_ETHACC_NE_MCASTMASK (0x1 << 1)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_IPMASK
+ *
+ * @brief This mask defines if a received frame is a IP frame.
+ *
+ * This mask applies to @a IX_ETHACC_NE_FLAGS and defines if a received
+ * frame is a IP frame. The IP flag is set on Rx direction, depending on
+ * the frame contents. The flag is set when the length/type field of a
+ * received frame is 0x8000.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ *
+ */
+#define IX_ETHACC_NE_IPMASK (0x1 << 2)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_VLANMASK
+ *
+ * @brief This mask defines if a received frame is VLAN tagged.
+ *
+ * This mask defines if a received frame is VLAN tagged.
+ * When set, the Rx frame is VLAN-tagged and the tag value
+ * is available thru @a IX_ETHACC_NE_VLANID.
+ * Note that when sending frames which are already tagged
+ * this flag should be set, to avoid inserting another VLAN tag.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ * @sa IX_ETHACC_NE_VLANID
+ *
+ */
+#define IX_ETHACC_NE_VLANMASK (0x1 << 3)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_LINKMASK
+ *
+ * @brief This mask is the link layer protocol indicator
+ *
+ * This mask applies to @a IX_ETHACC_NE_FLAGS.
+ * It reflects the state of a frame as it exits an NPE on the Rx path
+ * or enters an NPE on the Tx path. Its values are as follows:
+ * @li 0x00 - IEEE802.3 - 8802 (Rx) / IEEE802.3 - 8802 (Tx)
+ * @li 0x01 - IEEE802.3 - Ethernet (Rx) / IEEE802.3 - Ethernet (Tx)
+ * @li 0x02 - IEEE802.11 AP -> STA (Rx) / IEEE802.11 STA -> AP (Tx)
+ * @li 0x03 - IEEE802.11 AP -> AP (Rx) / IEEE802.11 AP->AP (Tx)
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ *
+ */
+#define IX_ETHACC_NE_LINKMASK (0x3 << 4)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_STMASK
+ *
+ * @brief This mask defines if a received frame is a Spanning Tree frame.
+ *
+ * This mask applies to @a IX_ETHACC_NE_FLAGS.
+ * On rx direction, it defines if a received if frame is a Spanning Tree frame.
+ * Setting this fkag on transmit direction overrides the port settings
+ * regarding the VLAN options and
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ *
+ */
+#define IX_ETHACC_NE_STMASK (0x1 << 6)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_FILTERMASK
+ *
+ * @brief This bit indicates whether a frame has been filtered by the Rx service.
+ *
+ * This mask applies to @a IX_ETHACC_NE_FLAGS.
+ * Certain frames, which should normally be fully filtered by the NPE to due
+ * the destination MAC address being on the same segment as the Rx port are
+ * still forwarded to the XScale (although the payload is invalid) in order
+ * to learn the MAC address of the transmitting station, if this is unknown.
+ * Normally EthAcc will filter and recycle these framess internally and no
+ * frames with the FILTER bit set will be received by the client.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ *
+ */
+#define IX_ETHACC_NE_FILTERMASK (0x1 << 7)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_PORTMASK
+ *
+ * @brief This mask defines the rule to transmit a frame
+ *
+ * This mask defines the rule to transmit a frame. When set, a frame
+ * is transmitted to the destination port as set by the macro
+ * @a IX_ETHACC_NE_DESTPORTID. If not set, the destination port
+ * is searched using the destination MAC address.
+ *
+ * @note This flag is meaningful only for multiport Network Engines.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ * @sa IX_ETHACC_NE_DESTPORTID
+ *
+ */
+#define IX_ETHACC_NE_PORTOVERMASK (0x1 << 8)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_TAGMODEMASK
+ *
+ * @brief This mask defines the tagging rules to apply to a transmit frame.
+ *
+ * This mask defines the tagging rules to apply to a transmit frame
+ * regardless of the default setting for a port. When used together
+ * with @a IX_ETHACC_NE_TAGOVERMASK and when set, the
+ * frame will be tagged prior to transmission. When not set,
+ * the frame will be untagged prior to transmission. This is accomplished
+ * irrespective of the Egress tagging rules, constituting a per-frame override.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ * @sa IX_ETHACC_NE_TAGOVERMASK
+ *
+ */
+#define IX_ETHACC_NE_TAGMODEMASK (0x1 << 9)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_TAGOVERMASK
+ *
+ * @brief This mask defines the rule to transmit a frame
+ *
+ * This mask defines the rule to transmit a frame. When set, the
+ * default transmit rules of a port are overriden.
+ * When not set, the default rules as set by @ref IxEthDB should apply.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ * @sa IX_ETHACC_NE_TAGMODEMASK
+ *
+ */
+#define IX_ETHACC_NE_TAGOVERMASK (0x1 << 10)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_VLANENABLEMASK
+ *
+ * @brief This mask defines if a frame is a VLAN frame or not
+ *
+ * When set, frames undergo normal VLAN processing on the Tx path
+ * (membership filtering, tagging, tag removal etc). If this flag is
+ * not set, the frame is considered to be a regular non-VLAN frame
+ * and no VLAN processing will be performed.
+ *
+ * Note that VLAN-enabled NPE images will always set this flag in all
+ * Rx frames, and images which are not VLAN enabled will clear this
+ * flag for all received frames.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ *
+ */
+#define IX_ETHACC_NE_VLANENABLEMASK (0x1 << 14)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_NEWSRCMASK
+ *
+ * @brief This mask defines if a received frame has been learned.
+ *
+ * This mask defines if the source MAC address of a frame is
+ * already known. If the bit is set, the source MAC address was
+ * unknown to the NPE at the time the frame was received.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ *
+ */
+#define IX_ETHACC_NE_NEWSRCMASK (0x1 << 15)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @brief This defines the recommanded minimum size of MBUF's submitted
+ * to the frame receive service.
+ *
+ */
+#define IX_ETHACC_RX_MBUF_MIN_SIZE (2048)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @brief This defines the highest MII address of any attached PHYs
+ *
+ * The maximum number for PHY address is 31, add on for range checking.
+ *
+ */
+#define IXP425_ETH_ACC_MII_MAX_ADDR 32
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccInit(void)
+ *
+ * @brief Initializes the IXP400 Ethernet Access Service.
+ *
+ * @li Reentrant - no
+ * @li ISR Callable - no
+ *
+ * This should be called once per module initialization.
+ * @pre
+ * The NPE must first be downloaded with the required microcode which supports all
+ * required features.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : Service has failed to initialize.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccInit(void);
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccUnload(void)
+ *
+ * @brief Unload the Ethernet Access Service.
+ *
+ * @li Reentrant - no
+ * @li ISR Callable - no
+ *
+ * @return void
+ *
+ * <hr>
+ */
+PUBLIC void ixEthAccUnload(void);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortInit( IxEthAccPortId portId)
+ *
+ * @brief Initializes an NPE/Ethernet MAC Port.
+ *
+ * The NPE/Ethernet port initialisation includes the following steps
+ * @li Initialize the NPE/Ethernet MAC hardware.
+ * @li Verify NPE downloaded and operational.
+ * @li The NPE shall be available for usage once this API returns.
+ * @li Verify that the Ethernet port is present before initializing
+ *
+ * @li Reentrant - no
+ * @li ISR Callable - no
+ *
+ * This should be called once per mac device.
+ * The NPE/MAC shall be in disabled state after init.
+ *
+ * @pre
+ * The component must be initialized via @a ixEthAccInit
+ * The NPE must first be downloaded with the required microcode which supports all
+ * required features.
+ *
+ * Dependant on Services: (Must be initialized before using this service may be initialized)
+ * ixNPEmh - NPE Message handling service.
+ * ixQmgr - Queue Manager component.
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS: if the ethernet port is not present, a warning is issued.
+ * @li @a IX_ETH_ACC_FAIL : The NPE processor has failed to initialize.
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccPortInit(IxEthAccPortId portId);
+
+
+/*************************************************************************
+
+ ##### ## ##### ## ##### ## ##### # #
+ # # # # # # # # # # # # # #
+ # # # # # # # # # # # # ######
+ # # ###### # ###### ##### ###### # # #
+ # # # # # # # # # # # # #
+ ##### # # # # # # # # # # #
+
+*************************************************************************/
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortTxFrameSubmit(
+ IxEthAccPortId portId,
+ IX_OSAL_MBUF *buffer,
+ IxEthAccTxPriority priority)
+ *
+ * @brief This function shall be used to submit MBUFs buffers for transmission on a particular MAC device.
+ *
+ * When the frame is transmitted, the buffer shall be returned thru the
+ * callback @a IxEthAccPortTxDoneCallback.
+ *
+ * In case of over-submitting, the order of the frames on the
+ * network may be modified.
+ *
+ * Buffers shall be not queued for transmission if the port is disabled.
+ * The port can be enabled using @a ixEthAccPortEnable
+ *
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - yes
+ *
+ *
+ * @pre
+ * @a ixEthAccPortTxDoneCallbackRegister must be called to register a function to allow this service to
+ * return the buffer to the calling service.
+ *
+ * @note
+ * If the buffer submit fails for any reason the user has retained ownership of the buffer.
+ *
+ * @param portId @ref IxEthAccPortId [in] - MAC port ID to transmit Ethernet frame on.
+ * @param buffer @ref IX_OSAL_MBUF [in] - pointer to an MBUF formatted buffer. Chained buffers are supported for transmission.
+ * Chained packets are not supported and the field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is ignored.
+ * @param priority @ref IxEthAccTxPriority [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : Failed to queue frame for transmission.
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+
+PUBLIC IxEthAccStatus ixEthAccPortTxFrameSubmit(
+ IxEthAccPortId portId,
+ IX_OSAL_MBUF *buffer,
+ IxEthAccTxPriority priority);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @brief Function prototype for Ethernet Tx Buffer Done callback. Registered
+ * via @a ixEthAccTxBufferDoneCallbackRegister
+ *
+ * This function is called once the previously submitted buffer is no longer required by this service.
+ * It may be returned upon successful transmission of the frame or during the shutdown of
+ * the port prior to the transmission of a queued frame.
+ * The calling of this registered function is not a guarantee of successful transmission of the buffer.
+ *
+ *
+ * @li Reentrant - yes , The user provided function should be reentrant.
+ * @li ISR Callable - yes , The user provided function must be callable from an ISR.
+ *
+ *
+ * <b>Calling Context </b>:
+ * @par
+ * This callback is called in the context of the queue manager dispatch loop @a ixQmgrgrDispatcherLoopRun
+ * within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread.
+ * The decision is system specific.
+ *
+ * @param callbackTag UINT32 [in] - This tag is that provided when the callback was registered for a particular MAC
+ * via @a ixEthAccPortTxDoneCallbackRegister. It allows the same callback to be used for multiple MACs.
+ * @param mbuf @ref IX_OSAL_MBUF [in] - Pointer to the Tx mbuf descriptor.
+ *
+ * @return void
+ *
+ * @note
+ * The field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is modified by the access layer and reset to NULL.
+ *
+ * <hr>
+ */
+typedef void (*IxEthAccPortTxDoneCallback) ( UINT32 callbackTag, IX_OSAL_MBUF *buffer );
+
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortTxDoneCallbackRegister( IxEthAccPortId portId,
+ IxEthAccPortTxDoneCallback txCallbackFn,
+ UINT32 callbackTag)
+ *
+ * @brief Register a callback function to allow
+ * the transmitted buffers to return to the user.
+ *
+ * This function registers the transmit buffer done function callback for a particular port.
+ *
+ * The registered callback function is called once the previously submitted buffer is no longer required by this service.
+ * It may be returned upon successful transmission of the frame or shutdown of port prior to submission.
+ * The calling of this registered function is not a guarantee of successful transmission of the buffer.
+ *
+ * If called several times the latest callback shall be registered for a particular port.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - yes
+ *
+ * @pre
+ * The port must be initialized via @a ixEthAccPortInit
+ *
+ *
+ * @param portId @ref IxEthAccPortId [in] - Register callback for a particular MAC device.
+ * @param txCallbackFn @ref IxEthAccPortTxDoneCallback [in] - Function to be called to return transmit buffers to the user.
+ * @param callbackTag UINT32 [in] - This tag shall be provided to the callback function.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortTxDoneCallbackRegister(IxEthAccPortId portId,
+ IxEthAccPortTxDoneCallback txCallbackFn,
+ UINT32 callbackTag);
+
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @brief Function prototype for Ethernet Frame Rx callback. Registered via @a ixEthAccPortRxCallbackRegister
+ *
+ * It is the responsibility of the user function to free any MBUF's which it receives.
+ *
+ * @li Reentrant - yes , The user provided function should be reentrant.
+ * @li ISR Callable - yes , The user provided function must be callable from an ISR.
+ * @par
+ *
+ * This function dispatches frames to the user level
+ * via the provided function. The invocation shall be made for each
+ * frame dequeued from the Ethernet QM queue. The user is required to free any MBUF's
+ * supplied via this callback. In addition the registered callback must free up MBUF's
+ * from the receive free queue when the port is disabled
+ *
+ * If called several times the latest callback shall be registered for a particular port.
+ *
+ * <b>Calling Context </b>:
+ * @par
+ * This callback is called in the context of the queue manager dispatch loop @a ixQmgrgrDispatcherLoopRun
+ * within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread.
+ * The decision is system specific.
+ *
+ *
+ * @param callbackTag UINT32 [in] - This tag is that provided when the callback was registered for a particular MAC
+ * via @a ixEthAccPortRxCallbackRegister. It allows the same callback to be used for multiple MACs.
+ * @param mbuf @ref IX_OSAL_MBUF [in] - Pointer to the Rx mbuf header. Mbufs may be chained if
+ * the frame length is greater than the supplied mbuf length.
+ * @param reserved [in] - deprecated parameter The information is passed
+ * thru the IxEthAccNe header destination port ID field
+ * (@sa IX_ETHACC_NE_DESTPORTID). For backward
+ * compatibility,the value is equal to IX_ETH_DB_UNKNOWN_PORT (0xff).
+ *
+ * @return void
+ *
+ * @note
+ * Buffers may not be filled up to the length supplied in
+ * @a ixEthAccPortRxFreeReplenish(). The firmware fills
+ * them to the previous 64 bytes boundary. The user has to be aware
+ * that the length of the received mbufs may be smaller than the length
+ * of the supplied mbufs.
+ * The mbuf header contains the following modified field
+ * @li @a IX_OSAL_MBUF_PKT_LEN is set in the header of the first mbuf and indicates
+ * the total frame size
+ * @li @a IX_OSAL_MBUF_MLEN is set each mbuf header and indicates the payload length
+ * @li @a IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR contains a pointer to the next
+ * mbuf, or NULL at the end of a chain.
+ * @li @a IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is modified. Its value is reset to NULL
+ * @li @a IX_OSAL_MBUF_FLAGS contains the bit 4 set for a broadcast packet and the bit 5
+ * set for a multicast packet. Other bits are unmodified.
+ *
+ * <hr>
+ */
+typedef void (*IxEthAccPortRxCallback) (UINT32 callbackTag, IX_OSAL_MBUF *buffer, UINT32 reserved);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @brief Function prototype for Ethernet Frame Rx callback. Registered via @a ixEthAccPortMultiBufferRxCallbackRegister
+ *
+ * It is the responsibility of the user function to free any MBUF's which it receives.
+ *
+ * @li Reentrant - yes , The user provided function should be reentrant.
+ * @li ISR Callable - yes , The user provided function must be callable from an ISR.
+ * @par
+ *
+ * This function dispatches many frames to the user level
+ * via the provided function. The invocation shall be made for multiple frames
+ * dequeued from the Ethernet QM queue. The user is required to free any MBUF's
+ * supplied via this callback. In addition the registered callback must free up MBUF's
+ * from the receive free queue when the port is disabled
+ *
+ * If called several times the latest callback shall be registered for a particular port.
+ *
+ * <b>Calling Context </b>:
+ * @par
+ * This callback is called in the context of the queue manager dispatch loop @a ixQmgrDispatcherLoopRun
+ * within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread.
+ * The decision is system specific.
+ *
+ *
+ * @param callbackTag - This tag is that provided when the callback was registered for a particular MAC
+ * via @a ixEthAccPortMultiBufferRxCallbackRegister. It allows the same callback to be used for multiple MACs.
+ * @param mbuf - Pointer to an array of Rx mbuf headers. Mbufs
+ * may be chained if
+ * the frame length is greater than the supplied mbuf length.
+ * The end of the array contains a zeroed entry (NULL pointer).
+ *
+ * @return void
+ *
+ * @note The mbufs passed to this callback have the same structure than the
+ * buffers passed to @a IxEthAccPortRxCallback interfac.
+ *
+ * @note The usage of this callback is exclusive with the usage of
+ * @a ixEthAccPortRxCallbackRegister and @a IxEthAccPortRxCallback
+ *
+ * @sa ixEthAccPortMultiBufferRxCallbackRegister
+ * @sa IxEthAccPortMultiBufferRxCallback
+ * @sa ixEthAccPortRxCallbackRegister
+ * @sa IxEthAccPortRxCallback
+ * <hr>
+ */
+
+typedef void (*IxEthAccPortMultiBufferRxCallback) (UINT32 callbackTag, IX_OSAL_MBUF **buffer);
+
+
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortRxCallbackRegister( IxEthAccPortId portId, IxEthAccPortRxCallback rxCallbackFn, UINT32 callbackTag)
+ *
+ * @brief Register a callback function to allow
+ * the reception of frames.
+ *
+ * The registered callback function is called once a frame is received by this service.
+ *
+ * If called several times the latest callback shall be registered for a particular port.
+ *
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - yes
+ *
+ *
+ * @param portId @ref IxEthAccPortId [in] - Register callback for a particular MAC device.
+ * @param rxCallbackFn @ref IxEthAccPortRxCallback [in] - Function to be called when Ethernet frames are availble.
+ * @param callbackTag UINT32 [in] - This tag shall be provided to the callback function.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortRxCallbackRegister(IxEthAccPortId portId,
+ IxEthAccPortRxCallback rxCallbackFn,
+ UINT32 callbackTag);
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortMultiBufferRxCallbackRegister( IxEthAccPortId portId, IxEthAccPortMultiBufferRxCallback rxCallbackFn, UINT32 callbackTag)
+ *
+ * @brief Register a callback function to allow
+ * the reception of frames.
+ *
+ * The registered callback function is called once a frame is
+ * received by this service. If many frames are already received,
+ * the function is called once.
+ *
+ * If called several times the latest callback shall be registered for a particular port.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - yes
+ *
+ *
+ * @param portId - Register callback for a particular MAC device.
+ * @param rxCallbackFn - @a IxEthAccMultiBufferRxCallbackFn - Function to be called when Ethernet frames are availble.
+ * @param callbackTag - This tag shall be provided to the callback function.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid.
+ *
+ * @sa ixEthAccPortMultiBufferRxCallbackRegister
+ * @sa IxEthAccPortMultiBufferRxCallback
+ * @sa ixEthAccPortRxCallbackRegister
+ * @sa IxEthAccPortRxCallback
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortMultiBufferRxCallbackRegister(IxEthAccPortId portId,
+ IxEthAccPortMultiBufferRxCallback rxCallbackFn,
+ UINT32 callbackTag);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortRxFreeReplenish( IxEthAccPortId portId, IX_OSAL_MBUF *buffer)
+ *
+ * @brief This function provides buffers for the Ethernet receive path.
+ *
+ * This component does not have a buffer management mechanisms built in. All Rx buffers must be supplied to it
+ * via this interface.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - yes
+ *
+ * @param portId @ref IxEthAccPortId [in] - Provide buffers only to specific Rx MAC.
+ * @param buffer @ref IX_OSAL_MBUF [in] - Provide an MBUF to the Ethernet receive mechanism.
+ * Buffers size smaller than IX_ETHACC_RX_MBUF_MIN_SIZE may result in poor
+ * performances and excessive buffer chaining. Buffers
+ * larger than this size may be suitable for jumbo frames.
+ * Chained packets are not supported and the field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR must be NULL.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : Buffer has was not able to queue the
+ * buffer in the receive service.
+ * @li @a IX_ETH_ACC_FAIL : Buffer size is less than IX_ETHACC_RX_MBUF_MIN_SIZE
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * @note
+ * If the buffer replenish operation fails it is the responsibility
+ * of the user to free the buffer.
+ *
+ * @note
+ * Sufficient buffers must be supplied to the component to maintain
+ * receive throughput and avoid rx buffer underflow conditions.
+ * To meet this goal, It is expected that the user preload the
+ * component with a sufficent number of buffers prior to enabling the
+ * NPE Ethernet receive path. The recommended minimum number of
+ * buffers is 8.
+ *
+ * @note
+ * For maximum performances, the mbuf size should be greater
+ * than the maximum frame size (Ethernet header, payload and FCS) + 64.
+ * Supplying smaller mbufs to the service results in mbuf
+ * chaining and degraded performances. The recommended size
+ * is @a IX_ETHACC_RX_MBUF_MIN_SIZE, which is
+ * enough to take care of 802.3 frames and "baby jumbo" frames without
+ * chaining, and "jumbo" frame within chaining.
+ *
+ * @note
+ * Buffers may not be filled up to their length. The firware fills
+ * them up to the previous 64 bytes boundary. The user has to be aware
+ * that the length of the received mbufs may be smaller than the length
+ * of the supplied mbufs.
+ *
+ * @warning This function checks the parameters if the NDEBUG
+ * flag is not defined. Turning on the argument checking (disabled by
+ * default) results in a lower EthAcc performance as this function
+ * is part of the data path.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortRxFreeReplenish( IxEthAccPortId portId, IX_OSAL_MBUF *buffer);
+
+
+
+/***************************************************************
+
+ #### #### # # ##### ##### #### #
+ # # # # ## # # # # # # #
+ # # # # # # # # # # # #
+ # # # # # # # ##### # # #
+ # # # # # ## # # # # # #
+ #### #### # # # # # #### ######
+
+
+ ##### # ## # # ######
+ # # # # # ## # #
+ # # # # # # # # #####
+ ##### # ###### # # # #
+ # # # # # ## #
+ # ###### # # # # ######
+
+***************************************************************/
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortEnable(IxEthAccPortId portId)
+ *
+ * @brief This enables an Ethernet port for both Tx and Rx.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @pre The port must first be initialized via @a ixEthAccPortInit and the MAC address
+ * must be set using @a ixEthAccUnicastMacAddressSet before enabling it
+ * The rx and Tx Done callbacks registration via @a
+ * ixEthAccPortTxDoneCallbackRegister amd @a ixEthAccPortRxCallbackRegister
+ * has to be done before enabling the traffic.
+ *
+ * @param portId @ref IxEthAccPortId [in] - Port id to act upon.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is not initialized
+ * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccPortEnable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortDisable(IxEthAccPortId portId)
+ *
+ * @brief This disables an Ethernet port for both Tx and Rx.
+ *
+ * Free MBufs are returned to the user via the registered callback when the port is disabled
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @pre The port must be enabled with @a ixEthAccPortEnable, otherwise this
+ * function has no effect
+ *
+ * @param portId @ref IxEthAccPortId [in] - Port id to act upon.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is not initialized
+ * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccPortDisable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled)
+ *
+ * @brief Get the enabled state of a port.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - yes
+ *
+ * @pre The port must first be initialized via @a ixEthAccPortInit
+ *
+ * @param portId @ref IxEthAccPortId [in] - Port id to act upon.
+ * @param enabled BOOL [out] - location to store the state of the port
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId)
+ *
+ * @brief Put the Ethernet MAC device in non-promiscuous mode.
+ *
+ * In non-promiscuous mode the MAC filters all frames other than
+ * destination MAC address which matches the following criteria:
+ * @li Unicast address provisioned via @a ixEthAccUnicastMacAddressSet
+ * @li All broadcast frames.
+ * @li Multicast addresses provisioned via @a ixEthAccMulticastAddressJoin
+ *
+ * Other functions modify the MAC filtering
+ *
+ * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast
+ * frames are forwarded to the application
+ * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the
+ * effects of @a ixEthAccPortMulticastAddressJoinAll()
+ * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new
+ * filtering address
+ * @li @a ixEthAccPortMulticastAddressJoin() - provision a new
+ * filtering address
+ * @li @a ixEthAccPortPromiscuousModeSet() - all frames are
+ * forwarded to the application regardless of the multicast
+ * address provisioned
+ * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded
+ * to the application following the multicast address provisioned
+ *
+ * In all cases, unicast and broadcast addresses are forwarded to
+ * the application.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @sa ixEthAccPortPromiscuousModeSet
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId);
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId)
+ *
+ * @brief Put the MAC device in promiscuous mode.
+ *
+ * If the device is in promiscuous mode then all all received frames shall be forwared
+ * to the NPE for processing.
+ *
+ * Other functions modify the MAC filtering
+ *
+ * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast
+ * frames are forwarded to the application
+ * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the
+ * effects of @a ixEthAccPortMulticastAddressJoinAll()
+ * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new
+ * filtering address
+ * @li @a ixEthAccPortMulticastAddressJoin() - provision a new
+ * filtering address
+ * @li @a ixEthAccPortPromiscuousModeSet() - all frames are
+ * forwarded to the application regardless of the multicast
+ * address provisioned
+ * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded
+ * to the application following the multicast address provisioned
+ *
+ * In all cases, unicast and broadcast addresses are forwarded to
+ * the application.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @sa ixEthAccPortPromiscuousModeClear
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortUnicastMacAddressSet( IxEthAccPortId portId,
+ IxEthAccMacAddr *macAddr)
+ *
+ * @brief Configure unicast MAC address for a particular port
+ *
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressSet(IxEthAccPortId portId,
+ IxEthAccMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortUnicastMacAddressGet( IxEthAccPortId portId,
+ IxEthAccMacAddr *macAddr)
+ *
+ * @brief Get unicast MAC address for a particular MAC port
+ *
+ * @pre
+ * The MAC address must first be set via @a ixEthAccMacPromiscuousModeSet
+ * If the MAC address has not been set, the function returns a
+ * IX_ETH_ACC_MAC_UNINITIALIZED status
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ * @param *macAddr @ref IxEthAccMacAddr [out] - Ethernet MAC address.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized.
+ * @li @a IX_ETH_ACC_FAIL : macAddr is invalid.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortUnicastMacAddressGet(IxEthAccPortId portId,
+ IxEthAccMacAddr *macAddr);
+
+
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortMulticastAddressJoin( IxEthAccPortId portId,
+ IxEthAccMacAddr *macAddr)
+ *
+ * @brief Add a multicast address to the MAC address table.
+ *
+ * @note
+ * Due to the operation of the Ethernet MAC multicast filtering mechanism, frames which do not
+ * have a multicast destination address which were provisioned via this API may be forwarded
+ * to the NPE's. This is a result of the hardware comparison algorithm used in the destination mac address logic
+ * within the Ethernet MAC.
+ *
+ * See Also: IXP425 hardware development manual.
+ *
+ * Other functions modify the MAC filtering
+ *
+ * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast
+ * frames are forwarded to the application
+ * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the
+ * effects of @a ixEthAccPortMulticastAddressJoinAll()
+ * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new
+ * filtering address
+ * @li @a ixEthAccPortMulticastAddressJoin() - provision a new
+ * filtering address
+ * @li @a ixEthAccPortPromiscuousModeSet() - all frames are
+ * forwarded to the application regardless of the multicast
+ * address provisioned
+ * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded
+ * to the application following the multicast address provisioned
+ *
+ * In all cases, unicast and broadcast addresses are forwarded to
+ * the application.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : Error writing to the MAC registers
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortMulticastAddressJoin(IxEthAccPortId portId,
+ IxEthAccMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortMulticastAddressJoinAll( IxEthAccPortId portId)
+ *
+ * @brief Filter all frames with multicast dest.
+ *
+ * This function clears the MAC address table, and then sets
+ * the MAC to forward ALL multicast frames to the NPE.
+ * Specifically, it forwards all frames whose destination address
+ * has the LSB of the highest byte set (01:00:00:00:00:00). This
+ * bit is commonly referred to as the "multicast bit".
+ * Broadcast frames will still be forwarded.
+ *
+ * Other functions modify the MAC filtering
+ *
+ * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast
+ * frames are forwarded to the application
+ * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the
+ * effects of @a ixEthAccPortMulticastAddressJoinAll()
+ * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new
+ * filtering address
+ * @li @a ixEthAccPortMulticastAddressJoin() - provision a new
+ * filtering address
+ * @li @a ixEthAccPortPromiscuousModeSet() - all frames are
+ * forwarded to the application regardless of the multicast
+ * address provisioned
+ * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded
+ * to the application following the multicast address provisioned
+ *
+ * In all cases, unicast and broadcast addresses are forwarded to
+ * the application.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortMulticastAddressJoinAll(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortMulticastAddressLeave( IxEthAccPortId portId,
+ IxEthAccMacAddr *macAddr)
+ *
+ * @brief Remove a multicast address from the MAC address table.
+ *
+ * Other functions modify the MAC filtering
+ *
+ * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast
+ * frames are forwarded to the application
+ * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the
+ * effects of @a ixEthAccPortMulticastAddressJoinAll()
+ * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new
+ * filtering address
+ * @li @a ixEthAccPortMulticastAddressJoin() - provision a new
+ * filtering address
+ * @li @a ixEthAccPortPromiscuousModeSet() - all frames are
+ * forwarded to the application regardless of the multicast
+ * address provisioned
+ * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded
+ * to the application following the multicast address provisioned
+ *
+ * In all cases, unicast and broadcast addresses are forwarded to
+ * the application.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_NO_SUCH_ADDR : Failed if MAC address was not in the table.
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortMulticastAddressLeave(IxEthAccPortId portId,
+ IxEthAccMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortMulticastAddressLeaveAll( IxEthAccPortId portId)
+ *
+ * @brief This function unconfigures the multicast filtering settings
+ *
+ * This function first clears the MAC address table, and then sets
+ * the MAC as configured by the promiscuous mode current settings.
+ *
+ * Other functions modify the MAC filtering
+ *
+ * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast
+ * frames are forwarded to the application
+ * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the
+ * effects of @a ixEthAccPortMulticastAddressJoinAll()
+ * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new
+ * filtering address
+ * @li @a ixEthAccPortMulticastAddressJoin() - provision a new
+ * filtering address
+ * @li @a ixEthAccPortPromiscuousModeSet() - all frames are
+ * forwarded to the application regardless of the multicast
+ * address provisioned
+ * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded
+ * to the application following the multicast address provisioned
+ *
+ * In all cases, unicast and broadcast addresses are forwarded to
+ * the application.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortMulticastAddressLeaveAll(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortUnicastAddressShow(IxEthAccPortId portId)
+ *
+ * @brief Displays unicast MAC address
+ *
+ * Displays unicast address which is configured using
+ * @a ixEthAccUnicastMacAddressSet. This function also displays the MAC filter used
+ * to filter multicast frames.
+ *
+ * Other functions modify the MAC filtering
+ *
+ * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast
+ * frames are forwarded to the application
+ * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the
+ * effects of @a ixEthAccPortMulticastAddressJoinAll()
+ * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new
+ * filtering address
+ * @li @a ixEthAccPortMulticastAddressJoin() - provision a new
+ * filtering address
+ * @li @a ixEthAccPortPromiscuousModeSet() - all frames are
+ * forwarded to the application regardless of the multicast
+ * address provisioned
+ * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded
+ * to the application following the multicast address provisioned
+ *
+ * In all cases, unicast and broadcast addresses are forwarded to
+ * the application.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ *
+ * @return void
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccPortUnicastAddressShow(IxEthAccPortId portId);
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortMulticastAddressShow( IxEthAccPortId portId)
+ *
+ * @brief Displays multicast MAC address
+ *
+ * Displays multicast address which have been configured using @a ixEthAccMulticastAddressJoin
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ *
+ * @return void
+ *
+ * <hr>
+ */
+PUBLIC void ixEthAccPortMulticastAddressShow( IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortDuplexModeSet( IxEthAccPortId portId, IxEthAccDuplexMode mode )
+ *
+ * @brief Set the duplex mode for the MAC.
+ *
+ * Configure the IXP400 MAC to either full or half duplex.
+ *
+ * @note
+ * The configuration should match that provisioned on the PHY.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ * @param mode @ref IxEthAccDuplexMode [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortDuplexModeSet(IxEthAccPortId portId,IxEthAccDuplexMode mode);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortDuplexModeGet( IxEthAccPortId portId, IxEthAccDuplexMode *mode )
+ *
+ * @brief Get the duplex mode for the MAC.
+ *
+ * return the duplex configuration of the IXP400 MAC.
+ *
+ * @note
+ * The configuration should match that provisioned on the PHY.
+ * See @a ixEthAccDuplexModeSet
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ * @param *mode @ref IxEthAccDuplexMode [out]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ *
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortDuplexModeGet(IxEthAccPortId portId,IxEthAccDuplexMode *mode );
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortTxFrameAppendPaddingEnable( IxEthAccPortId portId)
+ *
+ * @brief Enable padding bytes to be appended to runt frames submitted to
+ * this port
+ *
+ * Enable up to 60 null-bytes padding bytes to be appended to runt frames
+ * submitted to this port. This is the default behavior of the access
+ * component.
+ *
+ * @warning Do not change this behaviour while the port is enabled.
+ *
+ * @note When Tx padding is enabled, Tx FCS generation is turned on
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @sa ixEthAccPortTxFrameAppendFCSDusable
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortTxFrameAppendPaddingEnable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortTxFrameAppendPaddingDisable( IxEthAccPortId portId)
+ *
+ * @brief Disable padding bytes to be appended to runt frames submitted to
+ * this port
+ *
+ * Disable padding bytes to be appended to runt frames
+ * submitted to this port. This is not the default behavior of the access
+ * component.
+ *
+ * @warning Do not change this behaviour while the port is enabled.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortTxFrameAppendPaddingDisable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortTxFrameAppendFCSEnable( IxEthAccPortId portId)
+ *
+ * @brief Enable the appending of Ethernet FCS to all frames submitted to this port
+ *
+ * When enabled, the FCS is added to the submitted frames. This is the default
+ * behavior of the access component.
+ * Do not change this behaviour while the port is enabled.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortTxFrameAppendFCSEnable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortTxFrameAppendFCSDisable( IxEthAccPortId portId)
+ *
+ * @brief Disable the appending of Ethernet FCS to all frames submitted to this port.
+ *
+ * When disabled, the Ethernet FCS is not added to the submitted frames.
+ * This is not the default
+ * behavior of the access component.
+ *
+ * @note Since the FCS is not appended to the frame it is expected that the frame submitted to the
+ * component includes a valid FCS at the end of the data, although this will not be validated.
+ *
+ * The component shall forward the frame to the Ethernet MAC WITHOUT modification.
+ *
+ * Do not change this behaviour while the port is enabled.
+ *
+ * @note Tx FCS append is not disabled while Tx padding is enabled.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @sa ixEthAccPortTxFrameAppendPaddingEnable
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortTxFrameAppendFCSDisable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortRxFrameAppendFCSEnable( IxEthAccPortId portId)
+ *
+ * @brief Forward frames with FCS included in the receive buffer.
+ *
+ * The FCS is not striped from the receive buffer.
+ * The received frame length includes the FCS size (4 bytes). ie.
+ * A minimum sized ethernet frame shall have a length of 64bytes.
+ *
+ * Frame FCS validity checks are still carried out on all received frames.
+ *
+ * This is not the default
+ * behavior of the access component.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortRxFrameAppendFCSEnable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortRxFrameAppendFCSDisable( IxEthAccPortId portId)
+ *
+ * @brief Do not forward the FCS portion of the received Ethernet frame to the user.
+ * The FCS is striped from the receive buffer.
+ * The received frame length does not include the FCS size (4 bytes).
+ * Frame FCS validity checks are still carried out on all received frames.
+ *
+ * This is the default behavior of the component.
+ * Do not change this behaviour while the port is enabled.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortRxFrameAppendFCSDisable(IxEthAccPortId portId);
+
+
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @enum IxEthAccSchedulerDiscipline
+ *
+ * @brief Definition for the port scheduling discipline
+ *
+ * Select the port scheduling discipline on receive and transmit path
+ * @li FIFO : No Priority : In this configuration all frames are processed
+ * in the access component in the strict order in which
+ * the component received them.
+ * @li FIFO : Priority : This shall be a very simple priority mechanism.
+ * Higher prior-ity frames shall be forwarded
+ * before lower priority frames. There shall be no
+ * fairness mechanisms applied across different
+ * priorities. Higher priority frames could starve
+ * lower priority frames indefinitely.
+ */
+typedef enum
+{
+ FIFO_NO_PRIORITY, /**<frames submitted with no priority*/
+ FIFO_PRIORITY /**<higher prority frames submitted before lower priority*/
+}IxEthAccSchedulerDiscipline;
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IxEthAccTxSchedulerDiscipline
+ *
+ * @brief Deprecated definition for the port transmit scheduling discipline
+ */
+#define IxEthAccTxSchedulerDiscipline IxEthAccSchedulerDiscipline
+
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccTxSchedulingDisciplineSet( IxEthAccPortId portId, IxEthAccSchedulerDiscipline sched)
+ *
+ * @brief Set the port scheduling to one of @a IxEthAccSchedulerDiscipline
+ *
+ * The default behavior of the component is @a FIFO_NO_PRIORITY.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ * @param sched @ref IxEthAccSchedulerDiscipline [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : Set appropriate discipline.
+ * @li @a IX_ETH_ACC_FAIL : Invalid/unsupported discipline.
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccTxSchedulingDisciplineSet(IxEthAccPortId portId,
+ IxEthAccSchedulerDiscipline sched);
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched)
+ *
+ * @brief Set the Rx scheduling to one of @a IxEthAccSchedulerDiscipline
+ *
+ * The default behavior of the component is @a FIFO_NO_PRIORITY.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @param sched : @a IxEthAccSchedulerDiscipline
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : Set appropriate discipline.
+ * @li @a IX_ETH_ACC_FAIL : Invalid/unsupported discipline.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn IxEthAccStatus ixEthAccNpeLoopbackEnable(IxEthAccPortId portId)
+ *
+ * @brief Enable NPE loopback
+ *
+ * When this loopback mode is enabled all the transmitted frames are
+ * received on the same port, without payload.
+ *
+ * This function is recommended for power-up diagnostic checks and
+ * should never be used under normal Ethernet traffic operations.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @param portId : ID of the port
+ *
+ * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is
+ * guaranteed to restore correct Ethernet Tx/Rx operation.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : NPE loopback mode enabled
+ * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortNpeLoopbackEnable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn IxEthAccStatus ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId)
+ *
+ * @brief Disable NPE loopback
+ *
+ * This function is used to disable the NPE loopback if previously
+ * enabled using ixEthAccNpeLoopbackEnable.
+ *
+ * This function is recommended for power-up diagnostic checks and
+ * should never be used under normal Ethernet traffic operations.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is
+ * guaranteed to restore correct Ethernet Tx/Rx operation.
+ *
+ * @param portId : ID of the port
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : NPE loopback successfully disabled
+ * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn IxEthAccStatus ixEthAccPortTxEnable(IxEthAccPortId portId)
+ *
+ * @brief Enable Tx on the port
+ *
+ * This function is the complement of ixEthAccPortTxDisable and should
+ * be used only after Tx was disabled. A MAC core reset is required before
+ * this function is called (see @a ixEthAccPortMacReset).
+ *
+ * This function is the recommended usage scenario for emergency security
+ * shutdown and hardware failure recovery and should never be used for throttling
+ * traffic.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is
+ * guaranteed to restore correct Ethernet Tx/Rx operation.
+ *
+ * @param portId : ID of the port
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : Tx successfully enabled
+ * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortTxEnable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn IxEthAccStatus ixEthAccPortTxDisable(IxEthAccPortId portId)
+ *
+ * @brief Disable Tx on the port
+ *
+ * This function can be used to disable Tx in the MAC core.
+ * Tx can be re-enabled, although this is not guaranteed, by performing
+ * a MAC core reset (@a ixEthAccPortMacReset) and calling ixEthAccPortTxEnable.
+ * Note that using this function is not recommended, except for shutting
+ * down Tx for emergency reasons. For proper port shutdown and re-enabling
+ * see ixEthAccPortEnable and ixEthAccPortDisable.
+ *
+ * This function is the recommended usage scenario for emergency security
+ * shutdown and hardware failure recovery and should never be used for throttling
+ * traffic.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is
+ * guaranteed to restore correct Ethernet Tx/Rx operation.
+ *
+ * @pre
+ *
+ * @param portId : ID of the port
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : Tx successfully disabled
+ * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortTxDisable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn IxEthAccStatus ixEthAccPortRxEnable(IxEthAccPortId portId)
+ *
+ * @brief Enable Rx on the port
+ *
+ * This function is the complement of ixEthAccPortRxDisable and should
+ * be used only after Rx was disabled.
+ *
+ * This function is the recommended usage scenario for emergency security
+ * shutdown and hardware failure recovery and should never be used for throttling
+ * traffic.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is
+ * guaranteed to restore correct Ethernet Tx/Rx operation.
+ *
+ * @pre
+ *
+ * @param portId : ID of the port
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : Rx successfully enabled
+ * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortRxEnable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn IxEthAccStatus ixEthAccPortRxDisable(IxEthAccPortId portId)
+ *
+ * @brief Disable Rx on the port
+ *
+ * This function can be used to disable Rx in the MAC core.
+ * Rx can be re-enabled, although this is not guaranteed, by performing
+ * a MAC core reset (@a ixEthAccPortMacReset) and calling ixEthAccPortRxEnable.
+ * Note that using this function is not recommended, except for shutting
+ * down Rx for emergency reasons. For proper port shutdown and re-enabling
+ * see ixEthAccPortEnable and ixEthAccPortDisable.
+ *
+ * This function is the recommended usage scenario for emergency security
+ * shutdown and hardware failure recovery and should never be used for throttling
+ * traffic.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is
+ * guaranteed to restore correct Ethernet Tx/Rx operation.
+ *
+ * @param portId : ID of the port
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : Rx successfully disabled
+ * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortRxDisable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn IxEthAccStatus ixEthAccPortMacReset(IxEthAccPortId portId)
+ *
+ * @brief Reset MAC core on the port
+ *
+ * This function will perform a MAC core reset (NPE Ethernet coprocessor).
+ * This function is inherently unsafe and the NPE recovery is not guaranteed
+ * after this function is called. The proper manner of performing port disable
+ * and enable (which will reset the MAC as well) is ixEthAccPortEnable/ixEthAccPortDisable.
+ *
+ * This function is the recommended usage scenario for hardware failure recovery
+ * and should never be used for throttling traffic.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is
+ * guaranteed to restore correct Ethernet Tx/Rx operation.
+ *
+ * @param portId : ID of the port
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : MAC core reset
+ * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortMacReset(IxEthAccPortId portId);
+
+/*********************************************************************************
+ #### ##### ## ##### # #### ##### # #### ####
+ # # # # # # # # # # # #
+ #### # # # # # #### # # # ####
+ # # ###### # # # # # # #
+ # # # # # # # # # # # # # # #
+ #### # # # # # #### # # #### ####
+**********************************************************************************/
+
+
+/**
+ *
+ * @brief This struct defines the statistics returned by this component.
+ *
+ * The component returns MIB2 EthObj variables which are obtained from the
+ * hardware or maintained by this component.
+ *
+ *
+ */
+typedef struct
+{
+ UINT32 dot3StatsAlignmentErrors; /**< link error count (rx) */
+ UINT32 dot3StatsFCSErrors; /**< link error count (rx) */
+ UINT32 dot3StatsInternalMacReceiveErrors; /**< link error count (rx) */
+ UINT32 RxOverrunDiscards; /**< NPE: discarded frames count (rx) */
+ UINT32 RxLearnedEntryDiscards; /**< NPE: discarded frames count(rx) */
+ UINT32 RxLargeFramesDiscards; /**< NPE: discarded frames count(rx) */
+ UINT32 RxSTPBlockedDiscards; /**< NPE: discarded frames count(rx) */
+ UINT32 RxVLANTypeFilterDiscards; /**< NPE: discarded frames count (rx) */
+ UINT32 RxVLANIdFilterDiscards; /**< NPE: discarded frames count (rx) */
+ UINT32 RxInvalidSourceDiscards; /**< NPE: discarded frames count (rx) */
+ UINT32 RxBlackListDiscards; /**< NPE: discarded frames count (rx) */
+ UINT32 RxWhiteListDiscards; /**< NPE: discarded frames count (rx) */
+ UINT32 RxUnderflowEntryDiscards; /**< NPE: discarded frames count (rx) */
+ UINT32 dot3StatsSingleCollisionFrames; /**< link error count (tx) */
+ UINT32 dot3StatsMultipleCollisionFrames; /**< link error count (tx) */
+ UINT32 dot3StatsDeferredTransmissions; /**< link error count (tx) */
+ UINT32 dot3StatsLateCollisions; /**< link error count (tx) */
+ UINT32 dot3StatsExcessiveCollsions; /**< link error count (tx) */
+ UINT32 dot3StatsInternalMacTransmitErrors; /**< link error count (tx) */
+ UINT32 dot3StatsCarrierSenseErrors; /**< link error count (tx) */
+ UINT32 TxLargeFrameDiscards; /**< NPE: discarded frames count (tx) */
+ UINT32 TxVLANIdFilterDiscards; /**< NPE: discarded frames count (tx) */
+
+}IxEthEthObjStats;
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccMibIIStatsGet(IxEthAccPortId portId ,IxEthEthObjStats *retStats )
+ *
+ * @brief Returns the statistics maintained for a port.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ * @param retStats @ref IxEthEthObjStats [out]
+ * @note Please note the user is responsible for cache coheriency of the retStat
+ * buffer. The data is actually populated via the NPE's. As such cache safe
+ * memory should be used in the retStats argument.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : Invalid arguments.
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccMibIIStatsGet(IxEthAccPortId portId, IxEthEthObjStats *retStats );
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccMibIIStatsGetClear(IxEthAccPortId portId, IxEthEthObjStats *retStats)
+ *
+ * @brief Returns and clears the statistics maintained for a port.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - yes
+ *
+ * @pre
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ * @param retStats @ref IxEthEthObjStats [out]
+ * @note Please note the user is responsible for cache coheriency of the retStats
+ * buffer. The data is actually populated via the NPE's. As such cache safe
+ * memory should be used in the retStats argument.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : invalid arguments.
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccMibIIStatsGetClear(IxEthAccPortId portId, IxEthEthObjStats *retStats);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccMibIIStatsClear(IxEthAccPortId portId)
+ *
+ * @brief Clears the statistics maintained for a port.
+ *
+ * @li Reentrant - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : Invalid arguments.
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccMibIIStatsClear(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccMacInit(IxEthAccPortId portId)
+ *
+ * @brief Initializes the ethernet MAC settings
+ *
+ * @li Reentrant - no
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccMacInit(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccStatsShow(IxEthAccPortId portId)
+ *
+ *
+ * @brief Displays a ports statistics on the standard io console using printf.
+ *
+ * @li Reentrant - no
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ *
+ * @return void
+ *
+ * <hr>
+ */
+PUBLIC void ixEthAccStatsShow(IxEthAccPortId portId);
+
+/*************************************************************************
+
+ # # # # # # ##### # ####
+ ## ## # # ## ## # # # # #
+ # ## # # # # ## # # # # # #
+ # # # # # # # # # # #
+ # # # # # # # # # # #
+ # # # # # # ##### # ####
+
+*************************************************************************/
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccMiiReadRtn (UINT8 phyAddr,
+ UINT8 phyReg,
+ UINT16 *value)
+ *
+ *
+ * @brief Reads a 16 bit value from a PHY
+ *
+ * Reads a 16-bit word from a register of a MII-compliant PHY. Reading
+ * is performed through the MII management interface. This function returns
+ * when the read operation has successfully completed, or when a timeout has elapsed.
+ *
+ * @li Reentrant - no
+ * @li ISR Callable - no
+ *
+ * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
+ *
+ * @param phyAddr UINT8 [in] - the address of the Ethernet PHY (0-31)
+ * @param phyReg UINT8 [in] - the number of the MII register to read (0-31)
+ * @param value UINT16 [in] - the value read from the register
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : failed to read the register.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccMiiReadRtn (UINT8 phyAddr, UINT8 phyReg, UINT16 *value);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccMiiWriteRtn (UINT8 phyAddr,
+ UINT8 phyReg,
+ UINT16 value)
+ *
+ *
+ * @brief Writes a 16 bit value to a PHY
+ *
+ * Writes a 16-bit word from a register of a MII-compliant PHY. Writing
+ * is performed through the MII management interface. This function returns
+ * when the write operation has successfully completed, or when a timeout has elapsed.
+ *
+ * @li Reentrant - no
+ * @li ISR Callable - no
+ *
+ * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
+ *
+ * @param phyAddr UINT8 [in] - the address of the Ethernet PHY (0-31)
+ * @param phyReg UINT8 [in] - the number of the MII register to write (0-31)
+ * @param value UINT16 [out] - the value to write to the register
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : failed to write register.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccMiiWriteRtn (UINT8 phyAddr, UINT8 phyReg, UINT16 value);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccMiiAccessTimeoutSet(UINT32 timeout)
+ *
+ * @brief Overrides the default timeout value and retry count when reading or
+ * writing MII registers using ixEthAccMiiWriteRtn or ixEthAccMiiReadRtn
+ *
+ * The default behavior of the component is to use a IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS ms
+ * timeout (declared as 100 in IxEthAccMii_p.h) and a retry count of IX_ETH_ACC_MII_TIMEOUT_10TH_SECS
+ * (declared as 5 in IxEthAccMii_p.h).
+ *
+ * The MII read and write functions will attempt to read the status of the register up
+ * to the retry count times, delaying between each attempt with the timeout value.
+ *
+ * @li Reentrant - no
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @param timeout UINT32 [in] - new timeout value, in milliseconds
+ * @param timeout UINT32 [in] - new retry count (a minimum value of 1 must be used)
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : invalid parameter(s)
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccMiiAccessTimeoutSet(UINT32 timeout, UINT32 retryCount);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccMiiStatsShow (UINT32 phyAddr)
+ *
+ *
+ * @brief Displays detailed information on a specified PHY
+ *
+ * Displays the current values of the first eigth MII registers for a PHY,
+ *
+ * @li Reentrant - no
+ * @li ISR Callable - no
+ *
+ * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and
+ * generating the MDIO clock.
+ *
+ * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31)
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : invalid arguments.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccMiiStatsShow (UINT32 phyAddr);
+
+
+
+/******* BOARD SPECIFIC DEPRECATED API *********/
+
+/* The following functions are high level functions which rely
+ * on the properties and interface of some Ethernet PHYs. The
+ * implementation is hardware specific and has been moved to
+ * the hardware-specific component IxEthMii.
+ */
+
+ #include "IxEthMii.h"
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def ixEthAccMiiPhyScan
+ *
+ * @brief : deprecated API entry point. This definition
+ * ensures backward compatibility
+ *
+ * See @ref ixEthMiiPhyScan
+ *
+ * @note this feature is board specific
+ *
+ */
+#define ixEthAccMiiPhyScan(phyPresent) ixEthMiiPhyScan(phyPresent,IXP425_ETH_ACC_MII_MAX_ADDR)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def ixEthAccMiiPhyConfig
+ *
+ * @brief : deprecated API entry point. This definition
+ * ensures backward compatibility
+ *
+ * See @ref ixEthMiiPhyConfig
+ *
+ * @note this feature is board specific
+ */
+#define ixEthAccMiiPhyConfig(phyAddr,speed100,fullDuplex,autonegotiate) \
+ ixEthMiiPhyConfig(phyAddr,speed100,fullDuplex,autonegotiate)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def ixEthAccMiiPhyReset
+ *
+ * @brief : deprecated API entry point. This definition
+ * ensures backward compatibility
+ *
+ * See @ref ixEthMiiPhyReset
+ *
+ * @note this feature is board specific
+ */
+#define ixEthAccMiiPhyReset(phyAddr) \
+ ixEthMiiPhyReset(phyAddr)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def ixEthAccMiiLinkStatus
+ *
+ * @brief : deprecated API entry point. This definition
+ * ensures backward compatibility
+ *
+ * See @ref ixEthMiiLinkStatus
+ *
+ * @note this feature is board specific
+ */
+#define ixEthAccMiiLinkStatus(phyAddr,linkUp,speed100,fullDuplex,autoneg) \
+ ixEthMiiLinkStatus(phyAddr,linkUp,speed100,fullDuplex,autoneg)
+
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def ixEthAccMiiShow
+ *
+ * @brief : deprecated API entry point. This definition
+ * ensures backward compatibility
+ *
+ * See @ref ixEthMiiPhyShow
+ *
+ * @note this feature is board specific
+ */
+#define ixEthAccMiiShow(phyAddr) \
+ ixEthMiiPhyShow(phyAddr)
+
+#endif /* ndef IxEthAcc_H */
+/**
+ *@}
+ */
diff --git a/cpu/ixp/npe/include/IxEthAccDataPlane_p.h b/cpu/ixp/npe/include/IxEthAccDataPlane_p.h
new file mode 100644
index 0000000..8b8e6b2
--- /dev/null
+++ b/cpu/ixp/npe/include/IxEthAccDataPlane_p.h
@@ -0,0 +1,245 @@
+/**
+ * @file IxEthAccDataPlane_p.h
+ *
+ * @author Intel Corporation
+ * @date 12-Feb-2002
+ *
+ * @brief Internal Header file for IXP425 Ethernet Access component.
+ *
+ * Design Notes:
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+
+#ifndef IxEthAccDataPlane_p_H
+#define IxEthAccDataPlane_p_H
+
+#include <IxOsal.h>
+#include <IxQMgr.h>
+
+/**
+ * @addtogroup IxEthAccPri
+ *@{
+ */
+
+/* typedefs global to this file*/
+
+typedef struct
+{
+ IX_OSAL_MBUF *pHead;
+ IX_OSAL_MBUF *pTail;
+}IxEthAccDataPlaneQList;
+
+
+/**
+ * @struct IxEthAccDataPlaneStats
+ * @brief Statistics data structure associated with the data plane
+ *
+ */
+typedef struct
+{
+ UINT32 addToSwQ;
+ UINT32 removeFromSwQ;
+ UINT32 unchainedTxMBufs;
+ UINT32 chainedTxMBufs;
+ UINT32 unchainedTxDoneMBufs;
+ UINT32 chainedTxDoneMBufs;
+ UINT32 unchainedRxMBufs;
+ UINT32 chainedRxMBufs;
+ UINT32 unchainedRxFreeMBufs;
+ UINT32 chainedRxFreeMBufs;
+ UINT32 rxCallbackCounter;
+ UINT32 rxCallbackBurstRead;
+ UINT32 txDoneCallbackCounter;
+ UINT32 unexpectedError;
+} IxEthAccDataPlaneStats;
+
+/**
+ * @fn ixEthAccMbufFromSwQ
+ * @brief used during disable steps to convert mbufs from
+ * swq format, ready to be pushed into hw queues for NPE,
+ * back into XScale format
+ */
+IX_OSAL_MBUF *ixEthAccMbufFromSwQ(IX_OSAL_MBUF *mbuf);
+
+/**
+ * @fn ixEthAccDataPlaneShow
+ * @brief Show function (for data plane statistics
+ */
+void ixEthAccDataPlaneShow(void);
+
+/*
+ * lock dataplane when atomic operation is required
+ */
+#define IX_ETH_ACC_DATA_PLANE_LOCK(arg) arg = ixOsalIrqLock();
+#define IX_ETH_ACC_DATA_PLANE_UNLOCK(arg) ixOsalIrqUnlock(arg);
+
+/*
+ * Use MBUF fields
+ */
+#define IX_ETHACC_NE_SHARED(mBufPtr) \
+ ((IxEthAccNe *)&((mBufPtr)->ix_ne))
+
+#if 1
+
+#define IX_ETHACC_NE_NEXT(mBufPtr) (mBufPtr)->ix_ne.reserved[0]
+
+/* tm - wrong!! len and pkt_len are in the second word - #define IX_ETHACC_NE_LEN(mBufPtr) (mBufPtr)->ix_ne.reserved[3] */
+#define IX_ETHACC_NE_LEN(mBufPtr) (mBufPtr)->ix_ne.reserved[1]
+
+#define IX_ETHACC_NE_DATA(mBufPtr)(mBufPtr)->ix_ne.reserved[2]
+
+#else
+
+#define IX_ETHACC_NE_NEXT(mBufPtr) \
+ IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_next
+
+#define IX_ETHACC_NE_LEN(mBufPtr) \
+ IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_lengths
+
+#define IX_ETHACC_NE_DATA(mBufPtr) \
+ IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_data
+#endif
+
+/*
+ * Use MBUF next pointer field to chain data.
+ */
+#define IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER(mbuf) (mbuf)->ix_ctrl.ix_chain
+
+
+
+#define IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(mbuf_list) ((mbuf_list.pHead) == NULL)
+
+
+#define IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(mbuf_list,mbuf_to_add) \
+ do { \
+ int lockVal; \
+ IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); \
+ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.addToSwQ); \
+ if ( (mbuf_list.pHead) != NULL ) \
+ { \
+ (IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add))) = (mbuf_list.pHead);\
+ (mbuf_list.pHead) = (mbuf_to_add); \
+ } \
+ else { \
+ (mbuf_list.pTail) = (mbuf_list.pHead) = (mbuf_to_add); \
+ IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL; \
+ } \
+ IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); \
+ } while(0)
+
+
+#define IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL(mbuf_list,mbuf_to_add) \
+ do { \
+ int lockVal; \
+ IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); \
+ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.addToSwQ); \
+ if ( (mbuf_list.pHead) == NULL ) \
+ { \
+ (mbuf_list.pHead) = mbuf_to_add; \
+ IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL; \
+ } \
+ else { \
+ IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_list.pTail)) = (mbuf_to_add); \
+ IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL; \
+ } \
+ (mbuf_list.pTail) = mbuf_to_add; \
+ IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); \
+ } while (0)
+
+
+#define IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD(mbuf_list,mbuf_to_rem) \
+ do { \
+ int lockVal; \
+ IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); \
+ if ( (mbuf_list.pHead) != NULL ) \
+ { \
+ IX_ETH_ACC_STATS_INC(ixEthAccDataStats.removeFromSwQ); \
+ (mbuf_to_rem) = (mbuf_list.pHead) ; \
+ (mbuf_list.pHead) = (IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_rem)));\
+ } \
+ else { \
+ (mbuf_to_rem) = NULL; \
+ } \
+ IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); \
+ } while (0)
+
+
+/**
+ * @brief message handler QManager entries for NPE id => port ID conversion (NPE_B => 0, NPE_C => 1)
+ */
+#define IX_ETH_ACC_PORT_TO_NPE_ID(port) \
+ ixEthAccPortData[(port)].npeId
+
+#define IX_ETH_ACC_NPE_TO_PORT_ID(npe) ((npe == 0 ? 2 : (npe == 1 ? 0 : ( npe == 2 ? 1 : -1 ))))
+
+#define IX_ETH_ACC_PORT_TO_TX_Q_ID(port) \
+ ixEthAccPortData[(port)].ixEthAccTxData.txQueue
+
+#define IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(port) \
+ ixEthAccPortData[(port)].ixEthAccRxData.rxFreeQueue
+
+#define IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(port) (port == IX_ETH_PORT_1 ? IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE : (port == IX_ETH_PORT_2 ? IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE : IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE))
+
+#define IX_ETH_ACC_PORT_TO_RX_FREE_Q_SOURCE(port) (port == IX_ETH_PORT_1 ? IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE : (port == IX_ETH_PORT_2 ? IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE : IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE ))
+
+/* Flush the mbufs chain and all data pointed to by the mbuf */
+
+#ifndef NDEBUG
+#define IX_ETH_ACC_STATS_INC(x) (x++)
+#else
+#define IX_ETH_ACC_STATS_INC(x)
+#endif
+
+#define IX_ETH_ACC_MAX_TX_FRAMES_TO_SUBMIT 128
+
+void ixEthRxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId);
+void ixEthRxMultiBufferQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId);
+void ixEthTxFrameDoneQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId);
+
+#endif /* IxEthAccDataPlane_p_H */
+
+
+/**
+ *@}
+ */
+
diff --git a/cpu/ixp/npe/include/IxEthAccMac_p.h b/cpu/ixp/npe/include/IxEthAccMac_p.h
new file mode 100644
index 0000000..93e9d98
--- /dev/null
+++ b/cpu/ixp/npe/include/IxEthAccMac_p.h
@@ -0,0 +1,248 @@
+/*
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+
+#ifndef IxEthAccMac_p_H
+#define IxEthAccMac_p_H
+
+#include "IxOsal.h"
+
+#define IX_ETH_ACC_MAX_MULTICAST_ADDRESSES 256
+#define IX_ETH_ACC_NUM_PORTS 3
+#define IX_ETH_ACC_MAX_FRAME_SIZE_DEFAULT 1536
+#define IX_ETH_ACC_MAX_FRAME_SIZE_UPPER_RANGE (65536-64)
+#define IX_ETH_ACC_MAX_FRAME_SIZE_LOWER_RANGE 64
+
+/*
+ *
+ * MAC register definitions
+ *
+ */
+#define IX_ETH_ACC_MAC_0_BASE IX_OSAL_IXP400_ETHA_PHYS_BASE
+#define IX_ETH_ACC_MAC_1_BASE IX_OSAL_IXP400_ETHB_PHYS_BASE
+#define IX_ETH_ACC_MAC_2_BASE IX_OSAL_IXP400_ETH_NPEA_PHYS_BASE
+
+#define IX_ETH_ACC_MAC_TX_CNTRL1 0x000
+#define IX_ETH_ACC_MAC_TX_CNTRL2 0x004
+#define IX_ETH_ACC_MAC_RX_CNTRL1 0x010
+#define IX_ETH_ACC_MAC_RX_CNTRL2 0x014
+#define IX_ETH_ACC_MAC_RANDOM_SEED 0x020
+#define IX_ETH_ACC_MAC_THRESH_P_EMPTY 0x030
+#define IX_ETH_ACC_MAC_THRESH_P_FULL 0x038
+#define IX_ETH_ACC_MAC_BUF_SIZE_TX 0x040
+#define IX_ETH_ACC_MAC_TX_DEFER 0x050
+#define IX_ETH_ACC_MAC_RX_DEFER 0x054
+#define IX_ETH_ACC_MAC_TX_TWO_DEFER_1 0x060
+#define IX_ETH_ACC_MAC_TX_TWO_DEFER_2 0x064
+#define IX_ETH_ACC_MAC_SLOT_TIME 0x070
+#define IX_ETH_ACC_MAC_MDIO_CMD_1 0x080
+#define IX_ETH_ACC_MAC_MDIO_CMD_2 0x084
+#define IX_ETH_ACC_MAC_MDIO_CMD_3 0x088
+#define IX_ETH_ACC_MAC_MDIO_CMD_4 0x08c
+#define IX_ETH_ACC_MAC_MDIO_STS_1 0x090
+#define IX_ETH_ACC_MAC_MDIO_STS_2 0x094
+#define IX_ETH_ACC_MAC_MDIO_STS_3 0x098
+#define IX_ETH_ACC_MAC_MDIO_STS_4 0x09c
+#define IX_ETH_ACC_MAC_ADDR_MASK_1 0x0A0
+#define IX_ETH_ACC_MAC_ADDR_MASK_2 0x0A4
+#define IX_ETH_ACC_MAC_ADDR_MASK_3 0x0A8
+#define IX_ETH_ACC_MAC_ADDR_MASK_4 0x0AC
+#define IX_ETH_ACC_MAC_ADDR_MASK_5 0x0B0
+#define IX_ETH_ACC_MAC_ADDR_MASK_6 0x0B4
+#define IX_ETH_ACC_MAC_ADDR_1 0x0C0
+#define IX_ETH_ACC_MAC_ADDR_2 0x0C4
+#define IX_ETH_ACC_MAC_ADDR_3 0x0C8
+#define IX_ETH_ACC_MAC_ADDR_4 0x0CC
+#define IX_ETH_ACC_MAC_ADDR_5 0x0D0
+#define IX_ETH_ACC_MAC_ADDR_6 0x0D4
+#define IX_ETH_ACC_MAC_INT_CLK_THRESH 0x0E0
+#define IX_ETH_ACC_MAC_UNI_ADDR_1 0x0F0
+#define IX_ETH_ACC_MAC_UNI_ADDR_2 0x0F4
+#define IX_ETH_ACC_MAC_UNI_ADDR_3 0x0F8
+#define IX_ETH_ACC_MAC_UNI_ADDR_4 0x0FC
+#define IX_ETH_ACC_MAC_UNI_ADDR_5 0x100
+#define IX_ETH_ACC_MAC_UNI_ADDR_6 0x104
+#define IX_ETH_ACC_MAC_CORE_CNTRL 0x1FC
+
+
+/*
+ *
+ *Bit definitions
+ *
+ */
+
+/* TX Control Register 1*/
+
+#define IX_ETH_ACC_TX_CNTRL1_TX_EN BIT(0)
+#define IX_ETH_ACC_TX_CNTRL1_DUPLEX BIT(1)
+#define IX_ETH_ACC_TX_CNTRL1_RETRY BIT(2)
+#define IX_ETH_ACC_TX_CNTRL1_PAD_EN BIT(3)
+#define IX_ETH_ACC_TX_CNTRL1_FCS_EN BIT(4)
+#define IX_ETH_ACC_TX_CNTRL1_2DEFER BIT(5)
+#define IX_ETH_ACC_TX_CNTRL1_RMII BIT(6)
+
+/* TX Control Register 2 */
+#define IX_ETH_ACC_TX_CNTRL2_RETRIES_MASK 0xf
+
+/* RX Control Register 1 */
+#define IX_ETH_ACC_RX_CNTRL1_RX_EN BIT(0)
+#define IX_ETH_ACC_RX_CNTRL1_PADSTRIP_EN BIT(1)
+#define IX_ETH_ACC_RX_CNTRL1_CRC_EN BIT(2)
+#define IX_ETH_ACC_RX_CNTRL1_PAUSE_EN BIT(3)
+#define IX_ETH_ACC_RX_CNTRL1_LOOP_EN BIT(4)
+#define IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN BIT(5)
+#define IX_ETH_ACC_RX_CNTRL1_RX_RUNT_EN BIT(6)
+#define IX_ETH_ACC_RX_CNTRL1_BCAST_DIS BIT(7)
+
+/* RX Control Register 2 */
+#define IX_ETH_ACC_RX_CNTRL2_DEFER_EN BIT(0)
+
+
+
+/* Core Control Register */
+#define IX_ETH_ACC_CORE_RESET BIT(0)
+#define IX_ETH_ACC_CORE_RX_FIFO_FLUSH BIT(1)
+#define IX_ETH_ACC_CORE_TX_FIFO_FLUSH BIT(2)
+#define IX_ETH_ACC_CORE_SEND_JAM BIT(3)
+#define IX_ETH_ACC_CORE_MDC_EN BIT(4)
+
+/* 1st bit of 1st MAC octet */
+#define IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT ( 1)
+
+
+/*
+ *
+ * Default values
+ *
+ */
+
+
+#define IX_ETH_ACC_TX_CNTRL1_DEFAULT (IX_ETH_ACC_TX_CNTRL1_TX_EN | \
+ IX_ETH_ACC_TX_CNTRL1_RETRY | \
+ IX_ETH_ACC_TX_CNTRL1_FCS_EN | \
+ IX_ETH_ACC_TX_CNTRL1_2DEFER | \
+ IX_ETH_ACC_TX_CNTRL1_PAD_EN)
+
+#define IX_ETH_ACC_TX_MAX_RETRIES_DEFAULT 0x0f
+
+#define IX_ETH_ACC_RX_CNTRL1_DEFAULT (IX_ETH_ACC_RX_CNTRL1_CRC_EN \
+ | IX_ETH_ACC_RX_CNTRL1_RX_EN)
+
+#define IX_ETH_ACC_RX_CNTRL2_DEFAULT 0x0
+
+/* Thresholds determined by NPE firmware FS */
+#define IX_ETH_ACC_MAC_THRESH_P_EMPTY_DEFAULT 0x12
+#define IX_ETH_ACC_MAC_THRESH_P_FULL_DEFAULT 0x30
+
+/* Number of bytes that must be in the tx fifo before
+ transmission commences*/
+#define IX_ETH_ACC_MAC_BUF_SIZE_TX_DEFAULT 0x8
+
+/* One-part deferral values */
+#define IX_ETH_ACC_MAC_TX_DEFER_DEFAULT 0x15
+#define IX_ETH_ACC_MAC_RX_DEFER_DEFAULT 0x16
+
+/* Two-part deferral values... */
+#define IX_ETH_ACC_MAC_TX_TWO_DEFER_1_DEFAULT 0x08
+#define IX_ETH_ACC_MAC_TX_TWO_DEFER_2_DEFAULT 0x07
+
+/* This value applies to MII */
+#define IX_ETH_ACC_MAC_SLOT_TIME_DEFAULT 0x80
+
+/* This value applies to RMII */
+#define IX_ETH_ACC_MAC_SLOT_TIME_RMII_DEFAULT 0xFF
+
+#define IX_ETH_ACC_MAC_ADDR_MASK_DEFAULT 0xFF
+
+#define IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT 0x1
+/*The following is a value chosen at random*/
+#define IX_ETH_ACC_RANDOM_SEED_DEFAULT 0x8
+
+/*By default we must configure the MAC to generate the
+ MDC clock*/
+#define IX_ETH_ACC_CORE_DEFAULT (IX_ETH_ACC_CORE_MDC_EN)
+
+#define IXP425_ETH_ACC_MAX_PHY 2
+#define IXP425_ETH_ACC_MAX_AN_ENTRIES 20
+#define IX_ETH_ACC_MAC_RESET_DELAY 1
+
+#define IX_ETH_ACC_MAC_ALL_BITS_SET 0xFF
+
+#define IX_ETH_ACC_MAC_MSGID_SHL 24
+
+#define IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS 20
+#define IX_ETH_ACC_PORT_DISABLE_DELAY_COUNT 200 /* 4 seconds timeout */
+#define IX_ETH_ACC_PORT_DISABLE_RETRY_COUNT 3
+#define IX_ETH_ACC_MIB_STATS_DELAY_MSECS 2000 /* 2 seconds delay for ethernet stats */
+
+/*Register access macros*/
+#if (CPU == SIMSPARCSOLARIS)
+extern void registerWriteStub (UINT32 base, UINT32 offset, UINT32 val);
+extern UINT32 registerReadStub (UINT32 base, UINT32 offset);
+
+#define REG_WRITE(b,o,v) registerWriteStub(b, o, v)
+#define REG_READ(b,o,v) do { v = registerReadStub(b, o); } while (0)
+#else
+#define REG_WRITE(b,o,v) IX_OSAL_WRITE_LONG((volatile UINT32 *)(b + o), v)
+#define REG_READ(b,o,v) (v = IX_OSAL_READ_LONG((volatile UINT32 *)(b + o)))
+
+#endif
+
+void ixEthAccMacUnload(void);
+IxEthAccStatus ixEthAccMacMemInit(void);
+
+/* MAC core loopback */
+IxEthAccStatus ixEthAccPortLoopbackEnable(IxEthAccPortId portId);
+IxEthAccStatus ixEthAccPortLoopbackDisable(IxEthAccPortId portId);
+
+/* MAC core traffic control */
+IxEthAccStatus ixEthAccPortTxEnablePriv(IxEthAccPortId portId);
+IxEthAccStatus ixEthAccPortTxDisablePriv(IxEthAccPortId portId);
+IxEthAccStatus ixEthAccPortRxEnablePriv(IxEthAccPortId portId);
+IxEthAccStatus ixEthAccPortRxDisablePriv(IxEthAccPortId portId);
+IxEthAccStatus ixEthAccPortMacResetPriv(IxEthAccPortId portId);
+
+/* NPE software loopback */
+IxEthAccStatus ixEthAccNpeLoopbackDisablePriv(IxEthAccPortId portId);
+IxEthAccStatus ixEthAccNpeLoopbackEnablePriv(IxEthAccPortId portId);
+
+#endif /*IxEthAccMac_p_H*/
+
diff --git a/cpu/ixp/npe/include/IxEthAccMii_p.h b/cpu/ixp/npe/include/IxEthAccMii_p.h
new file mode 100644
index 0000000..aa42f9c
--- /dev/null
+++ b/cpu/ixp/npe/include/IxEthAccMii_p.h
@@ -0,0 +1,97 @@
+/**
+ * @file IxEthAccMii_p.h
+ *
+ * @author Intel Corporation
+ * @date
+ *
+ * @brief MII Header file
+ *
+ * Design Notes:
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxEthAccMii_p_H
+#define IxEthAccMii_p_H
+
+/* MII definitions - these have been verified against the LXT971 and LXT972 PHYs*/
+
+#define IXP425_ETH_ACC_MII_MAX_REG 32 /* max register per phy */
+
+#define IX_ETH_ACC_MII_REG_SHL 16
+#define IX_ETH_ACC_MII_ADDR_SHL 21
+
+/* Definitions for MII access routines*/
+
+#define IX_ETH_ACC_MII_GO BIT(31)
+#define IX_ETH_ACC_MII_WRITE BIT(26)
+#define IX_ETH_ACC_MII_TIMEOUT_10TH_SECS 5
+#define IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS 100
+#define IX_ETH_ACC_MII_READ_FAIL BIT(31)
+
+#define IX_ETH_ACC_MII_PHY_DEF_DELAY 300 /* max delay before link up, etc. */
+#define IX_ETH_ACC_MII_PHY_NO_DELAY 0x0 /* do not delay */
+#define IX_ETH_ACC_MII_PHY_NULL 0xff /* PHY is not present */
+#define IX_ETH_ACC_MII_PHY_DEF_ADDR 0x0 /* default PHY's logical address */
+
+#ifndef IX_ETH_ACC_MII_MONITOR_DELAY
+# define IX_ETH_ACC_MII_MONITOR_DELAY 0x5 /* in seconds */
+#endif
+
+/* Register definition */
+
+#define IX_ETH_ACC_MII_CTRL_REG 0x0 /* Control Register */
+#define IX_ETH_ACC_MII_STAT_REG 0x1 /* Status Register */
+#define IX_ETH_ACC_MII_PHY_ID1_REG 0x2 /* PHY identifier 1 Register */
+#define IX_ETH_ACC_MII_PHY_ID2_REG 0x3 /* PHY identifier 2 Register */
+#define IX_ETH_ACC_MII_AN_ADS_REG 0x4 /* Auto-Negotiation */
+ /* Advertisement Register */
+#define IX_ETH_ACC_MII_AN_PRTN_REG 0x5 /* Auto-Negotiation */
+ /* partner ability Register */
+#define IX_ETH_ACC_MII_AN_EXP_REG 0x6 /* Auto-Negotiation */
+ /* Expansion Register */
+#define IX_ETH_ACC_MII_AN_NEXT_REG 0x7 /* Auto-Negotiation */
+ /* next-page transmit Register */
+
+IxEthAccStatus ixEthAccMdioShow (void);
+IxEthAccStatus ixEthAccMiiInit(void);
+void ixEthAccMiiUnload(void);
+
+#endif /*IxEthAccMii_p_H*/
diff --git a/cpu/ixp/npe/include/IxEthAccQueueAssign_p.h b/cpu/ixp/npe/include/IxEthAccQueueAssign_p.h
new file mode 100644
index 0000000..e5fd16e
--- /dev/null
+++ b/cpu/ixp/npe/include/IxEthAccQueueAssign_p.h
@@ -0,0 +1,137 @@
+/**
+ * @file IxEthAccQueueAssign_p.h
+ *
+ * @author Intel Corporation
+ * @date 06-Mar-2002
+ *
+ * @brief Mapping from QMgr Q's to internal assignment
+ *
+ * Design Notes:
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @addtogroup IxEthAccPri
+ *@{
+ */
+
+/*
+ * Os/System dependancies.
+ */
+#include "IxOsal.h"
+
+/*
+ * Intermodule dependancies
+ */
+#include "IxQMgr.h"
+#include "IxQueueAssignments.h"
+
+/* Check range of Q's assigned to this component. */
+#if IX_ETH_ACC_RX_FRAME_ETH_Q >= (IX_QMGR_MIN_QUEUPP_QID ) | \
+ IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \
+ IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \
+ IX_ETH_ACC_TX_FRAME_ENET0_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \
+ IX_ETH_ACC_TX_FRAME_ENET1_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \
+ IX_ETH_ACC_TX_FRAME_DONE_ETH_Q >= (IX_QMGR_MIN_QUEUPP_QID)
+#error "Not all Ethernet Access Queues are betweem 1-31, requires full functionalty Q's unless otherwise validated "
+#endif
+
+/**
+*
+* @typedef IxEthAccQregInfo
+*
+* @brief
+*
+*/
+typedef struct
+{
+ IxQMgrQId qId;
+ char *qName;
+ IxQMgrCallback qCallback;
+ IxQMgrCallbackId callbackTag;
+ IxQMgrQSizeInWords qSize;
+ IxQMgrQEntrySizeInWords qWords;
+ BOOL qNotificationEnableAtStartup;
+ IxQMgrSourceId qConditionSource;
+ IxQMgrWMLevel AlmostEmptyThreshold;
+ IxQMgrWMLevel AlmostFullThreshold;
+
+} IxEthAccQregInfo;
+
+/*
+ * Prototypes for all QM callbacks.
+ */
+
+/*
+ * Rx Callbacks
+ */
+IX_ETH_ACC_PUBLIC
+void ixEthRxFrameQMCallback(IxQMgrQId, IxQMgrCallbackId);
+
+IX_ETH_ACC_PUBLIC
+void ixEthRxMultiBufferQMCallback(IxQMgrQId, IxQMgrCallbackId);
+
+IX_ETH_ACC_PUBLIC
+void ixEthRxFreeQMCallback(IxQMgrQId, IxQMgrCallbackId);
+
+/*
+ * Tx Callback.
+ */
+IX_ETH_ACC_PUBLIC
+void ixEthTxFrameQMCallback(IxQMgrQId, IxQMgrCallbackId);
+
+IX_ETH_ACC_PUBLIC
+void ixEthTxFrameDoneQMCallback(IxQMgrQId, IxQMgrCallbackId );
+
+
+#define IX_ETH_ACC_QM_QUEUE_DISPATCH_PRIORITY (IX_QMGR_Q_PRIORITY_0) /* Highest priority */
+
+/*
+ * Queue watermarks
+ */
+#define IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_NOT_E )
+#define IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
+#define IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
+#define IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
+#define IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
+#define IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
+#define IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E )
+#define IX_ETH_ACC_TX_FRAME_DONE_ETH_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_NOT_E )
diff --git a/cpu/ixp/npe/include/IxEthAcc_p.h b/cpu/ixp/npe/include/IxEthAcc_p.h
new file mode 100644
index 0000000..37c5560
--- /dev/null
+++ b/cpu/ixp/npe/include/IxEthAcc_p.h
@@ -0,0 +1,325 @@
+/**
+ * @file IxEthAcc_p.h
+ *
+ * @author Intel Corporation
+ * @date 12-Feb-2002
+ *
+ * @brief Internal Header file for IXP425 Ethernet Access component.
+ *
+ * Design Notes:
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @addtogroup IxEthAccPri
+ *@{
+ */
+
+#ifndef IxEthAcc_p_H
+#define IxEthAcc_p_H
+
+/*
+ * Os/System dependancies.
+ */
+#include "IxOsal.h"
+
+/*
+ * Intermodule dependancies
+ */
+#include "IxNpeDl.h"
+#include "IxQMgr.h"
+
+#include "IxEthNpe.h"
+
+/*
+ * Intra module dependancies
+ */
+
+#include "IxEthAccDataPlane_p.h"
+#include "IxEthAccMac_p.h"
+
+
+#define INLINE __inline__
+
+#ifdef NDEBUG
+
+#define IX_ETH_ACC_PRIVATE static
+
+#else
+
+#define IX_ETH_ACC_PRIVATE
+
+#endif /* ndef NDEBUG */
+
+#define IX_ETH_ACC_PUBLIC
+
+
+#define IX_ETH_ACC_IS_PORT_VALID(port) ((port) < IX_ETH_ACC_NUMBER_OF_PORTS ? TRUE : FALSE )
+
+
+
+#ifndef NDEBUG
+#define IX_ETH_ACC_FATAL_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
+#define IX_ETH_ACC_WARNING_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_WARNING,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
+#define IX_ETH_ACC_DEBUG_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
+#else
+#define IX_ETH_ACC_FATAL_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
+#define IX_ETH_ACC_WARNING_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_WARNING,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
+#define IX_ETH_ACC_DEBUG_LOG(a,b,c,d,e,f,g) {}
+#endif
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccInitDataPlane(void);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccQMgrQueuesConfig(void);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccSingleEthNpeCheck(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC void ixEthAccQMgrRxQEntryGet(UINT32 *numRxQueueEntries);
+
+/* prototypes for the private control plane functions (used by the control interface wrapper) */
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortEnablePriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDisablePriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortEnabledQueryPriv(IxEthAccPortId portId, BOOL *enabled);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeClearPriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeSetPriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressSetPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressGetPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressJoinPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressJoinAllPriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressLeavePriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressLeaveAllPriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastAddressShowPriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC void ixEthAccPortMulticastAddressShowPriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDuplexModeSetPriv(IxEthAccPortId portId, IxEthAccDuplexMode mode);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDuplexModeGetPriv(IxEthAccPortId portId, IxEthAccDuplexMode *mode);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendPaddingEnablePriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendPaddingDisablePriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendFCSEnablePriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendFCSDisablePriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortRxFrameAppendFCSEnablePriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortRxFrameAppendFCSDisablePriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccTxSchedulingDisciplineSetPriv(IxEthAccPortId portId, IxEthAccSchedulerDiscipline sched);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccRxSchedulingDisciplineSetPriv(IxEthAccSchedulerDiscipline sched);
+
+/**
+ * @struct ixEthAccRxDataStats
+ * @brief Stats data structures for data path. - Not obtained from h/w
+ *
+ */
+typedef struct
+{
+ UINT32 rxFrameClientCallback;
+ UINT32 rxFreeRepOK;
+ UINT32 rxFreeRepDelayed;
+ UINT32 rxFreeRepFromSwQOK;
+ UINT32 rxFreeRepFromSwQDelayed;
+ UINT32 rxFreeLateNotificationEnabled;
+ UINT32 rxFreeLowCallback;
+ UINT32 rxFreeOverflow;
+ UINT32 rxFreeLock;
+ UINT32 rxDuringDisable;
+ UINT32 rxSwQDuringDisable;
+ UINT32 rxUnlearnedMacAddress;
+ UINT32 rxPriority[IX_ETH_ACC_TX_PRIORITY_7 + 1];
+ UINT32 rxUnexpectedError;
+ UINT32 rxFiltered;
+} IxEthAccRxDataStats;
+
+/**
+ * @struct IxEthAccTxDataStats
+ * @brief Stats data structures for data path. - Not obtained from h/w
+ *
+ */
+typedef struct
+{
+ UINT32 txQOK;
+ UINT32 txQDelayed;
+ UINT32 txFromSwQOK;
+ UINT32 txFromSwQDelayed;
+ UINT32 txLowThreshCallback;
+ UINT32 txDoneClientCallback;
+ UINT32 txDoneClientCallbackDisable;
+ UINT32 txOverflow;
+ UINT32 txLock;
+ UINT32 txPriority[IX_ETH_ACC_TX_PRIORITY_7 + 1];
+ UINT32 txLateNotificationEnabled;
+ UINT32 txDoneDuringDisable;
+ UINT32 txDoneSwQDuringDisable;
+ UINT32 txUnexpectedError;
+} IxEthAccTxDataStats;
+
+/* port Disable state machine : list of states */
+typedef enum
+{
+ /* general port states */
+ DISABLED = 0,
+ ACTIVE,
+
+ /* particular Tx/Rx states */
+ REPLENISH,
+ RECEIVE,
+ TRANSMIT,
+ TRANSMIT_DONE
+} IxEthAccPortDisableState;
+
+typedef struct
+{
+ BOOL fullDuplex;
+ BOOL rxFCSAppend;
+ BOOL txFCSAppend;
+ BOOL txPADAppend;
+ BOOL enabled;
+ BOOL promiscuous;
+ BOOL joinAll;
+ IxOsalMutex ackMIBStatsLock;
+ IxOsalMutex ackMIBStatsResetLock;
+ IxOsalMutex MIBStatsGetAccessLock;
+ IxOsalMutex MIBStatsGetResetAccessLock;
+ IxOsalMutex npeLoopbackMessageLock;
+ IxEthAccMacAddr mcastAddrsTable[IX_ETH_ACC_MAX_MULTICAST_ADDRESSES];
+ UINT32 mcastAddrIndex;
+ IX_OSAL_MBUF *portDisableTxMbufPtr;
+ IX_OSAL_MBUF *portDisableRxMbufPtr;
+
+ volatile IxEthAccPortDisableState portDisableState;
+ volatile IxEthAccPortDisableState rxState;
+ volatile IxEthAccPortDisableState txState;
+
+ BOOL initDone;
+ BOOL macInitialised;
+} IxEthAccMacState;
+
+/**
+ * @struct IxEthAccRxInfo
+ * @brief System-wide data structures associated with the data plane.
+ *
+ */
+typedef struct
+{
+ IxQMgrQId higherPriorityQueue[IX_QMGR_MAX_NUM_QUEUES]; /**< higher priority queue list */
+ IxEthAccSchedulerDiscipline schDiscipline; /**< Receive Xscale QoS type */
+} IxEthAccInfo;
+
+/**
+ * @struct IxEthAccRxDataInfo
+ * @brief Per Port data structures associated with the receive data plane.
+ *
+ */
+typedef struct
+{
+ IxQMgrQId rxFreeQueue; /**< rxFree Queue for this port */
+ IxEthAccPortRxCallback rxCallbackFn;
+ UINT32 rxCallbackTag;
+ IxEthAccDataPlaneQList freeBufferList;
+ IxEthAccPortMultiBufferRxCallback rxMultiBufferCallbackFn;
+ UINT32 rxMultiBufferCallbackTag;
+ BOOL rxMultiBufferCallbackInUse;
+ IxEthAccRxDataStats stats; /**< Receive s/w stats */
+} IxEthAccRxDataInfo;
+
+/**
+ * @struct IxEthAccTxDataInfo
+ * @brief Per Port data structures associated with the transmit data plane.
+ *
+ */
+typedef struct
+{
+ IxEthAccPortTxDoneCallback txBufferDoneCallbackFn;
+ UINT32 txCallbackTag;
+ IxEthAccDataPlaneQList txQ[IX_ETH_ACC_NUM_TX_PRIORITIES]; /**< Transmit Q */
+ IxEthAccSchedulerDiscipline schDiscipline; /**< Transmit Xscale QoS */
+ IxQMgrQId txQueue; /**< txQueue for this port */
+ IxEthAccTxDataStats stats; /**< Transmit s/w stats */
+} IxEthAccTxDataInfo;
+
+
+/**
+ * @struct IxEthAccPortDataInfo
+ * @brief Per Port data structures associated with the port data plane.
+ *
+ */
+typedef struct
+{
+ BOOL portInitialized;
+ UINT32 npeId; /**< NpeId for this port */
+ IxEthAccTxDataInfo ixEthAccTxData; /**< Transmit data control structures */
+ IxEthAccRxDataInfo ixEthAccRxData; /**< Recieve data control structures */
+} IxEthAccPortDataInfo;
+
+extern IxEthAccPortDataInfo ixEthAccPortData[];
+#define IX_ETH_IS_PORT_INITIALIZED(port) (ixEthAccPortData[port].portInitialized)
+
+extern BOOL ixEthAccServiceInit;
+#define IX_ETH_ACC_IS_SERVICE_INITIALIZED() (ixEthAccServiceInit == TRUE )
+
+/*
+ * Maximum number of frames to consume from the Rx Frame Q.
+ */
+
+#define IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK (128)
+
+/*
+ * Max number of times to load the Rx Free Q from callback.
+ */
+#define IX_ETH_ACC_MAX_RX_FREE_BUFFERS_LOAD (256) /* Set greater than depth of h/w Q + drain time at line rate */
+
+/*
+ * Max number of times to read from the Tx Done Q in one sitting.
+ */
+
+#define IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK (256)
+
+/*
+ * Max number of times to take buffers from S/w queues and write them to the H/w Tx
+ * queues on receipt of a Tx low threshold callback
+ */
+
+#define IX_ETH_ACC_MAX_TX_FRAME_TX_CONSUME_PER_CALLBACK (16)
+
+
+#define IX_ETH_ACC_FLUSH_CACHE(addr,size) IX_OSAL_CACHE_FLUSH((addr),(size))
+#define IX_ETH_ACC_INVALIDATE_CACHE(addr,size) IX_OSAL_CACHE_INVALIDATE((addr),(size))
+
+
+#define IX_ETH_ACC_MEMSET(start,value,size) memset(start,value,size)
+
+#endif /* ndef IxEthAcc_p_H */
+
+
+
diff --git a/cpu/ixp/npe/include/IxEthDB.h b/cpu/ixp/npe/include/IxEthDB.h
new file mode 100644
index 0000000..1189c9a
--- /dev/null
+++ b/cpu/ixp/npe/include/IxEthDB.h
@@ -0,0 +1,2373 @@
+/** @file IxEthDB.h
+ *
+ * @brief this file contains the public API of @ref IxEthDB component
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ *
+ */
+
+#ifndef IxEthDB_H
+#define IxEthDB_H
+
+#include <IxOsBuffMgt.h>
+#include <IxTypes.h>
+
+/**
+ * @defgroup IxEthDB IXP400 Ethernet Database (IxEthDB) API
+ *
+ * @brief ethDB is a library that does provides a MAC address database learning/filtering capability
+ *
+ *@{
+ */
+
+#define INLINE __inline__
+
+#define IX_ETH_DB_PRIVATE PRIVATE /* imported from IxTypes.h */
+
+#define IX_ETH_DB_PUBLIC PUBLIC
+
+/**
+ * @brief port ID => message handler NPE id conversion (0 => NPE_B, 1 => NPE_C)
+ */
+#define IX_ETH_DB_PORT_ID_TO_NPE(id) (id == 0 ? 1 : (id == 1 ? 2 : (id == 2 ? 0 : -1)))
+
+/**
+ * @def IX_ETH_DB_NPE_TO_PORT_ID(npe)
+ * @brief message handler NPE id => port ID conversion (NPE_B => 0, NPE_C => 1)
+ */
+#define IX_ETH_DB_NPE_TO_PORT_ID(npe) (npe == 0 ? 2 : (npe == 1 ? 0 : (npe == 2 ? 1 : -1)))
+
+/* temporary define - won't work for Azusa */
+#define IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(id) (IX_ETH_DB_PORT_ID_TO_NPE(id) << 4)
+#define IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(id) (IX_ETH_DB_NPE_TO_PORT_ID(id >> 4))
+
+/**
+ * @def IX_IEEE803_MAC_ADDRESS_SIZE
+ * @brief The size of the MAC address
+ */
+#define IX_IEEE803_MAC_ADDRESS_SIZE (6)
+
+/**
+ * @def IX_IEEE802_1Q_QOS_PRIORITY_COUNT
+ * @brief Number of QoS priorities defined by IEEE802.1Q
+ */
+#define IX_IEEE802_1Q_QOS_PRIORITY_COUNT (8)
+
+/**
+ * @enum IxEthDBStatus
+ * @brief Ethernet Database API return values
+ */
+typedef enum /* IxEthDBStatus */
+{
+ IX_ETH_DB_SUCCESS = IX_SUCCESS, /**< Success */
+ IX_ETH_DB_FAIL = IX_FAIL, /**< Failure */
+ IX_ETH_DB_INVALID_PORT, /**< Invalid port */
+ IX_ETH_DB_PORT_UNINITIALIZED, /**< Port not initialized */
+ IX_ETH_DB_MAC_UNINITIALIZED, /**< MAC not initialized */
+ IX_ETH_DB_INVALID_ARG, /**< Invalid argument */
+ IX_ETH_DB_NO_SUCH_ADDR, /**< Address not found for search or delete operations */
+ IX_ETH_DB_NOMEM, /**< Learning database memory full */
+ IX_ETH_DB_BUSY, /**< Learning database cannot complete operation, access temporarily blocked */
+ IX_ETH_DB_END, /**< Database browser passed the end of the record set */
+ IX_ETH_DB_INVALID_VLAN, /**< Invalid VLAN ID (valid range is 0..4094, 0 signifies no VLAN membership, used for priority tagged frames) */
+ IX_ETH_DB_INVALID_PRIORITY, /**< Invalid QoS priority/traffic class (valid range for QoS priority is 0..7, valid range for traffic class depends on run-time configuration) */
+ IX_ETH_DB_NO_PERMISSION, /**< No permission for attempted operation */
+ IX_ETH_DB_FEATURE_UNAVAILABLE, /**< Feature not available (or not enabled) */
+ IX_ETH_DB_INVALID_KEY, /**< Invalid search key */
+ IX_ETH_DB_INVALID_RECORD_TYPE /**< Invalid record type */
+} IxEthDBStatus;
+
+/** @brief VLAN ID type, valid range is 0..4094, 0 signifying no VLAN membership */
+typedef UINT32 IxEthDBVlanId;
+
+/** @brief 802.1Q VLAN tag, contains 3 bits user priority, 1 bit CFI, 12 bits VLAN ID */
+typedef UINT32 IxEthDBVlanTag;
+
+/** @brief QoS priority/traffic class type, valid range is 0..7, 0 being the lowest */
+typedef UINT32 IxEthDBPriority;
+
+/** @brief Priority mapping table; 0..7 QoS priorities used to index, table contains traffic classes */
+typedef UINT8 IxEthDBPriorityTable[8];
+
+/** @brief A 4096 bit array used to map the complete VLAN ID range */
+typedef UINT8 IxEthDBVlanSet[512];
+
+#define IX_ETH_DB_802_1Q_VLAN_MASK (0xFFF)
+#define IX_ETH_DB_802_1Q_QOS_MASK (0x7)
+
+#define IX_ETH_DB_802_1Q_MAX_VLAN_ID (0xFFE)
+
+/**
+ * @def IX_ETH_DB_SET_VLAN_ID
+ * @brief returns the given 802.1Q tag with the VLAN ID field substituted with the given VLAN ID
+ *
+ * This macro is used to change the VLAN ID in a 802.1Q tag.
+ *
+ * Example:
+ *
+ * tag = IX_ETH_DB_SET_VLAN_ID(tag, 32)
+ *
+ * inserts the VLAN ID "32" in the given tag.
+ */
+#define IX_ETH_DB_SET_VLAN_ID(vlanTag, vlanID) (((vlanTag) & 0xF000) | ((vlanID) & IX_ETH_DB_802_1Q_VLAN_MASK))
+
+/**
+* @def IX_ETH_DB_GET_VLAN_ID
+* @brief returns the VLAN ID from the given 802.1Q tag
+*/
+#define IX_ETH_DB_GET_VLAN_ID(vlanTag) ((vlanTag) & IX_ETH_DB_802_1Q_VLAN_MASK)
+
+#define IX_ETH_DB_GET_QOS_PRIORITY(vlanTag) (((vlanTag) >> 13) & IX_ETH_DB_802_1Q_QOS_MASK)
+
+#define IX_ETH_DB_SET_QOS_PRIORITY(vlanTag, priority) (((vlanTag) & 0x1FFF) | (((priority) & IX_ETH_DB_802_1Q_QOS_MASK) << 13))
+
+#define IX_ETH_DB_CHECK_VLAN_TAG(vlanTag) { if(((vlanTag & 0xFFFF0000) != 0) || (IX_ETH_DB_GET_VLAN_ID(vlanTag) > 4094)) return IX_ETH_DB_INVALID_VLAN; }
+
+#define IX_ETH_DB_CHECK_VLAN_ID(vlanId) { if (vlanId > IX_ETH_DB_802_1Q_MAX_VLAN_ID) return IX_ETH_DB_INVALID_VLAN; }
+
+#define IX_IEEE802_1Q_VLAN_TPID (0x8100)
+
+typedef enum
+{
+ IX_ETH_DB_UNTAGGED_FRAMES = 0x1, /**< Accepts untagged frames */
+ IX_ETH_DB_VLAN_TAGGED_FRAMES = 0x2, /**< Accepts tagged frames */
+ IX_ETH_DB_PRIORITY_TAGGED_FRAMES = 0x4, /**< Accepts tagged frames with VLAN ID set to 0 (no VLAN membership) */
+ IX_ETH_DB_ACCEPT_ALL_FRAMES =
+ IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES /**< Accepts all the frames */
+} IxEthDBFrameFilter;
+
+typedef enum
+{
+ IX_ETH_DB_PASS_THROUGH = 0x1, /**< Leave frame as-is */
+ IX_ETH_DB_ADD_TAG = 0x2, /**< Add default port VLAN tag */
+ IX_ETH_DB_REMOVE_TAG = 0x3 /**< Remove VLAN tag from frame */
+} IxEthDBTaggingAction;
+
+typedef enum
+{
+ IX_ETH_DB_FIREWALL_WHITE_LIST = 0x1, /**< Firewall operates in white-list mode (MAC address based admission) */
+ IX_ETH_DB_FIREWALL_BLACK_LIST = 0x2 /**< Firewall operates in black-list mode (MAC address based blocking) */
+} IxEthDBFirewallMode;
+
+typedef enum
+{
+ IX_ETH_DB_FILTERING_RECORD = 0x01, /**< <table><caption> Filtering record </caption>
+ * <tr><td> MAC address <td> static/dynamic type <td> age
+ * </table>
+ */
+ IX_ETH_DB_FILTERING_VLAN_RECORD = 0x02, /**< <table><caption> VLAN-enabled filtering record </caption>
+ * <tr><td> MAC address <td> static/dynamic type <td> age <td> 802.1Q tag
+ * </table>
+ */
+ IX_ETH_DB_WIFI_RECORD = 0x04, /**< <table><caption> WiFi header conversion record </caption>
+ * <tr><td> MAC address <td> optional gateway MAC address <td>
+ * </table>
+ */
+ IX_ETH_DB_FIREWALL_RECORD = 0x08, /**< <table><caption> Firewall record </caption>
+ * <tr><td> MAC address
+ * </table>
+ */
+ IX_ETH_DB_GATEWAY_RECORD = 0x10, /**< <i>For internal use only</i> */
+ IX_ETH_DB_MAX_RECORD_TYPE_INDEX = 0x10, /**< <i>For internal use only</i> */
+ IX_ETH_DB_NO_RECORD_TYPE = 0, /**< None of the registered record types */
+ IX_ETH_DB_ALL_FILTERING_RECORDS = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD, /**< All the filtering records */
+ IX_ETH_DB_ALL_RECORD_TYPES = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD |
+ IX_ETH_DB_WIFI_RECORD | IX_ETH_DB_FIREWALL_RECORD /**< All the record types registered within EthDB */
+} IxEthDBRecordType;
+
+typedef enum
+{
+ IX_ETH_DB_LEARNING = 0x01, /**< Learning feature; enables EthDB to learn MAC address (filtering) records, including 802.1Q enabled records */
+ IX_ETH_DB_FILTERING = 0x02, /**< Filtering feature; enables EthDB to communicate with the NPEs for downloading filtering information in the NPEs; depends on the learning feature */
+ IX_ETH_DB_VLAN_QOS = 0x04, /**< VLAN/QoS feature; enables EthDB to configure NPEs to operate in VLAN/QoS aware modes */
+ IX_ETH_DB_FIREWALL = 0x08, /**< Firewall feature; enables EthDB to configure NPEs to operate in firewall mode, using white/black address lists */
+ IX_ETH_DB_SPANNING_TREE_PROTOCOL = 0x10, /**< Spanning tree protocol feature; enables EthDB to configure the NPEs as STP nodes */
+ IX_ETH_DB_WIFI_HEADER_CONVERSION = 0x20 /**< WiFi 802.3 to 802.11 header conversion feature; enables EthDB to handle WiFi conversion data */
+} IxEthDBFeature;
+
+typedef UINT32 IxEthDBProperty; /**< Property ID type */
+
+typedef enum
+{
+ IX_ETH_DB_INTEGER_PROPERTY = 0x1, /**< 4 byte unsigned integer type */
+ IX_ETH_DB_STRING_PROPERTY = 0x2, /**< NULL-terminated string type of maximum 255 characters (including the terminator) */
+ IX_ETH_DB_MAC_ADDR_PROPERTY = 0x3, /**< 6 byte MAC address type */
+ IX_ETH_DB_BOOL_PROPERTY = 0x4 /**< 4 byte boolean type; can contain only TRUE and FALSE values */
+} IxEthDBPropertyType;
+
+/* list of supported properties for the IX_ETH_DB_VLAN_QOS feature */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY (0x01) /**< Property identifying number the supported number of traffic classes */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY (0x10) /**< Rx queue assigned to traffic class 0 */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_1_RX_QUEUE_PROPERTY (0x11) /**< Rx queue assigned to traffic class 1 */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_2_RX_QUEUE_PROPERTY (0x12) /**< Rx queue assigned to traffic class 2 */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_3_RX_QUEUE_PROPERTY (0x13) /**< Rx queue assigned to traffic class 3 */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_4_RX_QUEUE_PROPERTY (0x14) /**< Rx queue assigned to traffic class 4 */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_5_RX_QUEUE_PROPERTY (0x15) /**< Rx queue assigned to traffic class 5 */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_6_RX_QUEUE_PROPERTY (0x16) /**< Rx queue assigned to traffic class 6 */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY (0x17) /**< Rx queue assigned to traffic class 7 */
+
+/* private property used by EthAcc to indicate queue configuration complete */
+#define IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE (0x18)
+
+/**
+ *
+ * @brief The IEEE 802.3 Ethernet MAC address structure.
+ *
+ * The data should be packed with bytes xx:xx:xx:xx:xx:xx
+ *
+ * @note The data must be packed in network byte order.
+ */
+typedef struct
+{
+ UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE];
+} IxEthDBMacAddr;
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @brief Definition of an IXP400 port.
+ */
+typedef UINT32 IxEthDBPortId;
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @brief Port dependency map definition
+ */
+typedef UINT8 IxEthDBPortMap[32];
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBInit(void)
+ *
+ * @brief Initializes the Ethernet learning/filtering database
+ *
+ * @note calling this function multiple times does not constitute an error;
+ * redundant calls will be ignored, returning IX_ETH_DB_SUCCESS
+ *
+ * @retval IX_ETH_DB_SUCCESS initialization was successful
+ * @retval IX_ETH_DB_FAIL initialization failed (OS error)
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBInit(void);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBUnload(void)
+ *
+ * @brief Stops and prepares the EthDB component for unloading.
+ *
+ * @retval IX_ETH_DB_SUCCESS de-initialization was successful
+ * @retval IX_ETH_DB_BUSY de-initialization failed, ports must be disabled first
+ * @retval IX_ETH_DB_FAIL de-initialization failed (OS error)
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBUnload(void);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn void ixEthDBPortInit(IxEthDBPortId portID)
+ *
+ * @brief Initializes a port
+ *
+ * This function is called automatically by the Ethernet Access
+ * ixEthAccPortInit() routine for Ethernet NPE ports and should be manually
+ * called for any user-defined port (any port that is not one of
+ * the two Ethernet NPEs).
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to be initialized
+ *
+ * @see IxEthDBPortDefs.h for port definitions
+ *
+ * @note calling this function multiple times does not constitute an error;
+ * redundant calls will be ignored
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBPortInit(IxEthDBPortId portID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID)
+ *
+ * @brief Enables a port
+ *
+ * This function is called automatically from the Ethernet Access component
+ * ixEthAccPortEnable() routine for Ethernet NPE ports and should be manually
+ * called for any user-defined port (any port that is not one of
+ * the Ethernet NPEs).
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to enable processing on
+ *
+ * @retval IX_ETH_DB_SUCCESS if enabling is successful
+ * @retval IX_ETH_DB_FAIL if the enabling was not successful due to
+ * a message handler error
+ * @retval IX_ETH_DB_MAC_UNINITIALIZED the MAC address of this port was
+ * not initialized (only for Ethernet NPEs)
+ * @retval IX_ETH_DB_INVALID_PORT if portID is invalid
+ *
+ * @pre ixEthDBPortAddressSet needs to be called prior to enabling the port events
+ * for Ethernet NPEs
+ *
+ * @see ixEthDBPortAddressSet
+ *
+ * @see IxEthDBPortDefs.h for port definitions
+ *
+ * @note calling this function multiple times does not constitute an error;
+ * redundant calls will be ignored
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID)
+ *
+ * @brief Disables processing on a port
+ *
+ * This function is called automatically from the Ethernet Access component
+ * ixEthAccPortDisable() routine for Ethernet NPE ports and should be manually
+ * called for any user-defined port (any port that is not one of
+ * the Ethernet NPEs).
+ *
+ * @note Calling ixEthAccPortDisable() will disable the respective Ethernet NPE.
+ * After Ethernet NPEs are disabled they are stopped therefore
+ * when re-enabled they need to be reset, downloaded with microcode and started.
+ * For learning to restart working the user needs to call again
+ * ixEthAccPortUnicastMacAddressSet or ixEthDBUnicastAddressSet
+ * with the respective port MAC address.
+ * Residual MAC addresses learnt before the port was disabled are deleted as soon
+ * as the port is disabled. This only applies to dynamic (learnt) entries, static
+ * entries do not dissapear when the port is disabled.
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to disable processing on
+ *
+ * @retval IX_ETH_DB_SUCCESS if disabling is successful
+ * @retval IX_ETH_DB_FAIL if the disabling was not successful due to
+ * a message handler error
+ * @retval IX_ETH_DB_INVALID_PORT if portID is invalid
+ *
+ * @note calling this function multiple times after the first time completed successfully
+ * does not constitute an error; redundant calls will be ignored and return IX_ETH_DB_SUCCESS
+*/
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Sets the port MAC address
+ *
+ * This function is to be called from the Ethernet Access component top-level
+ * ixEthDBUnicastAddressSet(). Event processing cannot be enabled for a port
+ * until its MAC address has been set.
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port whose MAC address is set
+ * @param macAddr @ref IxEthDBMacAddr [in] - port MAC address
+ *
+ * @retval IX_ETH_DB_SUCCESS MAC address was set successfully
+ * @retval IX_ETH_DB_FAIL MAC address was not set due to a message handler failure
+ * @retval IX_ETH_DB_INVALID_PORT if the port is not an Ethernet NPE
+ *
+ * @see IxEthDBPortDefs.h for port definitions
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize)
+ *
+ * @brief Set the maximum frame size supported on the given port ID
+ *
+ * This functions set the maximum frame size supported on a specific port ID
+ *
+ * - Reentrant - yes
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to configure
+ * @param maximumFrameSize UINT32 [in] - maximum frame size to configure
+ *
+ * @retval IX_ETH_DB_SUCCESS the port is configured
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED the port has not been initialized
+ * @retval IX_ETH_DB_INVALID_PORT portID is invalid
+ * @retval IX_ETH_DB_INVALID_ARG size parameter is out of range
+ * @retval IX_ETH_DB_NO_PERMISSION selected port is not an Ethernet NPE
+ * @retval IX_FAIL unknown OS or NPE communication error
+ *
+ * @note
+ * This maximum frame size is used to filter the frames based on their
+ * destination addresses and the capabilities of the destination port.
+ * The mximum value that can be set for a NPE port is 16320.
+ * (IX_ETHNPE_ACC_FRAME_LENGTH_MAX)
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Populate the Ethernet learning/filtering database with a static MAC address
+ *
+ * Populates the Ethernet learning/filtering database with a static MAC address. The entry will not be subject to aging.
+ * If there is an entry (static or dynamic) with the corresponding MAC address on any port this entry will take precedence.
+ * Any other entry with the same MAC address will be removed.
+ *
+ * - Reentrant - yes
+ * - ISR Callable - yes
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to add the static address to
+ * @param macAddr @ref IxEthDBMacAddr [in] - static MAC address to add
+ *
+ * @retval IX_ETH_DB_SUCCESS the add was successful
+ * @retval IX_ETH_DB_FAIL failed to populate the database entry
+ * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later
+ * @retval IX_ETH_DB_INVALID_PORT portID is invalid
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer argument
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Populate the Ethernet learning/filtering database with a dynamic MAC address
+ *
+ * Populates the Ethernet learning/filtering database with a dynamic MAC address. This entry will be subject to normal
+ * aging function, if aging is enabled on its port.
+ * If there is an entry (static or dynamic) with the same MAC address on any port this entry will take precedence.
+ * Any other entry with the same MAC address will be removed.
+ *
+ * - Reentrant - yes
+ * - ISR Callable - yes
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to add the dynamic address to
+ * @param macAddr @ref IxEthDBMacAddr [in] - static MAC address to add
+ *
+ * @retval IX_ETH_DB_SUCCESS the add was successful
+ * @retval IX_ETH_DB_FAIL failed to populate the database entry
+ * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later
+ * @retval IX_ETH_DB_INVALID_PORT portID is invalid
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer argument
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr)
+ *
+ * @brief Removes a MAC address entry from the Ethernet learning/filtering database
+ *
+ * @param macAddr IxEthDBMacAddr [in] - MAC address to remove
+ *
+ * - Reentrant - yes
+ * - ISR Callable - no
+ *
+ * @retval IX_ETH_DB_SUCCESS the removal was successful
+ * @retval IX_ETH_DB_NO_SUCH_ADDR failed to remove the address (not in the database)
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer argument
+ * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Search the Ethernet learning/filtering database for the given MAC address and port ID
+ *
+ * This functions searches the database for a specific port ID and MAC address. Both the port ID
+ * and the MAC address have to match in order for the record to be reported as found.
+ *
+ * - Reentrant - yes
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to search for
+ * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to search for
+ *
+ * @retval IX_ETH_DB_SUCCESS the record exists in the database
+ * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument
+ * @retval IX_ETH_DB_NO_SUCH_ADDR the record was not found in the database
+ * @retval IX_ETH_DB_INVALID_PORT portID is invalid
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Search the Ethernet learning/filtering database for a MAC address and return the port ID
+ *
+ * Searches the database for a MAC address. The function returns the portID for the
+ * MAC address record, if found. If no match is found the function returns IX_ETH_DB_NO_SUCH_ADDR.
+ * The portID is only valid if the function finds a match.
+ *
+ * - Reentrant - yes
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID the address belongs to (populated only on a successful search)
+ * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to search for
+ *
+ * @retval IX_ETH_DB_SUCCESS the record exists in the database
+ * @retval IX_ETH_DB_NO_SUCH_ADDR the record was not found in the database
+ * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or portID pointer argument(s)
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Search the filtering database for a MAC address, return the port ID and reset the record age
+ *
+ * Searches the database for a MAC address. The function returns the portID for the
+ * MAC address record and resets the entry age to 0, if found.
+ * If no match is found the function returns IX_ETH_DB_NO_SUCH_ADDR.
+ * The portID is only valid if the function finds a match.
+ *
+ * - Reentrant - yes
+ * - ISR Callable - no
+ *
+ * @retval IX_ETH_DB_SUCCESS the MAC address was found
+ * @retval IX_ETH_DB_NO_SUCH_ADDR the MAC address was not found
+ * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or portID pointer argument(s)
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @def IX_ETH_DB_MAINTENANCE_TIME
+ *
+ * @brief The @ref ixEthDBDatabaseMaintenance must be called by the user at a frequency of
+ * IX_ETH_DB_MAINTENANCE_TIME
+ *
+ */
+#define IX_ETH_DB_MAINTENANCE_TIME (1 * 60) /* 1 Minute */
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @def IX_ETH_DB_LEARNING_ENTRY_AGE_TIME
+ *
+ * @brief The define specifies the filtering database age entry time. Static entries older than
+ * IX_ETH_DB_LEARNING_ENTRY_AGE_TIME +/- IX_ETH_DB_MAINTENANCE_TIME shall be removed.
+ *
+ */
+#define IX_ETH_DB_LEARNING_ENTRY_AGE_TIME (15 * 60 ) /* 15 Mins */
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID)
+ *
+ * @brief Disable the aging function for a specific port
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to disable aging on
+ *
+ * - Reentrant - yes
+ * - ISR Callable - no
+ *
+ * @retval IX_ETH_DB_SUCCESS aging disabled successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is invalid
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID)
+ *
+ * @brief Enable the aging function for a specific port
+ *
+ * Enables the aging of dynamic MAC address entries stored in the learning/filtering database
+ *
+ * @note The aging function relies on the @ref ixEthDBDatabaseMaintenance being called with a period of
+ * @ref IX_ETH_DB_MAINTENANCE_TIME seconds.
+ *
+ * - Reentrant - yes
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to enable aging on
+ *
+ * @retval IX_ETH_DB_SUCCESS aging enabled successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is invalid
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn void ixEthDBDatabaseMaintenance(void)
+ *
+ * @brief Performs a maintenance operation on the Ethernet learning/filtering database
+ *
+ * In order to perform a database maintenance this function must be called every
+ * @ref IX_ETH_DB_MAINTENANCE_TIME seconds. It should be called regardless of whether learning is
+ * enabled or not.
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @note this function call will be ignored if the learning feature is disabled
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBDatabaseMaintenance(void);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID)
+ *
+ * @brief This function displays the Mac Ethernet MAC address filtering tables.
+ *
+ * It displays the MAC address, port ID, entry type (dynamic/static),and age for
+ * the given port ID.
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to display the MAC address entries
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is invalid
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized
+ * @retval IX_ETH_DB_FAIL record browser failed due to an internal busy or lock condition
+ *
+ * @note this function is deprecated and kept for compatibility reasons; use @ref ixEthDBFilteringDatabaseShowRecords instead
+ *
+ * @see ixEthDBFilteringDatabaseShowRecords
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn void ixEthDBFilteringDatabaseShowAll(void)
+ *
+ * @brief Displays the MAC address recorded in the filtering database for all registered
+ * ports (see IxEthDBPortDefs.h), grouped by port ID.
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @retval void
+ *
+ * @note this function is deprecated and kept for compatibility reasons; use @ref ixEthDBFilteringDatabaseShowRecords instead
+ *
+ * @see ixEthDBFilteringDatabaseShowRecords
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBFilteringDatabaseShowAll(void);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter)
+ *
+ * @brief This function displays per port database records, given a record type filter
+ *
+ * The supported record type filters are:
+ *
+ * - IX_ETH_DB_FILTERING_RECORD - displays the non-VLAN filtering records (MAC address, age, static/dynamic)
+ * - IX_ETH_DB_FILTERING_VLAN_RECORD - displays the VLAN filtering records (MAC address, age, static/dynamic, VLAN ID, CFI, QoS class)
+ * - IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD - displays the previous two types of records
+ * - IX_ETH_DB_WIFI_RECORD - displays the WiFi header conversion records (MAC address, optional gateway MAC address) and WiFi header conversion parameters (BBSID, Duration/ID)
+ * - IX_ETH_DB_FIREWALL_RECORD - displays the firewall MAC address table and firewall operating mode (white list/black list)
+ * - IX_ETH_DB_ALL_RECORD_TYPES - displays all the record types
+ * - IX_ETH_DB_NO_RECORD_TYPE - displays only the port status (no records are displayed)
+ *
+ * Additionally, the status of each port will be displayed, containg the following information: type, capabilities, enabled status,
+ * aging enabled status, group membership and maximum frame size.
+ *
+ * The port ID can either be an actual port or IX_ETH_DB_ALL_PORTS, in which case the requested information
+ * will be displayed for all the ports (grouped by port)
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param portID ID of the port to display information on (use IX_ETH_DB_ALL_PORTS for all the ports)
+ * @param recordFilter record type filter
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is invalid
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
+ *
+ * @brief Sets the dependency port map for a port
+ *
+ * @param portID ID of the port to set the dependency map to
+ * @param dependencyPortMap new dependency map (as bitmap, each bit set indicates a port being included)
+ *
+ * This function is used to share filtering information between ports.
+ * By adding a port into another port's dependency map the target port
+ * filtering data will import the filtering data from the port it depends on.
+ * Any changes to filtering data for a port - such as adding, updating or removing records -
+ * will trigger updates in the filtering information for all the ports depending on
+ * on the updated port.
+ *
+ * For example, if ports 2 and 3 are set in the port 0 dependency map the filtering
+ * information for port 0 will also include the filtering information from ports 2 and 3.
+ * Adding a record to port 2 will also trigger an update not only on port 2 but also on
+ * port 0.
+ *
+ * The dependency map is a 256 bit array where each bit corresponds to a port corresponding to the
+ * bit offset (bit 0 - port 0, bit 1 - port 1 etc). Setting a bit to 1 indicates that the corresponding
+ * port is the port map. For example, a dependency port map of 0x14 consists in the ports with IDs 2 and 4.
+ * Note that the last bit (offset 255) is reserved and should never be set (it will be automatically
+ * cleared by the function).
+ *
+ * By default, each port has a dependency port map consisting only of itself, i.e.
+ *
+ * @verbatim
+ IxEthDBPortMap portMap;
+
+ // clear all ports from port map
+ memset(portMap, 0, sizeof (portMap));
+
+ // include portID in port map
+ portMap[portID / 8] = 1 << (portID % 8);
+ @endverbatim
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @note Setting dependency maps is useful for NPE ports, which benefit from automatic updates
+ * of filtering information. Setting dependency maps for user-defined ports is not an error
+ * but will have no actual effect.
+ *
+ * @note Including a port in its own dependency map is not compulsory, however note that
+ * in this case updating the port will not trigger an update on the port itself, which
+ * might not be the intended behavior
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>dependencyPortMap</i> pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Filtering is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
+ *
+ * @brief Retrieves the dependency port map for a port
+ *
+ * @param portID ID of the port to set the dependency map to
+ * @param dependencyPortMap location where the port dependency map is to be copied
+ *
+ * This function will copy the port dependency map to a user specified location.
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>dependencyPortMap</i> pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Filtering is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag)
+ *
+ * @brief Sets the default 802.1Q VLAN tag for a given port
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to set the default VLAN tag to
+ * @param vlanTag @ref IxEthDBVlanTag [in] - default 802.1Q VLAN tag
+ *
+ * The tag format has 16 bits and it is defined in the IEEE802.1Q specification.
+ * This tag will be used for tagging untagged frames (if enabled) and classifying
+ * unexpedited traffic into an internal traffic class (using the user priority field).
+ *
+ * <table border="1"> <caption> 802.1Q tag format </caption>
+ * <tr> <td> <b> 3 bits <td> <b> 1 bit <td> <b> 12 bits </b>
+ * <tr> <td> user priority <td> CFI <td> VID
+ * </table>
+ *
+ * User Priority : Defines user priority, giving eight (2^3) priority levels. IEEE 802.1P defines
+ * the operation for these 3 user priority bits
+ *
+ * CFI : Canonical Format Indicator is always set to zero for Ethernet switches. CFI is used for
+ * compatibility reason between Ethernet type network and Token Ring type network. If a frame received
+ * at an Ethernet port has a CFI set to 1, then that frame should not be forwarded as it is to an untagged port.
+ *
+ * VID : VLAN ID is the identification of the VLAN, which is basically used by the standard 802.1Q.
+ * It has 12 bits and allow the id entification of 4096 (2^12) VLANs. Of the 4096 possible VIDs, a VID of 0
+ * is used to identify priority frames and value 4095 (FFF) is reserved, so the maximum possible VLAN
+ * configurations are 4,094.
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_ETH_DB_INVALID_VLAN <i>vlanTag</i> argument does not parse to a valid 802.1Q VLAN tag
+ *
+ * @note a VLAN ID value of 0 indicates that the port is not part of any VLAN
+ * @note the value of the cannonical frame indicator (CFI) field is ignored, the
+ * field being used only in frame tagging operations
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag)
+ *
+ * @brief Retrieves the default 802.1Q port VLAN tag for a given port (see also @ref ixEthDBPortVlanTagSet)
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to retrieve the default VLAN tag from
+ * @param vlanTag @ref IxEthDBVlanTag [out] - location to write the default port 802.1Q VLAN tag to
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid vlanTag pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag)
+ *
+ * @brief Sets the 802.1Q VLAN tag for a database record
+ *
+ * @param macAddr MAC address
+ * @param vlanTag 802.1Q VLAN tag
+ *
+ * This function is used together with @ref ixEthDBVlanTagGet to provide MAC-based VLAN classification support.
+ * Please note that the bridging application must contain specific code to make use of this feature (see below).
+ *
+ * VLAN tags can be set only in IX_ETH_DB_FILTERING_RECORD or IX_ETH_DB_FILTERING_VLAN_RECORD type records.
+ * If to an IX_ETH_DB_FILTERING_RECORD type record is added a VLAN tag the record type is automatically
+ * changed to IX_ETH_DB_FILTERING_VLAN_RECORD. Once this has occurred the record type will never
+ * revert to a non-VLAN type (unless deleted and re-added).
+ *
+ * Record types used for different purposes (such as IX_ETH_DB_WIFI_RECORD) will be ignored by
+ * this function.
+ *
+ * After using this function to associate a VLAN ID with a MAC address the VLAN ID can be extracted knowing the
+ * MAC address using @ref ixEthDBVlanTagGet. This mechanism can be used to implement MAC-based VLAN classification
+ * if a bridging application searches for the VLAN tag when receiving a frame based on the source MAC address
+ * (contained in the <i>ixp_ne_src_mac</i> field of the buffer header).
+ * If found in the database, the application can instruct the NPE to tag the frame by writing the VLAN tag
+ * in the <i>ixp_ne_vlan_tci</i> field of the buffer header. This way the NPE will inspect the Egress tagging
+ * rule associated with the given VLAN ID on the Tx port and tag the frame if Egress tagging on the VLAN is
+ * allowed. Additionally, Egress tagging can be forced by setting the <i>ixp_ne_tx_flags.tag_over</i> and
+ * <i>ixp_ne_tx_flags.tag_mode</i> flags in the buffer header.
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @note this function will <b>not</b> add a filtering record, it can only be used to update an existing one
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer
+ * @retval IX_ETH_DB_NO_SUCH_ADDR a filtering record with the specified MAC address was not found
+ * @retval IX_ETH_DB_INVALID_VLAN <i>vlanTag</i> argument does not parse to a valid 802.1Q VLAN tag
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag)
+ *
+ * @brief Retrieves the 802.1Q VLAN tag from a database record given the record MAC address
+ *
+ * @param macAddr MAC address
+ * @param vlanTag location to write the record 802.1Q VLAN tag to
+ *
+ * @note VLAN tags can be retrieved only from IX_ETH_DB_FILTERING_VLAN_RECORD type records
+ *
+ * This function is used together with ixEthDBVlanTagSet to provide MAC-based VLAN classification support.
+ * Please note that the bridging application must contain specific code to make use of this feature (see @ref ixEthDBVlanTagSet).
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> or <i>vlanTag</i> pointer
+ * @retval IX_ETH_DB_NO_SUCH_ADDR a filtering record with the specified MAC address was not found
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID)
+ *
+ * @brief Adds a VLAN ID to a port's VLAN membership table
+ *
+ * Adding a VLAN ID to a port's VLAN membership table will cause frames tagged with the specified
+ * VLAN ID to be accepted by the frame filter, if Ingress VLAN membership filtering is enabled.
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to add the VLAN ID membership to
+ * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be added to the port membership table
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_VLAN vlanID is not a valid VLAN ID
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ *
+ * @note A port's default VLAN ID is always in its own membership table, hence there
+ * is no need to explicitly add it using this function (although it is not an error
+ * to do so)
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax)
+ *
+ * @brief Adds a VLAN ID range to a port's VLAN membership table
+ *
+ * All the VLAN IDs in the specified range will be added to the port VLAN
+ * membership table, including the range start and end VLAN IDs. Tagged frames with
+ * VLAN IDs in the specified range will be accepted by the frame filter, if Ingress VLAN
+ * membership filtering is enabled.
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to add the VLAN membership range into
+ * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN ID range
+ * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN ID range
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_VLAN the specified VLAN IDs are invalid or do not constitute a range
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ *
+ * @note Is is valid to use the same VLAN ID for both vlanIDMin and vlanIDMax, in which case this
+ * function will behave as @ref ixEthDBPortVlanMembershipAdd
+ *
+ * @note A port's default VLAN ID is always in its own membership table, hence there is no need
+ * to explicitly add it using this function (although it is not an error to do so)
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID)
+ *
+ * @brief Removes a VLAN ID from a port's VLAN membership table
+ *
+ * Frames tagged with a VLAN ID which is not in a port's VLAN membership table
+ * will be discarded by the frame filter, if Ingress membership filtering is enabled.
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to remove the VLAN ID membership from
+ * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be removed from the port membership table
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_INVALID_VLAN vlanID is not a valid VLAN ID
+ * @retval IX_ETH_DB_NO_PERMISSION attempted to remove the default VLAN ID
+ * from the port membership table (vlanID was set to the default port VLAN ID)
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ *
+ * @note A port's default VLAN ID cannot be removed from the port's membership
+ * table; attempting it will return IX_ETH_DB_NO_PERMISSION
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax)
+ *
+ * @brief Removes a VLAN ID range from a port's VLAN membership table
+ *
+ * All the VLAN IDs in the specified range will be removed from the port VLAN
+ * membership table, including the range start and end VLAN IDs. Tagged frames
+ * with VLAN IDs in the range will be discarded by the frame filter, if Ingress
+ * membership filtering is enabled.
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to remove the VLAN membership range from
+ * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN ID range
+ * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN ID range
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_VLAN the specified VLAN IDs are invalid or do not constitute a range
+ * @retval IX_ETH_DB_NO_PERMISSION attempted to remove the default VLAN ID
+ * from the port membership table (both vlanIDMin and vlanIDMax were set to the default port VLAN ID)
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ *
+ * @note Is is valid to use the same VLAN ID for both vlanIDMin and vlanIDMax, in which case
+ * function will behave as @ref ixEthDBPortVlanMembershipRemove
+ *
+ * @note If the given range overlaps the default port VLAN ID this function
+ * will remove all the VLAN IDs in the range except for the port VLAN ID from its
+ * own membership table. This situation will be silently dealt with (no error message
+ * will be returned) as long as the range contains more than one value (i.e. at least
+ * one other value, apart from the default port VLAN ID). If the function is called
+ * with the vlanIDMin and vlanIDMax parameters both set to the port default VLAN ID, the
+ * function will infer that an attempt was specifically made to remove the default port
+ * VLAN ID from the port membership table, in which case the return value will be
+ * IX_ETH_DB_NO_PERMISSION.
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
+ *
+ * @brief Sets a port's VLAN membership table
+ *
+ * Sets a port's VLAN membership table from a complete VLAN table containing all the possible
+ * 4096 VLAN IDs. The table format is an array containing 4096 bits (512 bytes), where each bit
+ * indicates whether the VLAN at that bit index is in the port's membership list (if set) or
+ * not (unset).
+ *
+ * The bit at index 0, indicating VLAN ID 0, indicates no VLAN membership and therefore no
+ * other bit must be set if bit 0 is set.
+ *
+ * The bit at index 4095 is reserved and should never be set (it will be ignored if set).
+ *
+ * The bit referencing the same VLAN ID as the default port VLAN ID should always be set, as
+ * the membership list must contain at least the default port VLAN ID.
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to set the VLAN membership table to
+ * @param vlanSet @ref IxEthDBVlanSet [in] - pointer to the VLAN membership table
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>vlanSet</i> pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
+ *
+ * @brief Retrieves a port's VLAN membership table
+ *
+ * Retrieves the complete VLAN membership table from a port, containing all the possible
+ * 4096 VLAN IDs. The table format is an array containing 4096 bits (512 bytes), where each bit
+ * indicates whether the VLAN at that bit index is in the port's membership list (if set) or
+ * not (unset).
+ *
+ * The bit at index 0, indicating VLAN ID 0, indicates no VLAN membership and therefore no
+ * other bit will be set if bit 0 is set.
+ *
+ * The bit at index 4095 is reserved and will not be set (it will be ignored if set).
+ *
+ * The bit referencing the same VLAN ID as the default port VLAN ID will always be set, as
+ * the membership list must contain at least the default port VLAN ID.
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to retrieve the VLAN membership table from
+ * @param vlanSet @ref IxEthDBVlanSet [out] - pointer a location where the VLAN membership table will be
+ * written to
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>vlanSet</i> pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter)
+ *
+ * @brief Sets a port's acceptable frame type filter
+ *
+ * The acceptable frame type is one (or a combination) of the following values:
+ * - IX_ETH_DB_ACCEPT_ALL_FRAMES - accepts all the frames
+ * - IX_ETH_DB_UNTAGGED_FRAMES - accepts untagged frames
+ * - IX_ETH_DB_VLAN_TAGGED_FRAMES - accepts tagged frames
+ * - IX_ETH_DB_PRIORITY_TAGGED_FRAMES - accepts tagged frames with VLAN ID set to 0 (no VLAN membership)
+ *
+ * Except for using the exact values given above only the following combinations are valid:
+ * - IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES
+ * - IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_PRIORITY_TAGGED_FRAMES
+ *
+ * Please note that IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES is equivalent
+ * to IX_ETH_DB_ACCEPT_ALL_FRAMES.
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @note by default the acceptable frame type filter is set to IX_ETH_DB_ACCEPT_ALL_FRAMES
+ *
+ * @note setting the acceptable frame type to PRIORITY_TAGGED_FRAMES is internally
+ * accomplished by changing the frame filter to VLAN_TAGGED_FRAMES and setting the
+ * VLAN membership list to include only VLAN ID 0; the membership list will need
+ * to be restored manually to an appropriate value if the acceptable frame type
+ * filter is changed back to ACCEPT_ALL_FRAMES or VLAN_TAGGED_FRAMES; failure to do so
+ * will filter all VLAN traffic bar frames tagged with VLAN ID 0
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to set the acceptable frame type filter to
+ * @param frameFilter @ref IxEthDBFrameFilter [in] - acceptable frame type filter
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid frame type filter
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter)
+ *
+ * @brief Retrieves a port's acceptable frame type filter
+ *
+ * For a description of the acceptable frame types see @ref ixEthDBAcceptableFrameTypeSet
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to retrieve the acceptable frame type filter from
+ * @param frameFilter @ref IxEthDBFrameFilter [out] - location to store the acceptable frame type filter
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>frameFilter</i> pointer argument
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable)
+ *
+ * @brief Sets a port's priority mapping table
+ *
+ * The priority mapping table is an 8x2 table mapping a QoS (user) priority into an internal
+ * traffic class. There are 8 valid QoS priorities (0..7, 0 being the lowest) which can be
+ * mapped into one of the 4 available traffic classes (0..3, 0 being the lowest).
+ * If a custom priority mapping table is not specified using this function the following
+ * default priority table will be used (as per IEEE 802.1Q and IEEE 802.1D):
+ *
+ * <table border="1"> <caption> QoS traffic classes </caption>
+ * <tr> <td> <b> QoS priority <td> <b> Default traffic class <td> <b> Traffic type </b>
+ * <tr> <td> 0 <td> 1 <td> Best effort, default class for unexpedited traffic
+ * <tr> <td> 1 <td> 0 <td> Background traffic
+ * <tr> <td> 2 <td> 0 <td> Spare bandwidth
+ * <tr> <td> 3 <td> 1 <td> Excellent effort
+ * <tr> <td> 4 <td> 2 <td> Controlled load
+ * <tr> <td> 5 <td> 2 <td> Video traffic
+ * <tr> <td> 6 <td> 3 <td> Voice traffic
+ * <tr> <td> 7 <td> 3 <td> Network control
+ * </table>
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID of the port to set the priority mapping table to
+ * @param priorityTable @ref IxEthDBPriorityTable [in] - location of the user priority table
+ *
+ * @note The provided table will be copied into internal data structures in EthDB and
+ * can be deallocated by the called after this function has completed its execution, if
+ * so desired
+ *
+ * @warning The number of available traffic classes differs depending on the NPE images
+ * and queue configuration. Check IxEthDBQoS.h for up-to-date information on the availability of
+ * traffic classes. Note that specifiying a traffic class in the priority map which exceeds
+ * the system availability will produce an IX_ETH_DB_INVALID_PRIORITY return error code and no
+ * priority will be remapped.
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>priorityTable</i> pointer
+ * @retval IX_ETH_DB_INVALID_PRIORITY at least one priority value exceeds
+ * the current number of available traffic classes
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable)
+ *
+ * @brief Retrieves a port's priority mapping table
+ *
+ * The priority mapping table for the given port will be copied in the location
+ * specified by the caller using "priorityTable"
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param portID ID @ref IxEthDBPortId [in] - of the port to retrieve the priority mapping table from
+ * @param priorityTable @ref IxEthDBPriorityTable [out] - pointer to a user specified location where the table will be copied to
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid priorityTable pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass)
+ *
+ * @brief Sets one QoS/user priority => traffic class mapping in a port's priority mapping table
+ *
+ * This function establishes a mapping between a user (QoS) priority and an internal traffic class.
+ * The mapping will be saved in the port's priority mapping table. Use this function when not all
+ * the QoS priorities need remapping (see also @ref ixEthDBPriorityMappingTableSet)
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to set the mapping to
+ * @param userPriority @ref IxEthDBPriority [in] - user (QoS) priority, between 0 and 7 (0 being the lowest)
+ * @param trafficClass @ref IxEthDBPriority [in] - internal traffic class, between 0 and 3 (0 being the lowest)
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_PRIORITY <i>userPriority</i> out of range or
+ * <i>trafficClass</i> is beyond the number of currently available traffic classes
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass)
+ *
+ * @brief Retrieves one QoS/user priority => traffic class mapping in a port's priority mapping table
+ *
+ * This function retrieves the internal traffic class associated with a QoS (user) priority from a given
+ * port's priority mapping table. Use this function when not all the QoS priority mappings are
+ * required (see also @ref ixEthDBPriorityMappingTableGet)
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to set the mapping to
+ * @param userPriority @ref IxEthDBPriority [in] - user (QoS) priority, between 0 and 7 (0 being the lowest)
+ * @param trafficClass @ref IxEthDBPriority [out] - location to write the corresponding internal traffic class to
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_PRIORITY invalid userPriority value (out of range)
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>trafficClass</i> pointer argument
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled)
+ *
+ * @brief Enables or disables Egress VLAN tagging for a port and a given VLAN
+ *
+ * This function enables or disables Egress VLAN tagging for the given port and VLAN ID.
+ * If the VLAN tagging for a certain VLAN ID is enabled then all the frames to be
+ * transmitted on the given port tagged with the same VLAN ID will be transmitted in a tagged format.
+ * If tagging is not enabled for the given VLAN ID, the VLAN tag from the frames matching
+ * this VLAN ID will be removed (the frames will be untagged).
+ *
+ * VLAN ID 4095 is reserved and should never be used with this function.
+ * VLAN ID 0 has the special meaning of "No VLAN membership" and it is used in this
+ * context to allow the port to send priority-tagged frames or not.
+ *
+ * By default, no Egress VLAN tagging is enabled on any port.
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the VLAN ID Egress tagging on
+ * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be matched against outgoing frames
+ * @param enabled BOOL [in] - TRUE to enable Egress VLAN tagging on the port and given VLAN, and
+ * FALSE to disable Egress VLAN tagging
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range)
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled)
+ *
+ * @brief Retrieves the Egress VLAN tagging enabling status for a port and VLAN ID
+ *
+ * @param portID [in] - ID of the port to extract the Egress VLAN ID tagging status from
+ * @param vlanID VLAN [in] - ID whose tagging status is to be extracted
+ * @param enabled [in] - user-specifed location where the status is copied to; following
+ * the successfull execution of this function the value will be TRUE if Egress VLAN
+ * tagging is enabled for the given port and VLAN ID, and FALSE otherwise
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @see ixEthDBEgressVlanEntryTaggingEnabledGet
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range)
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>enabled</i> argument pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled)
+ *
+ * @brief Enables or disables Egress VLAN tagging for a port and given VLAN range
+ *
+ * This function is very similar to @ref ixEthDBEgressVlanEntryTaggingEnabledSet with the
+ * difference that it can manipulate the Egress tagging status on multiple VLAN IDs,
+ * defined by a contiguous range. Note that both limits in the range are explicitly
+ * included in the execution of this function.
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the VLAN ID Egress tagging on
+ * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN range to be matched against outgoing frames
+ * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN range to be matched against outgoing frames
+ * @param enabled BOOL [in] - TRUE to enable Egress VLAN tagging on the port and given VLAN range,
+ * and FALSE to disable Egress VLAN tagging
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range), or do not constitute a range
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_ETH_DB_NO_PERMISSION attempted to explicitly remove the default port VLAN ID from the tagging table
+ * @retval IX_FAIL unknown OS or NPE communication error
+ *
+ * @note Specifically removing the default port VLAN ID from the Egress tagging table by setting both vlanIDMin and vlanIDMax
+ * to the VLAN ID portion of the PVID is not allowed by this function and will return IX_ETH_DB_NO_PERMISSION.
+ * However, this can be circumvented, should the user specifically desire this, by either using a
+ * larger range (vlanIDMin < vlanIDMax) or by using ixEthDBEgressVlanEntryTaggingEnabledSet.
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
+ *
+ * @brief Sets the complete Egress VLAN tagging table for a port
+ *
+ * This function is used to set the VLAN tagging/untagging per VLAN ID for a given port
+ * covering the entire VLAN ID range (0..4094). The <i>vlanSet</i> parameter is a 4096
+ * bit array, each bit indicating the Egress behavior for the corresponding VLAN ID.
+ * If a bit is set then outgoing frames with the corresponding VLAN ID will be transmitted
+ * with the VLAN tag, otherwise the frame will be transmitted without the VLAN tag.
+ *
+ * Bit 0 has a special significance, indicating tagging or tag removal for priority-tagged
+ * frames.
+ *
+ * Bit 4095 is reserved and should never be set (it will be ignored if set).
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port whose Egress VLAN tagging behavior is set
+ * @param vlanSet @ref IxEthDBVlanSet [in] - 4096 bit array controlling per-VLAN tagging and untagging
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>vlanSet</i> pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ *
+ * @warning This function will automatically add the default port VLAN ID to the Egress tagging table
+ * every time it is called. The user should manually call ixEthDBEgressVlanEntryTaggingEnabledSet to
+ * prevent tagging on the default port VLAN ID if the default behavior is not intended.
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
+ *
+ * @brief Retrieves the complete Egress VLAN tagging table from a port
+ *
+ * This function copies the 4096 bit table controlling the Egress VLAN tagging into a user specified
+ * area. Each bit in the array indicates whether tagging for the corresponding VLAN (the bit position
+ * in the array) is enabled (the bit is set) or not (the bit is unset).
+ *
+ * Bit 4095 is reserved and should not be set (it will be ignored if set).
+ *
+ * @see ixEthDBEgressVlanTaggingEnabledSet
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port whose Egress VLAN tagging behavior is retrieved
+ * @param vlanSet @ref IxEthDBVlanSet [out] - user location to copy the Egress tagging table into; should have
+ * room to store 4096 bits (512 bytes)
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>vlanSet</i> pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction)
+ *
+ * @brief Sets the Ingress VLAN tagging behavior for a port
+ *
+ * A port's Ingress tagging behavior is controlled by the taggingAction parameter,
+ * which can take one of the following values:
+ *
+ * - IX_ETH_DB_PASS_THROUGH - leaves the frame unchanged (does not add or remove the VLAN tag)
+ * - IX_ETH_DB_ADD_TAG - adds the VLAN tag if not present, using the default port VID
+ * - IX_ETH_DB_REMOVE_TAG - removes the VLAN tag if present
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port whose Ingress VLAN tagging behavior is set
+ * @param taggingAction @ref IxEthDBTaggingAction [in] - tagging behavior for the port
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>taggingAction</i> argument
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction)
+ *
+ * @brief Retrieves the Ingress VLAN tagging behavior from a port (see @ref ixEthDBIngressVlanTaggingEnabledSet)
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port whose Ingress VLAN tagging behavior is set
+ * @param taggingAction @ref IxEthDBTaggingAction [out] - location where the tagging behavior for the port is written to
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>taggingAction</i> pointer argument
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable)
+ *
+ * @brief Enables or disables port ID extraction
+ *
+ * This feature can be used in the situation when a multi-port device (e.g. a switch)
+ * is connected to an IXP4xx port and the device can provide incoming frame port
+ * identification by tagging the TPID field in the Ethernet frame. Enabling
+ * port extraction will instruct the NPE to copy the TPID field from the frame and
+ * place it in the <i>ixp_ne_src_port</i> of the <i>ixp_buf</i> header. In addition,
+ * the NPE restores the TPID field to 0.
+ *
+ * If the frame is not tagged the NPE will fill the <i>ixp_ne_src_port</i> with the
+ * port ID of the MII interface the frame was received from.
+ *
+ * The TPID field is the least significant byte of the type/length field, which is
+ * normally set to 0x8100 for 802.1Q-tagged frames.
+ *
+ * This feature is disabled by default.
+ *
+ * @param portID ID of the port to configure port ID extraction on
+ * @param enable TRUE to enable port ID extraction and FALSE to disable it
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet)
+ *
+ * @brief Retrieves the feature capability set for a port
+ *
+ * This function retrieves the feature capability set for a port or the common capabilities shared between all
+ * the ports, writing the feature capability set in a user specified location.
+ *
+ * The feature capability set will consist of a set formed by OR-ing one or more of the following values:
+ * - IX_ETH_DB_LEARNING - Learning feature; enables EthDB to learn MAC address (filtering) records, including 802.1Q enabled records
+ * - IX_ETH_DB_FILTERING - Filtering feature; enables EthDB to communicate with the NPEs for downloading filtering information in the NPEs; depends on the learning feature
+ * - IX_ETH_DB_VLAN_QOS - VLAN/QoS feature; enables EthDB to configure NPEs to operate in VLAN/QoS aware modes
+ * - IX_ETH_DB_FIREWALL - Firewall feature; enables EthDB to configure NPEs to operate in firewall mode, using white/black address lists
+ * - IX_ETH_DB_SPANNING_TREE_PROTOCOL - Spanning tree protocol feature; enables EthDB to configure the NPEs as STP nodes
+ * - IX_ETH_DB_WIFI_HEADER_CONVERSION - WiFi 802.3 to 802.11 header conversion feature; enables EthDB to handle WiFi conversion data
+ *
+ * Note that EthDB provides only the LEARNING feature for non-NPE ports.
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to retrieve the capability set for
+ * (use IX_ETH_DB_ALL_PORTS to retrieve the common capabilities shared between all the ports)
+ * @param featureSet @ref IxEthDBFeature [out] - location where the capability set will be written to
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>featureSet</i> pointer
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enabled)
+ *
+ * @brief Enables or disables one or more EthDB features
+ *
+ * Selects one or more features (see @ref ixEthDBFeatureCapabilityGet for a description of the supported
+ * features) to be enabled or disabled on the selected port (or all the ports).
+ *
+ * Note that some features are mutually incompatible:
+ * - IX_ETH_DB_FILTERING is incompatible with IX_ETH_DB_WIFI_HEADER_CONVERSION
+ *
+ * Also note that some features require other features to be enabled:
+ * - IX_ETH_DB_FILTERING requires IX_ETH_DB_LEARNING
+ *
+ * This function will either enable the entire selected feature set for the selected port (or all the ports),
+ * in which case it will return IX_ETH_DB_SUCCESS, or in case of error it will not enable any feature at all
+ * and return an appropriate error message.
+ *
+ * The following features are enabled by default (for ports with the respective capability),
+ * for compatibility reasons with previous versions of CSR:
+ * - IX_ETH_DB_LEARNING
+ * - IX_ETH_DB_FILTERING
+ *
+ * All other features are disabled by default and require manual enabling using ixEthDBFeatureEnable.
+ *
+ * <b>Default settings for VLAN, QoS, Firewall and WiFi header conversion features:</b>
+ *
+ * <i>VLAN</i>
+ *
+ * When the VLAN/QoS feature is enabled for a port for the first time the default VLAN behavior
+ * of the port is set to be as <b>permissive</b> (it will accept all the frames) and
+ * <b>non-interferential</b> (it will not change any frames) as possible:
+ * - the port VLAN ID (VID) is set to 0
+ * - the Ingress acceptable frame filter is set to accept all frames
+ * - the VLAN port membership is set to the complete VLAN range (0 - 4094)
+ * - the Ingress tagging mode is set to pass-through (will not change frames)
+ * - the Egress tagging mode is to send tagged frames in the entire VLAN range (0 - 4094)
+ *
+ * Note that further disabling and re-enabling the VLAN feature for a given port will not reset the port VLAN behavior
+ * to the settings listed above. Any VLAN settings made by the user are kept.
+ *
+ * <i>QoS</i>
+ *
+ * The following default priority mapping table will be used (as per IEEE 802.1Q and IEEE 802.1D):
+ *
+ * <table border="1"> <caption> QoS traffic classes </caption>
+ * <tr> <td> <b> QoS priority <td> <b> Default traffic class <td> <b> Traffic type </b>
+ * <tr> <td> 0 <td> 1 <td> Best effort, default class for unexpedited traffic
+ * <tr> <td> 1 <td> 0 <td> Background traffic
+ * <tr> <td> 2 <td> 0 <td> Spare bandwidth
+ * <tr> <td> 3 <td> 1 <td> Excellent effort
+ * <tr> <td> 4 <td> 2 <td> Controlled load
+ * <tr> <td> 5 <td> 2 <td> Video traffic
+ * <tr> <td> 6 <td> 3 <td> Voice traffic
+ * <tr> <td> 7 <td> 3 <td> Network control
+ * </table>
+ *
+ * <i> Firewall </i>
+ *
+ * The port firewall is configured by default in <b>black-list mode</b>, and the firewall address table is empty.
+ * This means the firewall will not filter any frames until the feature is configured and the firewall table is
+ * downloaded to the NPE.
+ *
+ * <i> Spanning Tree </i>
+ *
+ * The port is set to <b>STP unblocked mode</b>, therefore it will accept all frames until re-configured.
+ *
+ * <i> WiFi header conversion </i>
+ *
+ * The WiFi header conversion database is empty, therefore no actual header conversion will take place until this
+ * feature is configured and the conversion table downloaded to the NPE.
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the features on (use IX_ETH_DB_ALL_PORTS for all the ports)
+ * @param feature @ref IxEthDBFeature [in] - feature or feature set to enable or disable
+ * @param enabled BOOL [in] - TRUE to enable the feature and FALSE to disable it
+ *
+ * @note Certain features, from a functional point of view, cannot be disabled as such at NPE level;
+ * when such features are set to <i>disabled</i> using the EthDB API they will be configured in such
+ * a way to determine a behavior equivalent to the feature being disabled. As well as this, disabled
+ * features cannot be configured or accessed via the EthDB API (except for getting their status).
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_NO_PERMISSION attempted to enable mutually exclusive features,
+ * or a feature that depends on another feature which is not present or enabled
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE at least one of the features selected is unavailable
+ * @retval IX_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enabled);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled)
+ *
+ * @brief Retrieves the availability and status of a feature set
+ *
+ * This function returns the availability and status for a feature set.
+ * Note that if more than one feature is selected (e.g. IX_ETH_DB_LEARNING | IX_ETH_DB_FILTERING)
+ * the "present" and "enabled" return values will be set to TRUE only if all the features in the
+ * feature set are present and enabled (not only some).
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ * @param feature @ref IxEthDBFeature [in] - identifier of the feature to retrieve the status for
+ * @param present BOOL [out] - location where a boolean flag indicating whether this feature is present will be written to
+ * @param enabled BOOL [out] - location where a boolean flag indicating whether this feature is enabled will be written to
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG either <i>present</i> or <i>enabled</i> pointer argument is invalid
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value)
+ *
+ * @brief Retrieves the value of a feature property
+ *
+ * The EthDB features usually contain feature-specific properties describing or
+ * controlling how the feature operates. While essential properties (e.g. the
+ * firewall operating mode) have their own API, secondary properties can be
+ * retrieved using this function.
+ *
+ * Properties can be read-only or read-write. ixEthDBFeaturePropertyGet operates with
+ * both types of features.
+ *
+ * Properties have types associated with them. A descriptor indicating the property
+ * type is returned in the <i>type</i> argument for convenience.
+ *
+ * The currently supported properties and their corresponding features are as follows:
+ *
+ * <table border="1"> <caption> Properties for IX_ETH_DB_VLAN_QOS </caption>
+ * <tr> <td> <b> Property identifier <td> <b> Property type <td> <b> Property value <td> <b> Read-Only </b>
+ * <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY <td> IX_ETH_DB_INTEGER_PROPERTY <td> number of internal traffic classes <td> Yes
+ * <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY <td> IX_ETH_DB_INTEGER_PROPERTY <td> queue assignment for traffic class 0 <td> Yes
+ * <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_1_RX_QUEUE_PROPERTY <td> IX_ETH_DB_INTEGER_PROPERTY <td> queue assignment for traffic class 1 <td> Yes
+ * <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_2_RX_QUEUE_PROPERTY <td> IX_ETH_DB_INTEGER_PROPERTY <td> queue assignment for traffic class 2 <td> Yes
+ * <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_3_RX_QUEUE_PROPERTY <td> IX_ETH_DB_INTEGER_PROPERTY <td> queue assignment for traffic class 3 <td> Yes
+ * <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_4_RX_QUEUE_PROPERTY <td> IX_ETH_DB_INTEGER_PROPERTY <td> queue assignment for traffic class 4 <td> Yes
+ * <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_5_RX_QUEUE_PROPERTY <td> IX_ETH_DB_INTEGER_PROPERTY <td> queue assignment for traffic class 5 <td> Yes
+ * <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_6_RX_QUEUE_PROPERTY <td> IX_ETH_DB_INTEGER_PROPERTY <td> queue assignment for traffic class 6 <td> Yes
+ * <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY <td> IX_ETH_DB_INTEGER_PROPERTY <td> queue assignment for traffic class 7 <td> Yes
+ * </table>
+ *
+ * @see ixEthDBFeaturePropertySet
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ * @param feature @ref IxEthDBFeature [in] - EthDB feature for which the property is retrieved
+ * @param property @ref IxEthDBProperty [in] - property identifier
+ * @param type @ref IxEthDBPropertyType [out] - location where the property type will be stored
+ * @param value void [out] - location where the property value will be stored
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_INVALID_ARG invalid property identifier, <i>type</i> or <i>value</i> pointer arguments
+ * @retval IX_ETH_DB_FAIL incorrect property value or unknown error
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value)
+ *
+ * @brief Sets the value of a feature property
+ *
+ * Unlike @ref ixEthDBFeaturePropertyGet, this function operates only with read-write properties
+ *
+ * The currently supported properties and their corresponding features are as follows:
+ *
+ * - IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE (for IX_ETH_DB_VLAN_QOS): freezes the availability of traffic classes
+ * to the number of traffic classes currently in use
+ *
+ * Note that this function creates deep copies of the property values; once the function is invoked the client
+ * can free or reuse the memory area containing the original property value.
+ *
+ * Copy behavior for different property types is defined as follows:
+ *
+ * - IX_ETH_DB_INTEGER_PROPERTY - 4 bytes are copied from the source location
+ * - IX_ETH_DB_STRING_PROPERTY - the source string will be copied up to the NULL '\0' string terminator, maximum of 255 characters
+ * - IX_ETH_DB_MAC_ADDR_PROPERTY - 6 bytes are copied from the source location
+ * - IX_ETH_DB_BOOL_PROPERTY - 4 bytes are copied from the source location; the only allowed values are TRUE (1L) and false (0L)
+ *
+ * @see ixEthDBFeaturePropertySet
+ *
+ * @warning IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE is provided for EthAcc internal use;
+ * do not attempt to set this property directly
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ * @param feature @ref IxEthDBFeature [in] - EthDB feature for which the property is set
+ * @param property @ref IxEthDBProperty [in] - property identifier
+ * @param value void [in] - location where the property value is to be copied from
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_INVALID_ARG invalid property identifier, <i>value</i> pointer, or invalid property value
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType)
+ *
+ * @brief Deletes a set of record types from the Ethernet Database
+ *
+ * This function deletes all the records of certain types (specified in the recordType filter)
+ * associated with a port. Additionally, the IX_ETH_DB_ALL_PORTS value can be used as port ID
+ * to indicate that the specified record types should be deleted for all the ports.
+ *
+ * The record type filter can be an ORed combination of the following types:
+ *
+ * <caption> Record types </caption>
+ * - IX_ETH_DB_FILTERING_RECORD <table><caption> Filtering record </caption>
+ * <tr><td> MAC address <td> static/dynamic type <td> age </tr>
+ * </table>
+ *
+ * - IX_ETH_DB_FILTERING_VLAN_RECORD <table><caption> VLAN-enabled filtering record </caption>
+ * <tr><td> MAC address <td> static/dynamic type <td> age <td> 802.1Q tag </tr>
+ * </table>
+ *
+ * - IX_ETH_DB_WIFI_RECORD <table><caption> WiFi header conversion record </caption>
+ * <tr><td> MAC address <td> optional gateway MAC address <td> </tr>
+ * </table>
+ *
+ * - IX_ETH_DB_FIREWALL_RECORD <table><caption> Firewall record </caption>
+ * <tr><td> MAC address </tr>
+ * </table>
+ * - IX_ETH_DB_ALL_RECORD_TYPES
+ *
+ * Any combination of the above types is valid e.g.
+ *
+ * (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD | IX_ETH_DB_FIREWALL_RECORD),
+ *
+ * although some might be redundant (it is not an error to do so) e.g.
+ *
+ * (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_ALL_RECORD_TYPES)
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ * @param recordType @ref IxEthDBRecordType [in] - record type filter
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>recordType</i> filter
+ *
+ * @note If the record type filter contains any unrecognized value (hence the
+ * IX_ETH_DB_INVALID_ARG error value is returned) no actual records will be deleted.
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Adds an "Access Point to Station" record to the database, for 802.3 => 802.11 frame
+ * header conversion
+ *
+ * Frame header conversion is controlled by the set of MAC addresses
+ * added using @ref ixEthDBWiFiStationEntryAdd and @ref ixEthDBWiFiAccessPointEntryAdd.
+ * Conversion arguments are added using @ref ixEthDBWiFiFrameControlSet,
+ * @ref ixEthDBWiFiDurationIDSet and @ref ixEthDBWiFiBBSIDSet.
+ *
+ * Note that adding the same MAC address twice will not return an error
+ * (but will not accomplish anything either), while re-adding a record previously added
+ * as an "Access Point to Access Point" will migrate the record to the "Access Point
+ * to Station" type.
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to add
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_INVALID_ARG macAddr is an invalid pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer argument
+ * @retval IX_ETH_DB_NOMEM maximum number of records reached
+ * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr)
+ *
+ * @brief Adds an "Access Point to Access Point" record to the database
+ *
+ * @see ixEthDBWiFiStationEntryAdd
+ *
+ * Note that adding the same MAC address twice will simply overwrite the previously
+ * defined gateway MAC address value in the same record, if the record was previously of the
+ * "Access Point to Access Point" type.
+ *
+ * Re-adding a MAC address as "Access Point to Access Point", which was previously added as
+ * "Access Point to Station" will migrate the record type to "Access Point to Access Point" and
+ * record the gateway MAC address.
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to add
+ * @param gatewayMacAddr @ref IxEthDBMacAddr [in] - MAC address of the gateway Access Point
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG macAddr is an invalid pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> or <i>gatewayMacAddr</i> pointer argument
+ * @retval IX_ETH_DB_NOMEM maximum number of records reached
+ * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Removes a WiFi station record
+ *
+ * This function removes both types of WiFi records ("Access Point to Station" and
+ * "Access Point to Access Point").
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to remove
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer argument
+ * @retval IX_ETH_DB_NO_SUCH_ADDR specified address was not found in the database
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled
+ * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID)
+ *
+ * @brief Downloads the MAC address table for 802.3 => 802.11 frame header
+ * conversion to the NPE
+ *
+ * Note that the frame conversion MAC address table must be individually downloaded
+ * to each NPE for which the frame header conversion feature is enabled (i.e. it
+ * is not possible to specify IX_ETH_DB_ALL_PORTS).
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled
+ * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl)
+ *
+ * @brief Sets the GlobalFrameControl field
+ *
+ * The GlobalFrameControl field is a 2-byte value inserted in the <i>Frame Control</i>
+ * field for all 802.3 to 802.11 frame header conversions
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ * @param frameControl UINT16 [in] - GlobalFrameControl value
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled
+ * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID)
+ *
+ * @brief Sets the GlobalDurationID field
+ *
+ * The GlobalDurationID field is a 2-byte value inserted in the <i>Duration/ID</i>
+ * field for all 802.3 to 802.11 frame header conversions
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ * @param durationID UINT16 [in] - GlobalDurationID field
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled
+ * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid)
+ *
+ * @brief Sets the BBSID field
+ *
+ * The BBSID field is a 6-byte value which
+ * identifies the infrastructure of the service set managed
+ * by the Access Point having the IXP400 as its processor. The value
+ * is written in the <i>BBSID</i> field of the 802.11 frame header.
+ * The BBSID value is the MAC address of the Access Point.
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ * @param bbsid @ref IxEthDBMacAddr [in] - pointer to 6 bytes containing the BSSID
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>bbsid</i> pointer argument
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled
+ * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked)
+ *
+ * @brief Sets the STP blocked/unblocked state for a port
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ * @param blocked BOOL [in] - TRUE to set the port as STP blocked, FALSE to set it as unblocked
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Spanning Tree Protocol feature not enabled
+ * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked)
+ *
+ * @brief Retrieves the STP blocked/unblocked state for a port
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ * @param blocked BOOL * [in] - set to TRUE if the port is STP blocked, FALSE otherwise
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>blocked</i> pointer argument
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Spanning Tree Protocol feature not enabled
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode)
+ *
+ * @brief Sets the firewall mode to use white or black listing
+ *
+ * When enabled, the NPE MAC address based firewall support operates in two modes:
+ *
+ * - white-list mode (MAC address based admission)
+ * - <i>mode</i> set to IX_ETH_DB_FIREWALL_WHITE_LIST
+ * - only packets originating from MAC addresses contained in the firewall address list
+ * are allowed on the Rx path
+ * - black-list mode (MAC address based blocking)
+ * - <i>mode</i> set to IX_ETH_DB_FIREWALL_BLACK_LIST
+ * - packets originating from MAC addresses contained in the firewall address list
+ * are discarded
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ * @param mode @ref IxEthDBFirewallMode [in] - firewall mode (IX_ETH_DB_FIREWALL_WHITE_LIST or IX_ETH_DB_FIREWALL_BLACK_LIST)
+ *
+ * @note by default the firewall operates in black-list mode with an empty address
+ * list, hence it doesn't filter any packets
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled
+ * @retval IX_ETH_DB_INVALID_ARGUMENT <i>mode</i> argument is not a valid firewall configuration mode
+ * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error
+*/
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable)
+ *
+ * @brief Enables or disables invalid MAC address filtering
+ *
+ * According to IEEE802 it is illegal for a source address to be a multicast
+ * or broadcast address. If this feature is enabled the NPE inspects the source
+ * MAC addresses of incoming frames and discards them if invalid addresses are
+ * detected.
+ *
+ * By default this service is enabled, if the firewall feature is supported by the
+ * NPE image.
+ *
+ * @param portID ID of the port
+ * @param enable TRUE to enable invalid MAC address filtering and FALSE to disable it
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled
+ * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Adds a MAC address to the firewall address list
+ *
+ * Note that adding the same MAC address twice will not return an error
+ * but will not actually accomplish anything.
+ *
+ * The firewall MAC address list has a limited number of entries; once
+ * the maximum number of entries has been reached this function will failed
+ * to add more addresses, returning IX_ETH_DB_NOMEM.
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to be added
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer argument
+ * @retval IX_ETH_DB_NOMEM maximum number of records reached
+ * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Removes a MAC address from the firewall address list
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to be removed
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer argument
+ * @retval IX_ETH_DB_NO_SUCH_ADDR address not found
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID)
+ *
+ * @brief Downloads the MAC firewall table to a port
+ *
+ * @param portID ID of the port
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled
+ * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field)
+ *
+ * @brief Adds a user-defined field to a database record
+ *
+ * This function associates a user-defined field to a database record.
+ * The user-defined field is passed as a <i>(void *)</i> parameter, hence it can be used
+ * for any purpose (such as identifying a structure). Retrieving the user-defined field from
+ * a record is done using @ref ixEthDBUserFieldGet. Note that EthDB never uses the user-defined
+ * field for any internal operation and it is not aware of the significance of its contents. The
+ * field is only stored as a pointer.
+ *
+ * The database record is identified using a combination of the given parameters, depending on the record type.
+ * All the record types require the record MAC address.
+ *
+ * - IX_ETH_DB_FILTERING_RECORD requires only the MAC address
+ * - IX_ETH_DB_VLAN_FILTERING_RECORD requires the MAC address and the VLAN ID
+ * - IX_ETH_DB_WIFI_RECORD requires the MAC address and the portID
+ * - IX_ETH_DB_FIREWALL_RECORD requires the MAC address and the portID
+ *
+ * Please note that if a parameter is not required it is completely ignored (it does not undergo parameter checking).
+ * The user-defined field can be cleared using a <b>NULL</b> <i>field</i> parameter.
+ *
+ * @param recordType @ref IxEthDBRecordType [in] - type of record (can be IX_ETH_DB_FILTERING_RECORD,
+ * IX_ETH_DB_FILTERING_VLAN_RECORD, IX_ETH_DB_WIFI_RECORD or IX_ETH_DB_FIREWALL_RECORD)
+ * @param portID @ref IxEthDBPortId [in] - ID of the port (required only for WIFI and FIREWALL records)
+ * @param macAddr @ref IxEthDBMacAddr * [in] - MAC address of the record
+ * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID of the record (required only for FILTERING_VLAN records)
+ * @param field void * [in] - user defined field
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID was required but it is not a valid port identifier
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer argument
+ * @retval IX_ETH_DB_NO_SUCH_ADDR record not found
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void **field)
+ *
+ * @brief Retrieves a user-defined field from a database record
+ *
+ * The database record is identified using a combination of the given parameters, depending on the record type.
+ * All the record types require the record MAC address.
+ *
+ * - IX_ETH_DB_FILTERING_RECORD requires only the MAC address
+ * - IX_ETH_DB_VLAN_FILTERING_RECORD requires the MAC address and the VLAN ID
+ * - IX_ETH_DB_WIFI_RECORD requires the MAC address and the portID
+ * - IX_ETH_DB_FIREWALL_RECORD requires the MAC address and the portID
+ *
+ * Please note that if a parameter is not required it is completely ignored (it does not undergo parameter checking).
+ *
+ * If no user-defined field was registered with the specified record then <b>NULL</b> will be written
+ * at the location specified by <i>field</i>.
+ *
+ * @param recordType type of record (can be IX_ETH_DB_FILTERING_RECORD, IX_ETH_DB_FILTERING_VLAN_RECORD, IX_ETH_DB_WIFI_RECORD
+ * or IX_ETH_DB_FIREWALL_RECORD)
+ * @param portID ID of the port (required only for WIFI and FIREWALL records)
+ * @param macAddr MAC address of the record
+ * @param vlanID VLAN ID of the record (required only for FILTERING_VLAN records)
+ * @param field location to write the user defined field into
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID was required but it is not a valid port identifier
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> or <i>field</i> pointer arguments
+ * @retval IX_ETH_DB_NO_SUCH_ADDR record not found
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portId, IxEthDBVlanId vlanID, void **field);
+
+/**
+ * @}
+ */
+
+#endif /* IxEthDB_H */
diff --git a/cpu/ixp/npe/include/IxEthDBLocks_p.h b/cpu/ixp/npe/include/IxEthDBLocks_p.h
new file mode 100644
index 0000000..1d8b24f
--- /dev/null
+++ b/cpu/ixp/npe/include/IxEthDBLocks_p.h
@@ -0,0 +1,122 @@
+/**
+ * @file IxEthAccDBLocks_p.h
+ *
+ * @brief Definition of transaction lock stacks and lock utility macros
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxEthAccDBLocks_p_H
+#define IxEthAccDBLocks_p_H
+
+#include "IxOsPrintf.h"
+
+/* Lock and lock stacks */
+typedef struct
+{
+ IxOsalFastMutex* locks[MAX_LOCKS];
+ UINT32 stackPointer, basePointer;
+} LockStack;
+
+#define TRY_LOCK(mutex) \
+ { \
+ if (ixOsalFastMutexTryLock(mutex) != IX_SUCCESS) \
+ { \
+ return IX_ETH_DB_BUSY; \
+ } \
+ }
+
+
+#define UNLOCK(mutex) { ixOsalFastMutexUnlock(mutex); }
+
+#define INIT_STACK(stack) \
+ { \
+ (stack)->basePointer = 0; \
+ (stack)->stackPointer = 0; \
+ }
+
+#define PUSH_LOCK(stack, lock) \
+ { \
+ if ((stack)->stackPointer == MAX_LOCKS) \
+ { \
+ ERROR_LOG("Ethernet DB: maximum number of elements in a lock stack has been exceeded on push, heavy chaining?\n"); \
+ UNROLL_STACK(stack); \
+ \
+ return IX_ETH_DB_NOMEM; \
+ } \
+ \
+ if (ixOsalFastMutexTryLock(lock) == IX_SUCCESS) \
+ { \
+ (stack)->locks[(stack)->stackPointer++] = (lock); \
+ } \
+ else \
+ { \
+ UNROLL_STACK(stack); \
+ \
+ return IX_ETH_DB_BUSY; \
+ } \
+ }
+
+#define POP_LOCK(stack) \
+ { \
+ ixOsalFastMutexUnlock((stack)->locks[--(stack)->stackPointer]); \
+ }
+
+#define UNROLL_STACK(stack) \
+ { \
+ while ((stack)->stackPointer > (stack)->basePointer) \
+ { \
+ POP_LOCK(stack); \
+ } \
+ }
+
+#define SHIFT_STACK(stack) \
+ { \
+ if ((stack)->basePointer == MAX_LOCKS - 1) \
+ { \
+ ERROR_LOG("Ethernet DB: maximum number of elements in a lock stack has been exceeded on shift, heavy chaining?\n"); \
+ UNROLL_STACK(stack); \
+ \
+ return IX_ETH_DB_BUSY; \
+ } \
+ \
+ ixOsalFastMutexUnlock((stack)->locks[(stack)->basePointer++]); \
+ }
+
+#endif /* IxEthAccDBLocks_p_H */
diff --git a/cpu/ixp/npe/include/IxEthDBLog_p.h b/cpu/ixp/npe/include/IxEthDBLog_p.h
new file mode 100644
index 0000000..1d6b0bb
--- /dev/null
+++ b/cpu/ixp/npe/include/IxEthDBLog_p.h
@@ -0,0 +1,227 @@
+/**
+ * @file IxEthDBLog_p.h
+ *
+ * @brief definitions of log macros and log configuration
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include <IxOsal.h>
+
+#ifdef IX_UNIT_TEST
+#define NULL_PRINT_ROUTINE(format, arg...) /* nothing */
+#else
+#define NULL_PRINT_ROUTINE if(0) printf
+#endif
+
+/***************************************************
+ * Globals *
+ ***************************************************/
+/* safe to permanently leave these on */
+#define HAS_ERROR_LOG
+#define HAS_ERROR_IRQ_LOG
+#define HAS_WARNING_LOG
+
+/***************************************************
+ * Log Configuration *
+ ***************************************************/
+
+/* debug output can be turned on unless specifically
+ declared as a non-debug build */
+#ifndef NDEBUG
+
+#undef HAS_EVENTS_TRACE
+#undef HAS_EVENTS_VERBOSE_TRACE
+
+#undef HAS_SUPPORT_TRACE
+#undef HAS_SUPPORT_VERBOSE_TRACE
+
+#undef HAS_NPE_TRACE
+#undef HAS_NPE_VERBOSE_TRACE
+#undef HAS_DUMP_NPE_TREE
+
+#undef HAS_UPDATE_TRACE
+#undef HAS_UPDATE_VERBOSE_TRACE
+
+#endif /* NDEBUG */
+
+
+/***************************************************
+ * Log Macros *
+ ***************************************************/
+
+/************** Globals ******************/
+
+#ifdef HAS_ERROR_LOG
+
+ #define ERROR_LOG printf
+
+#else
+
+ #define ERROR_LOG NULL_PRINT_ROUTINE
+
+#endif
+
+#ifdef HAS_ERROR_IRQ_LOG
+
+ #define ERROR_IRQ_LOG(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6)
+
+#else
+
+ #define ERROR_IRQ_LOG(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */
+
+#endif
+
+#ifdef HAS_WARNING_LOG
+
+ #define WARNING_LOG printf
+
+#else
+
+ #define WARNING_LOG NULL_PRINT_ROUTINE
+
+#endif
+
+/************** Events *******************/
+
+#ifdef HAS_EVENTS_TRACE
+
+ #define IX_ETH_DB_EVENTS_TRACE printf
+ #define IX_ETH_DB_IRQ_EVENTS_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6)
+
+ #ifdef HAS_EVENTS_VERBOSE_TRACE
+
+ #define IX_ETH_DB_EVENTS_VERBOSE_TRACE printf
+
+ #else
+
+ #define IX_ETH_DB_EVENTS_VERBOSE_TRACE NULL_PRINT_ROUTINE
+
+ #endif /* HAS_EVENTS_VERBOSE_TRACE */
+
+#else
+
+ #define IX_ETH_DB_EVENTS_TRACE NULL_PRINT_ROUTINE
+ #define IX_ETH_DB_EVENTS_VERBOSE_TRACE NULL_PRINT_ROUTINE
+ #define IX_ETH_DB_IRQ_EVENTS_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */
+
+#endif /* HAS_EVENTS_TRACE */
+
+/************** Support *******************/
+
+#ifdef HAS_SUPPORT_TRACE
+
+ #define IX_ETH_DB_SUPPORT_TRACE printf
+ #define IX_ETH_DB_SUPPORT_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6)
+
+ #ifdef HAS_SUPPORT_VERBOSE_TRACE
+
+ #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE printf
+
+ #else
+
+ #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE NULL_PRINT_ROUTINE
+
+ #endif /* HAS_SUPPORT_VERBOSE_TRACE */
+
+#else
+
+ #define IX_ETH_DB_SUPPORT_TRACE NULL_PRINT_ROUTINE
+ #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE NULL_PRINT_ROUTINE
+ #define IX_ETH_DB_SUPPORT_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */
+
+#endif /* HAS_SUPPORT_TRACE */
+
+/************** NPE Adaptor *******************/
+
+#ifdef HAS_NPE_TRACE
+
+ #define IX_ETH_DB_NPE_TRACE printf
+ #define IX_ETH_DB_NPE_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6)
+
+ #ifdef HAS_NPE_VERBOSE_TRACE
+
+ #define IX_ETH_DB_NPE_VERBOSE_TRACE printf
+
+ #else
+
+ #define IX_ETH_DB_NPE_VERBOSE_TRACE NULL_PRINT_ROUTINE
+
+ #endif /* HAS_NPE_VERBOSE_TRACE */
+
+#else
+
+ #define IX_ETH_DB_NPE_TRACE NULL_PRINT_ROUTINE
+ #define IX_ETH_DB_NPE_VERBOSE_TRACE NULL_PRINT_ROUTINE
+ #define IX_ETH_DB_NPE_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */
+
+#endif /* HAS_NPE_TRACE */
+
+#ifdef HAS_DUMP_NPE_TREE
+
+#define IX_ETH_DB_NPE_DUMP_ELT(eltBaseAddress, eltSize) ixEthELTDumpTree(eltBaseAddress, eltSize)
+
+#else
+
+#define IX_ETH_DB_NPE_DUMP_ELT(eltBaseAddress, eltSize) /* nothing */
+
+#endif /* HAS_DUMP_NPE_TREE */
+
+/************** Port Update *******************/
+
+#ifdef HAS_UPDATE_TRACE
+
+ #define IX_ETH_DB_UPDATE_TRACE printf
+
+ #ifdef HAS_UPDATE_VERBOSE_TRACE
+
+ #define IX_ETH_DB_UPDATE_VERBOSE_TRACE printf
+
+ #else
+
+ #define IX_ETH_DB_UPDATE_VERBOSE_TRACE NULL_PRINT_ROUTINE
+
+ #endif
+
+#else /* HAS_UPDATE_VERBOSE_TRACE */
+
+ #define IX_ETH_DB_UPDATE_TRACE NULL_PRINT_ROUTINE
+ #define IX_ETH_DB_UPDATE_VERBOSE_TRACE NULL_PRINT_ROUTINE
+
+#endif /* HAS_UPDATE_TRACE */
diff --git a/cpu/ixp/npe/include/IxEthDBMessages_p.h b/cpu/ixp/npe/include/IxEthDBMessages_p.h
new file mode 100644
index 0000000..ff18160
--- /dev/null
+++ b/cpu/ixp/npe/include/IxEthDBMessages_p.h
@@ -0,0 +1,258 @@
+/**
+ * @file IxEthDBMessages_p.h
+ *
+ * @brief Definitions of NPE messages
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxEthDBMessages_p_H
+#define IxEthDBMessages_p_H
+
+#include <IxEthNpe.h>
+#include <IxOsCacheMMU.h>
+#include "IxEthDB_p.h"
+
+/* events watched by the Eth event processor */
+#define IX_ETH_DB_MIN_EVENT_ID (IX_ETHNPE_EDB_GETMACADDRESSDATABASE)
+#define IX_ETH_DB_MAX_EVENT_ID (IX_ETHNPE_PC_SETAPMACTABLE)
+
+/* macros to fill and extract data from NPE messages - place any endian conversions here */
+#define RESET_ELT_MESSAGE(message) { memset((void *) &(message), 0, sizeof((message))); }
+#define NPE_MSG_ID(msg) ((msg).data[0] >> 24)
+
+#define FILL_SETPORTVLANTABLEENTRY_MSG(message, portID, setOffset, vlanMembershipSet, ttiSet) \
+ do { \
+ message.data[0] = (IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY << 24) | (portID << 16) | (setOffset * 2); \
+ message.data[1] = (vlanMembershipSet << 8) | ttiSet; \
+ } while (0);
+
+#define FILL_SETPORTVLANTABLERANGE_MSG(message, portID, offset, length, zone) \
+ do { \
+ message.data[0] = IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE << 24 | portID << 16 | offset << 9 | length << 1; \
+ message.data[1] = (UINT32) zone; \
+ } while (0);
+
+#define FILL_SETDEFAULTRXVID_MSG(message, portID, tpid, vlanTag) \
+ do { \
+ message.data[0] = (IX_ETHNPE_VLAN_SETDEFAULTRXVID << 24) \
+ | (portID << 16); \
+ \
+ message.data[1] = (tpid << 16) | vlanTag; \
+ } while (0);
+
+#define FILL_SETRXTAGMODE_MSG(message, portID, filterMode, tagMode) \
+ do { \
+ message.data[0] = IX_ETHNPE_VLAN_SETRXTAGMODE << 24 \
+ | portID << 16 \
+ | filterMode << 2 \
+ | tagMode; \
+ \
+ message.data[1] = 0; \
+ } while (0);
+
+#define FILL_SETRXQOSENTRY(message, portID, classIndex, trafficClass, aqmQueue) \
+ do { \
+ message.data[0] = IX_ETHNPE_VLAN_SETRXQOSENTRY << 24 \
+ | portID << 16 \
+ | classIndex; \
+ \
+ message.data[1] = trafficClass << 24 \
+ | 0x1 << 23 \
+ | aqmQueue << 16 \
+ | aqmQueue << 4; \
+ } while (0);
+
+#define FILL_SETPORTIDEXTRACTIONMODE(message, portID, enable) \
+ do { \
+ message.data[0] = IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE << 24 \
+ | portID << 16 \
+ | (enable ? 0x1 : 0x0); \
+ \
+ message.data[1] = 0; \
+ } while (0);
+
+
+#define FILL_SETBLOCKINGSTATE_MSG(message, portID, blocked) \
+ do { \
+ message.data[0] = IX_ETHNPE_STP_SETBLOCKINGSTATE << 24 \
+ | portID << 16 \
+ | (blocked ? 0x1 : 0x0); \
+ \
+ message.data[1] = 0; \
+ } while (0);
+
+#define FILL_SETBBSID_MSG(message, portID, bbsid) \
+ do { \
+ message.data[0] = IX_ETHNPE_PC_SETBBSID << 24 \
+ | portID << 16 \
+ | bbsid->macAddress[0] << 8 \
+ | bbsid->macAddress[1]; \
+ \
+ message.data[1] = bbsid->macAddress[2] << 24 \
+ | bbsid->macAddress[3] << 16 \
+ | bbsid->macAddress[4] << 8 \
+ | bbsid->macAddress[5]; \
+ } while (0);
+
+#define FILL_SETFRAMECONTROLDURATIONID(message, portID, frameControlDurationID) \
+ do { \
+ message.data[0] = (IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID << 24) | (portID << 16); \
+ message.data[1] = frameControlDurationID; \
+ } while (0);
+
+#define FILL_SETAPMACTABLE_MSG(message, zone) \
+ do { \
+ message.data[0] = IX_ETHNPE_PC_SETAPMACTABLE << 24 \
+ | 0 << 8 /* always use index 0 */ \
+ | 64; /* 32 entries, 8 bytes each, 4 bytes in a word */ \
+ message.data[1] = (UINT32) zone; \
+ } while (0);
+
+#define FILL_SETFIREWALLMODE_MSG(message, portID, epDelta, mode, address) \
+ do { \
+ message.data[0] = IX_ETHNPE_FW_SETFIREWALLMODE << 24 \
+ | portID << 16 \
+ | (epDelta & 0xFF) << 8 \
+ | mode; \
+ \
+ message.data[1] = (UINT32) address; \
+ } while (0);
+
+#define FILL_SETMACADDRESSDATABASE_MSG(message, portID, epDelta, blockCount, address) \
+ do { \
+ message.data[0] = IX_ETHNPE_EDB_SETMACADDRESSSDATABASE << 24 \
+ | (epDelta & 0xFF) << 8 \
+ | (blockCount & 0xFF); \
+ \
+ message.data[1] = (UINT32) address; \
+ } while (0);
+
+#define FILL_GETMACADDRESSDATABASE(message, npeId, zone) \
+ do { \
+ message.data[0] = IX_ETHNPE_EDB_GETMACADDRESSDATABASE << 24; \
+ message.data[1] = (UINT32) zone; \
+ } while (0);
+
+#define FILL_SETMAXFRAMELENGTHS_MSG(message, portID, maxRxFrameSize, maxTxFrameSize) \
+ do { \
+ message.data[0] = IX_ETHNPE_SETMAXFRAMELENGTHS << 24 \
+ | portID << 16 \
+ | ((maxRxFrameSize + 63) / 64) << 8 /* max Rx 64-byte blocks */ \
+ | (maxTxFrameSize + 63) / 64; /* max Tx 64-byte blocks */ \
+ \
+ message.data[1] = maxRxFrameSize << 16 | maxTxFrameSize; \
+ } while (0);
+
+#define FILL_SETPORTADDRESS_MSG(message, portID, macAddress) \
+ do { \
+ message.data[0] = IX_ETHNPE_EDB_SETPORTADDRESS << 24 \
+ | portID << 16 \
+ | macAddress[0] << 8 \
+ | macAddress[1]; \
+ \
+ message.data[1] = macAddress[2] << 24 \
+ | macAddress[3] << 16 \
+ | macAddress[4] << 8 \
+ | macAddress[5]; \
+ } while (0);
+
+/* access to a MAC node in the NPE tree */
+#define NPE_NODE_BYTE(eltNodeAddr, offset) (((UINT8 *) (eltNodeAddr))[offset])
+
+/* browsing of the implicit linear binary tree structure of the NPE tree */
+#define LEFT_CHILD_OFFSET(offset) ((offset) << 1)
+#define RIGHT_CHILD_OFFSET(offset) (((offset) << 1) + 1)
+
+#define IX_EDB_FLAGS_ACTIVE (0x2)
+#define IX_EDB_FLAGS_VALID (0x1)
+#define IX_EDB_FLAGS_RESERVED (0xfc)
+#define IX_EDB_FLAGS_INACTIVE_VALID (0x1)
+
+#define IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET (6)
+#define IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET (7)
+#define IX_EDB_NPE_NODE_WIFI_INDEX_OFFSET (6)
+#define IX_EDB_NPE_NODE_WIFI_FLAGS_OFFSET (7)
+#define IX_EDB_NPE_NODE_FW_FLAGS_OFFSET (1)
+#define IX_EDB_NPE_NODE_FW_RESERVED_OFFSET (6)
+#define IX_EDB_NPE_NODE_FW_ADDR_OFFSET (2)
+
+#define IX_EDB_NPE_NODE_VALID(address) ((NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) & IX_EDB_FLAGS_VALID) != 0)
+#define IX_EDB_NPE_NODE_ACTIVE(address) ((NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) & IX_EDB_FLAGS_ACTIVE) != 0)
+#define IX_EDB_NPE_NODE_PORT_ID(address) (NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET))
+
+/* macros to send messages to the NPEs */
+#define IX_ETHDB_ASYNC_SEND_NPE_MSG(npeId, msg, result) \
+ do { \
+ result = ixNpeMhMessageSend(npeId, msg, IX_NPEMH_SEND_RETRIES_DEFAULT); \
+ \
+ if (result != IX_SUCCESS) \
+ { \
+ ERROR_LOG("DB: Failed to send NPE message\n"); \
+ } \
+ } while (0);
+
+#define IX_ETHDB_SYNC_SEND_NPE_MSG(npeId, msg, result) \
+ do { \
+ result = ixNpeMhMessageWithResponseSend(npeId, msg, msg.data[0] >> 24, ixEthDBNpeMsgAck, IX_NPEMH_SEND_RETRIES_DEFAULT); \
+ \
+ if (result == IX_SUCCESS) \
+ { \
+ result = ixOsalMutexLock(&ixEthDBPortInfo[IX_ETH_DB_NPE_TO_PORT_ID(npeId)].npeAckLock, IX_ETH_DB_NPE_TIMEOUT); \
+ \
+ if (result != IX_SUCCESS) \
+ { \
+ ERROR_LOG("DB: NPE failed to respond within %dms\n", IX_ETH_DB_NPE_TIMEOUT); \
+ } \
+ } \
+ else \
+ { \
+ ERROR_LOG("DB: Failed to send NPE message\n"); \
+ } \
+ } while (0);
+
+#ifndef IX_NDEBUG
+#define IX_ETH_DB_NPE_MSG_HISTORY_DEPTH (100)
+extern IX_ETH_DB_PUBLIC UINT32 npeMsgHistory[IX_ETH_DB_NPE_MSG_HISTORY_DEPTH][2];
+extern IX_ETH_DB_PUBLIC UINT32 npeMsgHistoryLen;
+#endif
+
+#define IX_ETHDB_SEND_NPE_MSG(npeId, msg, result) { LOG_NPE_MSG(msg); IX_ETHDB_SYNC_SEND_NPE_MSG(npeId, msg, result); }
+
+#endif /* IxEthDBMessages_p_H */
diff --git a/cpu/ixp/npe/include/IxEthDBPortDefs.h b/cpu/ixp/npe/include/IxEthDBPortDefs.h
new file mode 100644
index 0000000..c3acbdd
--- /dev/null
+++ b/cpu/ixp/npe/include/IxEthDBPortDefs.h
@@ -0,0 +1,163 @@
+/**
+ * @file IxEthDBPortDefs.h
+ *
+ * @brief Public definition of the ports and port capabilities
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxEthDBPortDefs IXP400 Ethernet Database Port Definitions (IxEthDBPortDefs)
+ *
+ * @brief IXP400 Public definition of the ports and port capabilities
+ *
+ * @{
+ */
+
+#ifndef IxEthDBPortDefs_H
+#define IxEthDBPortDefs_H
+
+/**
+ * @brief Port types - currently only Ethernet NPEs are recognized as specific types
+ * All other (user-defined) ports must be specified as IX_ETH_GENERIC
+ */
+typedef enum
+{
+ IX_ETH_GENERIC = 0, /**< generic ethernet port */
+ IX_ETH_NPE /**< specific Ethernet NPE */
+} IxEthDBPortType;
+
+/**
+ * @brief Port capabilities - used by ixEthAccDatabaseMaintenance to decide whether it
+ * should manually age entries or not depending on the port capabilities.
+ *
+ * Ethernet NPEs have aging capabilities, meaning that they will age the entries
+ * automatically (by themselves).*/
+typedef enum
+{
+ IX_ETH_NO_CAPABILITIES = 0, /**< no aging capabilities */
+ IX_ETH_ENTRY_AGING = 0x1 /**< aging capabilities present */
+} IxEthDBPortCapability;
+
+/**
+ * @brief Port Definition - a structure contains the Port type and capabilities
+ */
+typedef struct
+{
+ IxEthDBPortType type;
+ IxEthDBPortCapability capabilities;
+} IxEthDBPortDefinition;
+
+/**
+ * @brief Port definitions structure, indexed on the port ID
+ * @warning Ports 0 and 1 are used by the Ethernet access component therefore
+ * it is essential to be left untouched. Port 2 here (WAN) is given as
+ * an example port. The NPE firmware also assumes the NPE B to be
+ * the port 0 and NPE C to be the port 1.
+ *
+ * @note that only 32 ports (0..31) are supported by EthDB
+ */
+static const IxEthDBPortDefinition ixEthDBPortDefinitions[] =
+{
+ /* id type capabilities */
+ { /* 0 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE B */
+ { /* 1 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE C */
+ { /* 2 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE A */
+ { /* 3 */ IX_ETH_GENERIC, IX_ETH_NO_CAPABILITIES }, /* WAN port */
+};
+
+/**
+ * @def IX_ETH_DB_NUMBER_OF_PORTS
+ * @brief number of supported ports
+ */
+#define IX_ETH_DB_NUMBER_OF_PORTS (sizeof (ixEthDBPortDefinitions) / sizeof (ixEthDBPortDefinitions[0]))
+
+/**
+ * @def IX_ETH_DB_UNKNOWN_PORT
+ * @brief definition of an unknown port
+ */
+#define IX_ETH_DB_UNKNOWN_PORT (0xff)
+
+/**
+ * @def IX_ETH_DB_ALL_PORTS
+ * @brief Special port ID indicating all the ports
+ * @note This port ID can be used only by a subset of the EthDB API; each
+ * function specifically mentions whether this is a valid parameter as the port ID
+ */
+#define IX_ETH_DB_ALL_PORTS (IX_ETH_DB_NUMBER_OF_PORTS + 1)
+
+/**
+ * @def IX_ETH_DB_PORTS_ASSERTION
+ * @brief catch invalid port definitions (<2) with a
+ * compile-time assertion resulting in a duplicate case error.
+ */
+#define IX_ETH_DB_PORTS_ASSERTION { switch(0) { case 0 : ; case 1 : ; case IX_ETH_DB_NUMBER_OF_PORTS : ; }}
+
+/**
+ * @def IX_ETH_DB_CHECK_PORT(portID)
+ * @brief safety checks to verify whether the port is invalid or uninitialized
+ */
+#define IX_ETH_DB_CHECK_PORT(portID) \
+{ \
+ if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \
+ { \
+ return IX_ETH_DB_INVALID_PORT; \
+ } \
+ \
+ if (!ixEthDBPortInfo[(portID)].enabled) \
+ { \
+ return IX_ETH_DB_PORT_UNINITIALIZED; \
+ } \
+}
+
+/**
+ * @def IX_ETH_DB_CHECK_PORT_ALL(portID)
+ * @brief safety checks to verify whether the port is invalid or uninitialized;
+ * tolerates the use of IX_ETH_DB_ALL_PORTS
+ */
+#define IX_ETH_DB_CHECK_PORT_ALL(portID) \
+{ \
+ if ((portID) != IX_ETH_DB_ALL_PORTS) \
+ IX_ETH_DB_CHECK_PORT(portID) \
+}
+
+#endif /* IxEthDBPortDefs_H */
+/**
+ *@}
+ */
diff --git a/cpu/ixp/npe/include/IxEthDBQoS.h b/cpu/ixp/npe/include/IxEthDBQoS.h
new file mode 100644
index 0000000..6d34889
--- /dev/null
+++ b/cpu/ixp/npe/include/IxEthDBQoS.h
@@ -0,0 +1,154 @@
+/**
+ * @file IxEthDBQoS.h
+ *
+ * @brief Public definitions for QoS traffic classes
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxEthDBPortDefs IXP400 Ethernet QoS definitions
+ *
+ * @brief IXP00 Public definitions for QoS traffic classes
+ *
+ * @{
+ */
+
+#ifndef IxEthDBQoS_H
+#define IxEthDBQoS_H
+
+/**
+ * @def IX_ETH_DB_QUEUE_UNAVAILABLE
+ * @brief alias to indicate a queue (traffic class) is not available
+ */
+#define IX_ETH_DB_QUEUE_UNAVAILABLE (0)
+
+#ifndef IX_IEEE802_1Q_QOS_PRIORITY_COUNT
+/**
+ * @def IX_IEEE802_1Q_QOS_PRIORITY_COUNT
+ * @brief number of QoS priorities, according to IEEE 802.1Q
+ */
+#define IX_IEEE802_1Q_QOS_PRIORITY_COUNT (8)
+#endif
+
+/**
+ * @brief array containing all the supported traffic class configurations
+ */
+static const
+UINT8 ixEthDBQueueAssignments[][IX_IEEE802_1Q_QOS_PRIORITY_COUNT] =
+{
+ { 4, 5, 6, 7, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE },
+ { 15, 16, 17, 18, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE },
+ { 11, 23, 26, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE },
+ { 4, 5, 6, 7, 8, 9, 10, 11 }
+ /* add here all other cases of queue configuration structures and update ixEthDBTrafficClassDefinitions to use them */
+};
+
+/**
+ * @brief value used to index the NPE A functionality ID in the traffic class definition table
+ */
+#define IX_ETH_DB_NPE_A_FUNCTIONALITY_ID_INDEX (0)
+
+/**
+ * @brief value used to index the traffic class count in the traffic class definition table
+ */
+#define IX_ETH_DB_TRAFFIC_CLASS_COUNT_INDEX (1)
+
+/**
+ * @brief value used to index the queue assignment index in the traffic class definition table
+ */
+#define IX_ETH_DB_QUEUE_ASSIGNMENT_INDEX (2)
+
+/**
+ * @brief traffic class definitions
+ *
+ * This array contains the default traffic class definition configuration,
+ * as well as any special cases dictated by the functionality ID of NPE A.
+ *
+ * The default case should not be removed (otherwise the Ethernet
+ * components will assert a fatal failure on initialization).
+ */
+static const
+UINT8 ixEthDBTrafficClassDefinitions[][3] =
+{
+ /* NPE A functionality ID | traffic class count | queue assignment index (points to the queue enumeration in ixEthDBQueueAssignments) */
+ { 0x00, 4, 0 }, /* default case - DO NOT REMOVE */
+ { 0x04, 4, 1 }, /* NPE A image ID 0.4.0.0 */
+ { 0x09, 3, 2 }, /* NPE A image ID 0.9.0.0 */
+ { 0x80, 8, 3 }, /* NPE A image ID 10.80.02.0 */
+ { 0x81, 8, 3 }, /* NPE A image ID 10.81.02.0 */
+ { 0x82, 8, 3 } /* NPE A image ID 10.82.02.0 */
+};
+
+/**
+ * @brief IEEE 802.1Q recommended QoS Priority => traffic class maps
+ *
+ * @verbatim
+ Number of available traffic classes
+ 1 2 3 4 5 6 7 8
+ QoS Priority
+ 0 0 0 0 1 1 1 1 2
+ 1 0 0 0 0 0 0 0 0
+ 2 0 0 0 0 0 0 0 1
+ 3 0 0 0 1 1 2 2 3
+ 4 0 1 1 2 2 3 3 4
+ 5 0 1 1 2 3 4 4 5
+ 6 0 1 2 3 4 5 5 6
+ 7 0 1 2 3 4 5 6 7
+
+ @endverbatim
+ */
+static const
+UINT8 ixEthIEEE802_1QUserPriorityToTrafficClassMapping[IX_IEEE802_1Q_QOS_PRIORITY_COUNT][IX_IEEE802_1Q_QOS_PRIORITY_COUNT] =
+ {
+ { 0, 0, 0, 0, 0, 0, 0, 0 }, /* 1 traffic class available */
+ { 0, 0, 0, 0, 1, 1, 1, 1 }, /* 2 traffic classes available */
+ { 0, 0, 0, 0, 1, 1, 2, 2 }, /* 3 traffic classes available */
+ { 1, 0, 0, 1, 2, 2, 3, 3 }, /* 4 traffic classes available */
+ { 1, 0, 0, 1, 2, 3, 4, 4 }, /* 5 traffic classes available */
+ { 1, 0, 0, 2, 3, 4, 5, 5 }, /* 6 traffic classes available */
+ { 1, 0, 0, 2, 3, 4, 5, 6 }, /* 7 traffic classes available */
+ { 2, 0, 1, 3, 4, 5, 6, 7 } /* 8 traffic classes available */
+ };
+
+#endif /* IxEthDBQoS_H */
+
+/**
+ *@}
+ */
diff --git a/cpu/ixp/npe/include/IxEthDB_p.h b/cpu/ixp/npe/include/IxEthDB_p.h
new file mode 100644
index 0000000..e7c67ae
--- /dev/null
+++ b/cpu/ixp/npe/include/IxEthDB_p.h
@@ -0,0 +1,712 @@
+/**
+ * @file IxEthDB_p.h
+ *
+ * @brief Private MAC learning API
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxEthDB_p_H
+#define IxEthDB_p_H
+
+#include <IxTypes.h>
+#include <IxOsal.h>
+#include <IxEthDB.h>
+#include <IxNpeMh.h>
+#include <IxEthDBPortDefs.h>
+
+#include "IxEthDBMessages_p.h"
+#include "IxEthDBLog_p.h"
+
+#if (CPU==SIMSPARCSOLARIS)
+
+/* when running unit tests intLock() won't protect the event queue so we lock it manually */
+#define TEST_FIXTURE_LOCK_EVENT_QUEUE { ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER); }
+#define TEST_FIXTURE_UNLOCK_EVENT_QUEUE { ixOsalMutexUnlock(&eventQueueLock); }
+
+#else
+
+#define TEST_FIXTURE_LOCK_EVENT_QUEUE /* nothing */
+#define TEST_FIXTURE_UNLOCK_EVENT_QUEUE /* nothing */
+
+#endif /* #if(CPU==SIMSPARCSOLARIS) */
+
+#ifndef IX_UNIT_TEST
+
+#define TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER /* nothing */
+#define TEST_FIXTURE_MARK_OVERFLOW_EVENT /* nothing */
+
+#else
+
+extern int dbAccessCounter;
+extern int overflowEvent;
+
+#define TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER { dbAccessCounter++; }
+#define TEST_FIXTURE_MARK_OVERFLOW_EVENT { overflowEvent = 1; }
+
+#endif
+
+/* code readability markers */
+#define __mempool__ /* memory pool marker */
+#define __lock__ /* hash write locking marker */
+#define __smartpointer__ /* smart pointer marker - warning: use only clone() when duplicating! */
+#define __alignment__ /* marker for data used only as alignment zones */
+
+/* constants */
+#define IX_ETH_DB_NPE_TIMEOUT (100) /* NPE response timeout, in ms */
+
+/**
+ * number of hash table buckets
+ * it should be at least 8x the predicted number of entries for performance
+ * each bucket needs 8 bytes
+ */
+#define NUM_BUCKETS (8192)
+
+/**
+ * number of hash table buckets to preload when incrementing bucket iterator
+ * = two cache lines
+ */
+#define IX_ETHDB_CACHE_LINE_AHEAD (2)
+
+#define IX_ETHDB_BUCKETPTR_AHEAD ((IX_ETHDB_CACHE_LINE_AHEAD * IX_OSAL_CACHE_LINE_SIZE)/sizeof(void *))
+
+#define IX_ETHDB_BUCKET_INDEX_MASK (((IX_OSAL_CACHE_LINE_SIZE)/sizeof(void *)) - 1)
+
+/* locks */
+#define MAX_LOCKS (20) /**< maximum number of locks used simultaneously, do not tamper with */
+
+/* learning tree constants */
+#define INITIAL_ELT_SIZE (8) /**< initial byte size of tree (empty unused root size) */
+#define MAX_ELT_SIZE (512) /**< maximum number of entries (includes unused root) */
+#define MAX_GW_SIZE (32) /**< maximum number of gateway entries (including unused root) */
+#define MAX_FW_SIZE (32) /**< maximum number of firewall entries (including unused root) */
+#define ELT_ENTRY_SIZE (8) /**< entry size, in bytes */
+#define ELT_ROOT_OFFSET (ELT_ENTRY_SIZE) /**< tree root offset, in bytes - node preceeding root is unused */
+#define FULL_ELT_BYTE_SIZE (MAX_ELT_SIZE * ELT_ENTRY_SIZE) /**< full size of tree, in bytes, including unused root */
+#define FULL_GW_BYTE_SIZE (MAX_GW_SIZE * ELT_ENTRY_SIZE) /**< full size of gateway list, in bytes, including unused root */
+#define FULL_FW_BYTE_SIZE (MAX_FW_SIZE * ELT_ENTRY_SIZE) /**< full size of firewall table, in bytes, including unused root */
+
+/* maximum size of the VLAN table:
+ * 4096 bits (one per VLAN)
+ * 8 bits in one byte
+ * interleaved VLAN membership and VLAN TTI (*2) */
+#define FULL_VLAN_BYTE_SIZE (4096 / 8 * 2)
+
+/* upper 9 bits used as set index, lower 3 bits as byte index */
+#define VLAN_SET_OFFSET(vlanID) ((vlanID) >> 3)
+#define VLAN_SET_MASK(vlanID) (0x7 - ((vlanID) & 0x7))
+
+/* Update zone definitions */
+#define NPE_TREE_MEM_SIZE (4096) /* ((511 entries + 1 unused root) * 8 bytes/entry) */
+
+/* check the above value, we rely on 4k */
+#if NPE_TREE_MEM_SIZE != 4096
+ #error NPE_TREE_MEM_SIZE is not defined to 4096 bytes!
+#endif
+
+/* Size Filtering limits (Jumbo frame filtering) */
+#define IX_ETHDB_MAX_FRAME_SIZE 65535 /* other ports than NPE ports */
+#define IX_ETHDB_MIN_FRAME_SIZE 1 /* other ports than NPE ports */
+#define IX_ETHDB_MAX_NPE_FRAME_SIZE 16320 /* NPE ports firmware limit */
+#define IX_ETHDB_MIN_NPE_FRAME_SIZE 1 /* NPE ports firmware limit */
+#define IX_ETHDB_DEFAULT_FRAME_SIZE 1522
+
+/* memory management pool sizes */
+
+/*
+ * Note:
+ *
+ * NODE_POOL_SIZE controls the maximum number of elements in the database at any one time.
+ * It should be large enough to cover all the search trees of all the ports simultaneously.
+ *
+ * MAC_POOL_SIZE should be higher than NODE_POOL_SIZE by at least the total number of MAC addresses
+ * possible to be held at any time in all the ports.
+ *
+ * TREE_POOL_SIZE should follow the same guideline as for MAC_POOL_SIZE.
+ *
+ * The database structure described here (2000/4000/4000) is enough for two NPEs holding at most 511
+ * entries each plus one PCI NIC holding at most 900 entries.
+ */
+
+#define NODE_POOL_SIZE (2000) /**< number of HashNode objects - also master number of elements in the database; each entry has 16 bytes */
+#define MAC_POOL_SIZE (4000) /**< number of MacDescriptor objects; each entry has 28 bytes */
+#define TREE_POOL_SIZE (4000) /**< number of MacTreeNode objects; each entry has 16 bytes */
+
+/* retry policies */
+#define BUSY_RETRY_ENABLED (TRUE) /**< if set to TRUE the API will retry automatically calls returning BUSY */
+#define FOREVER_RETRY (TRUE) /**< if set to TRUE the API will retry forever BUSY calls */
+#define MAX_RETRIES (400) /**< upper retry limit - used only when FOREVER_RETRY is FALSE */
+#define BUSY_RETRY_YIELD (5) /**< ticks to yield for every failed retry */
+
+/* event management */
+#define EVENT_QUEUE_SIZE (500) /**< size of the sink collecting events from the Message Handler FIFO */
+#define EVENT_PROCESSING_LIMIT (100) /**< batch processing control size (how many events are extracted from the queue at once) */
+
+/* MAC descriptors */
+#define STATIC_ENTRY (TRUE)
+#define DYNAMIC_ENTRY (FALSE)
+
+/* age reset on next maintenance - incrementing by 1 will reset to 0 */
+#define AGE_RESET (0xFFFFFFFF)
+
+/* dependency maps */
+#define EMPTY_DEPENDENCY_MAP (0)
+
+/* trees */
+#define RIGHT (1)
+#define LEFT (-1)
+
+/* macros */
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+#define IX_ETH_DB_CHECK_PORT_EXISTS(portID) \
+{ \
+ if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \
+ { \
+ return IX_ETH_DB_INVALID_PORT; \
+ } \
+}
+
+#define IX_ETH_DB_CHECK_PORT_INITIALIZED(portID) \
+{ \
+ if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \
+ { \
+ return IX_ETH_DB_INVALID_PORT; \
+ } \
+ else \
+ { \
+ if (!ixEthDBPortInfo[portID].initialized) \
+ { \
+ return IX_ETH_DB_PORT_UNINITIALIZED; \
+ } \
+ } \
+}
+
+/* single NPE check */
+#define IX_ETH_DB_CHECK_SINGLE_NPE(portID) \
+ if (ixEthDBSingleEthNpeCheck(portID) != IX_ETH_DB_SUCCESS) \
+ { \
+ WARNING_LOG("EthDB: port ID %d is unavailable\n",(UINT32) portID); \
+ \
+ return IX_ETH_DB_INVALID_PORT; \
+ }
+
+/* feature check */
+#define IX_ETH_DB_CHECK_FEATURE(portID, feature) \
+ if ((ixEthDBPortInfo[portID].featureStatus & feature) == 0) \
+ { \
+ return IX_ETH_DB_FEATURE_UNAVAILABLE; \
+ }
+
+/* busy retrying */
+#define BUSY_RETRY(functionCall) \
+ { \
+ UINT32 retries = 0; \
+ IxEthDBStatus br_result; \
+ \
+ while ((br_result = functionCall) == IX_ETH_DB_BUSY \
+ && BUSY_RETRY_ENABLED && (FOREVER_RETRY || ++retries < MAX_RETRIES)) { ixOsalSleep(BUSY_RETRY_YIELD); }; \
+ \
+ if ((!FOREVER_RETRY && retries == MAX_RETRIES) || (br_result == IX_ETH_DB_FAIL)) \
+ {\
+ ERROR_LOG("Ethernet Learning Database Error: BUSY_RETRY failed at %s:%d\n", __FILE__, __LINE__); \
+ }\
+ }
+
+#define BUSY_RETRY_WITH_RESULT(functionCall, brwr_result) \
+ { \
+ UINT32 retries = 0; \
+ \
+ while ((brwr_result = functionCall) == IX_ETH_DB_BUSY \
+ && BUSY_RETRY_ENABLED && (FOREVER_RETRY || ++retries < MAX_RETRIES)) { ixOsalSleep(BUSY_RETRY_YIELD); }; \
+ \
+ if ((!FOREVER_RETRY && retries == MAX_RETRIES) || (brwr_result == IX_ETH_DB_FAIL)) \
+ {\
+ ERROR_LOG("Ethernet Learning Database Error: BUSY_RETRY_WITH_RESULT failed at %s:%d\n", __FILE__, __LINE__); \
+ }\
+ }
+
+/* iterators */
+#define IS_ITERATOR_VALID(iteratorPtr) ((iteratorPtr)->node != NULL)
+
+/* dependency port maps */
+
+/* Warning: if port indexing starts from 1 replace (portID) with (portID - 1) in DEPENDENCY_MAP (and make sure IX_ETH_DB_NUMBER_OF_PORTS is big enough) */
+
+/* gives an empty dependency map */
+#define SET_EMPTY_DEPENDENCY_MAP(map) { int i = 0; for (; i < 32 ; i++) map[i] = 0; }
+
+#define IS_EMPTY_DEPENDENCY_MAP(result, map) { int i = 0 ; result = TRUE; for (; i < 32 ; i++) if (map[i] != 0) { result = FALSE; break; }}
+
+/**
+ * gives a map consisting only of 'portID'
+ */
+#define SET_DEPENDENCY_MAP(map, portID) {SET_EMPTY_DEPENDENCY_MAP(map); map[portID >> 3] = 1 << (portID & 0x7);}
+
+/**
+ * gives a map resulting from joining map1 and map2
+ */
+#define JOIN_MAPS(map, map1, map2) { int i = 0; for (; i < 32 ; i++) map[i] = map1[i] | map2[i]; }
+
+/**
+ * gives the map resulting from joining portID and map
+ */
+#define JOIN_PORT_TO_MAP(map, portID) { map[portID >> 3] |= 1 << (portID & 0x7); }
+
+/**
+ * gives the map resulting from excluding portID from map
+ */
+#define EXCLUDE_PORT_FROM_MAP(map, portID) { map[portID >> 3] &= ~(1 << (portID & 0x7); }
+
+/**
+ * returns TRUE if map1 is a subset of map2 and FALSE otherwise
+ */
+#define IS_MAP_SUBSET(result, map1, map2) { int i = 0; result = TRUE; for (; i < 32 ; i++) if ((map1[i] | map2[i]) != map2[i]) result = FALSE; }
+
+/**
+ * returns TRUE is portID is part of map and FALSE otherwise
+ */
+#define IS_PORT_INCLUDED(portID, map) ((map[portID >> 3] & (1 << (portID & 0x7))) != 0)
+
+/**
+ * returns the difference between map1 and map2 (ports included in map1 and not included in map2)
+ */
+#define DIFF_MAPS(map, map1, map2) { int i = 0; for (; i < 32 ; i++) map[i] = map1[i] ^ (map1[i] & map2[i]); }
+
+/**
+ * returns TRUE if the maps collide (have at least one port in common) and FALSE otherwise
+ */
+#define MAPS_COLLIDE(result, map1, map2) { int i = 0; result = FALSE; for (; i < 32 ; i++) if ((map1[i] & map2[i]) != 0) result = TRUE; }
+
+/* size (number of ports) of a dependency map */
+#define GET_MAP_SIZE(map, size) { int i = 0, b = 0; size = 0; for (; i < 32 ; i++) { char y = map[i]; for (; b < 8 && (y >>= 1); b++) size += (y & 1); }}
+
+/* copy map2 into map1 */
+#define COPY_DEPENDENCY_MAP(map1, map2) { memcpy (map1, map2, sizeof (map1)); }
+
+/* definition of a port map size/port number which cannot be reached (we support at most 32 ports) */
+#define MAX_PORT_SIZE (0xFF)
+#define MAX_PORT_NUMBER (0xFF)
+
+#define IX_ETH_DB_CHECK_REFERENCE(ptr) { if ((ptr) == NULL) { return IX_ETH_DB_INVALID_ARG; } }
+#define IX_ETH_DB_CHECK_MAP(portID, map) { if (!IS_PORT_INCLUDED(portID, map)) { return IX_ETH_DB_INVALID_ARG; } }
+
+/* event queue macros */
+#define EVENT_QUEUE_WRAP(offset) ((offset) >= EVENT_QUEUE_SIZE ? (offset) - EVENT_QUEUE_SIZE : (offset))
+
+#define CAN_ENQUEUE(eventQueuePtr) ((eventQueuePtr)->length < EVENT_QUEUE_SIZE)
+
+#define QUEUE_HEAD(eventQueuePtr) (&(eventQueuePtr)->queue[EVENT_QUEUE_WRAP((eventQueuePtr)->base + (eventQueuePtr)->length)])
+
+#define QUEUE_TAIL(eventQueuePtr) (&(eventQueuePtr)->queue[(eventQueuePtr)->base])
+
+#define PUSH_UPDATE_QUEUE(eventQueuePtr) { (eventQueuePtr)->length++; }
+
+#define SHIFT_UPDATE_QUEUE(eventQueuePtr) \
+ { \
+ (eventQueuePtr)->base = EVENT_QUEUE_WRAP((eventQueuePtr)->base + 1); \
+ (eventQueuePtr)->length--; \
+ }
+
+#define RESET_QUEUE(eventQueuePtr) \
+ { \
+ (eventQueuePtr)->base = 0; \
+ (eventQueuePtr)->length = 0; \
+ }
+
+/* node stack macros - used to browse a tree without using a recursive function */
+#define NODE_STACK_INIT(stack) { (stack)->nodeCount = 0; }
+#define NODE_STACK_PUSH(stack, node, offset) { (stack)->nodes[(stack)->nodeCount] = (node); (stack)->offsets[(stack)->nodeCount++] = (offset); }
+#define NODE_STACK_POP(stack, node, offset) { (node) = (stack)->nodes[--(stack)->nodeCount]; offset = (stack)->offsets[(stack)->nodeCount]; }
+#define NODE_STACK_NONEMPTY(stack) ((stack)->nodeCount != 0)
+
+#ifndef IX_NDEBUG
+#define IX_ETH_DB_NPE_MSG_HISTORY_DEPTH (100)
+#define LOG_NPE_MSG(msg) \
+ do { \
+ UINT32 npeMsgHistoryIndex = (npeMsgHistoryLen++) % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH; \
+ npeMsgHistory[npeMsgHistoryIndex][0] = msg.data[0]; \
+ npeMsgHistory[npeMsgHistoryIndex][1] = msg.data[1]; \
+ } while (0);
+#else
+#define LOG_NPE_MSG() /* nothing */
+#endif
+
+/* ----------- Data -------------- */
+
+/* typedefs */
+
+typedef UINT32 (*HashFunction)(void *entity);
+typedef BOOL (*MatchFunction)(void *reference, void *entry);
+typedef void (*FreeFunction)(void *entry);
+
+/**
+ * basic component of a hash table
+ */
+typedef struct HashNode_t
+{
+ void *data; /**< specific data */
+ struct HashNode_t *next; /**< used for bucket chaining */
+
+ __mempool__ struct HashNode_t *nextFree; /**< memory pool management */
+
+ __lock__ IxOsalFastMutex lock; /**< node lock */
+} HashNode;
+
+/**
+ * @brief hash table iterator definition
+ *
+ * an iterator is an object which can be used
+ * to browse a hash table
+ */
+typedef struct
+{
+ UINT32 bucketIndex; /**< index of the currently iterated bucket */
+ HashNode *previousNode; /**< reference to the previously iterated node within the current bucket */
+ HashNode *node; /**< reference to the currently iterated node */
+} HashIterator;
+
+/**
+ * definition of a MAC descriptor (a database record)
+ */
+
+typedef enum
+{
+ IX_ETH_DB_WIFI_AP_TO_STA = 0x0,
+ IX_ETH_DB_WIFI_AP_TO_AP = 0x1
+} IxEthDBWiFiRecordType;
+
+typedef union
+{
+ struct
+ {
+ UINT32 age;
+ BOOL staticEntry; /**< TRUE if this address is static (doesn't age) */
+ } filteringData;
+
+ struct
+ {
+ UINT32 age;
+ BOOL staticEntry;
+ UINT32 ieee802_1qTag;
+ } filteringVlanData;
+
+ struct
+ {
+ IxEthDBWiFiRecordType type; /**< AP_TO_AP (0x1) or AP_TO_STA (0x0) */
+ UINT32 gwAddressIndex; /**< used only when linearizing the entries for NPE usage */
+ UINT8 gwMacAddress[IX_IEEE803_MAC_ADDRESS_SIZE];
+
+ __alignment__ UINT8 reserved2[2];
+ } wifiData;
+} IxEthDBRecordData;
+
+typedef struct MacDescriptor_t
+{
+ UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE];
+
+ __alignment__ UINT8 reserved1[2];
+
+ UINT32 portID;
+ IxEthDBRecordType type;
+ IxEthDBRecordData recordData;
+
+ /* used for internal operations, such as NPE linearization */
+ void *internal;
+
+ /* custom user data */
+ void *user;
+
+ __mempool__ struct MacDescriptor_t *nextFree; /**< memory pool management */
+ __smartpointer__ UINT32 refCount; /**< smart pointer reference counter */
+} MacDescriptor;
+
+/**
+ * hash table definition
+ */
+typedef struct
+{
+ HashNode *hashBuckets[NUM_BUCKETS];
+ UINT32 numBuckets;
+
+ __lock__ IxOsalFastMutex bucketLocks[NUM_BUCKETS];
+
+ HashFunction entryHashFunction;
+ MatchFunction *matchFunctions;
+ FreeFunction freeFunction;
+} HashTable;
+
+typedef enum
+{
+ IX_ETH_DB_MAC_KEY = 1,
+ IX_ETH_DB_MAC_PORT_KEY = 2,
+ IX_ETH_DB_MAC_VLAN_KEY = 3,
+ IX_ETH_DB_MAX_KEY_INDEX = 3
+} IxEthDBSearchKeyType;
+
+typedef struct MacTreeNode_t
+{
+ __smartpointer__ MacDescriptor *descriptor;
+ struct MacTreeNode_t *left, *right;
+
+ __mempool__ struct MacTreeNode_t *nextFree;
+} MacTreeNode;
+
+typedef IxEthDBStatus (*IxEthDBPortUpdateHandler)(IxEthDBPortId portID, IxEthDBRecordType type);
+
+typedef void (*IxEthDBNoteWriteFn)(void *address, MacTreeNode *node);
+
+typedef struct
+{
+ BOOL updateEnabled; /**< TRUE if updates are enabled for port */
+ BOOL userControlled; /**< TRUE if the user has manually used ixEthDBPortUpdateEnableSet */
+ BOOL treeInitialized; /**< TRUE if the NPE has received an initial tree */
+ IxEthDBPortUpdateHandler updateHandler; /**< port update handler routine */
+ void *npeUpdateZone; /**< port update memory zone */
+ void *npeGwUpdateZone; /**< port update memory zone for gateways */
+ void *vlanUpdateZone; /**< port update memory zone for VLAN tables */
+ MacTreeNode *searchTree; /**< internal search tree, in MacTreeNode representation */
+ BOOL searchTreePendingWrite; /**< TRUE if searchTree holds a tree pending write to the port */
+} PortUpdateMethod;
+
+typedef struct
+{
+ IxEthDBPortId portID; /**< port ID */
+ BOOL enabled; /**< TRUE if the port is enabled */
+ BOOL agingEnabled; /**< TRUE if aging on this port is enabled */
+ BOOL initialized;
+ IxEthDBPortMap dependencyPortMap; /**< dependency port map for this port */
+ PortUpdateMethod updateMethod; /**< update method structure */
+ BOOL macAddressUploaded; /**< TRUE if the MAC address was uploaded into the port */
+ UINT32 maxRxFrameSize; /**< maximum Rx frame size for this port */
+ UINT32 maxTxFrameSize; /**< maximum Rx frame size for this port */
+
+ UINT8 bbsid[6];
+ __alignment__ UINT8 reserved[2];
+ UINT32 frameControlDurationID; /**< Frame Control - Duration/ID WiFi control */
+
+ IxEthDBVlanTag vlanTag; /**< default VLAN tag for port */
+ IxEthDBPriorityTable priorityTable; /**< QoS <=> internal priority mapping */
+ IxEthDBVlanSet vlanMembership;
+ IxEthDBVlanSet transmitTaggingInfo;
+ IxEthDBFrameFilter frameFilter;
+ IxEthDBTaggingAction taggingAction;
+
+ UINT32 npeFrameFilter;
+ UINT32 npeTaggingAction;
+
+ IxEthDBFirewallMode firewallMode;
+ BOOL srcAddressFilterEnabled;
+
+ BOOL stpBlocked;
+
+ IxEthDBFeature featureCapability;
+ IxEthDBFeature featureStatus;
+
+ UINT32 ixEthDBTrafficClassAQMAssignments[IX_IEEE802_1Q_QOS_PRIORITY_COUNT];
+
+ UINT32 ixEthDBTrafficClassCount;
+
+ UINT32 ixEthDBTrafficClassAvailable;
+
+
+
+ __lock__ IxOsalMutex npeAckLock;
+} PortInfo;
+
+/* list of port information structures indexed on port Ids */
+extern IX_ETH_DB_PUBLIC PortInfo ixEthDBPortInfo[IX_ETH_DB_NUMBER_OF_PORTS];
+
+typedef enum
+{
+ IX_ETH_DB_ADD_FILTERING_RECORD = 0xFF0001,
+ IX_ETH_DB_REMOVE_FILTERING_RECORD = 0xFF0002
+} PortEventType;
+
+typedef struct
+{
+ UINT32 eventType;
+ IxEthDBPortId portID;
+ IxEthDBMacAddr macAddr;
+ BOOL staticEntry;
+} PortEvent;
+
+typedef struct
+{
+ PortEvent queue[EVENT_QUEUE_SIZE];
+ UINT32 base;
+ UINT32 length;
+} PortEventQueue;
+
+typedef struct
+{
+ IxEthDBPortId portID; /**< originating port */
+ MacDescriptor *macDescriptors[MAX_ELT_SIZE]; /**< addresses to be synced into db */
+ UINT32 addressCount; /**< number of addresses */
+} TreeSyncInfo;
+
+typedef struct
+{
+ MacTreeNode *nodes[MAX_ELT_SIZE];
+ UINT32 offsets[MAX_ELT_SIZE];
+ UINT32 nodeCount;
+} MacTreeNodeStack;
+
+/* Prototypes */
+
+/* ----------- Memory management -------------- */
+
+IX_ETH_DB_PUBLIC void ixEthDBInitMemoryPools(void);
+
+IX_ETH_DB_PUBLIC HashNode* ixEthDBAllocHashNode(void);
+IX_ETH_DB_PUBLIC void ixEthDBFreeHashNode(HashNode *);
+
+IX_ETH_DB_PUBLIC __smartpointer__ MacDescriptor* ixEthDBAllocMacDescriptor(void);
+IX_ETH_DB_PUBLIC __smartpointer__ MacDescriptor* ixEthDBCloneMacDescriptor(MacDescriptor *macDescriptor);
+IX_ETH_DB_PUBLIC __smartpointer__ void ixEthDBFreeMacDescriptor(MacDescriptor *);
+
+IX_ETH_DB_PUBLIC __smartpointer__ MacTreeNode* ixEthDBAllocMacTreeNode(void);
+IX_ETH_DB_PUBLIC __smartpointer__ MacTreeNode* ixEthDBCloneMacTreeNode(MacTreeNode *);
+IX_ETH_DB_PUBLIC __smartpointer__ void ixEthDBFreeMacTreeNode(MacTreeNode *);
+
+IX_ETH_DB_PUBLIC void ixEthDBPoolFreeMacTreeNode(MacTreeNode *);
+IX_ETH_DB_PUBLIC UINT32 ixEthDBSearchTreeUsageGet(MacTreeNode *tree);
+IX_ETH_DB_PUBLIC int ixEthDBShowMemoryStatus(void);
+
+/* Hash Table */
+IX_ETH_DB_PUBLIC void ixEthDBInitHash(HashTable *hashTable, UINT32 numBuckets, HashFunction entryHashFunction, MatchFunction *matchFunctions, FreeFunction freeFunction);
+
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAddHashEntry(HashTable *hashTable, void *entry);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemoveHashEntry(HashTable *hashTable, int keyType, void *reference);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBSearchHashEntry(HashTable *hashTable, int keyType, void *reference, HashNode **searchResult);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPeekHashEntry(HashTable *hashTable, int keyType, void *reference);
+IX_ETH_DB_PUBLIC void ixEthDBReleaseHashNode(HashNode *node);
+
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBInitHashIterator(HashTable *hashTable, HashIterator *iterator);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBIncrementHashIterator(HashTable *hashTable, HashIterator *iterator);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemoveEntryAtHashIterator(HashTable *hashTable, HashIterator *iterator);
+IX_ETH_DB_PUBLIC void ixEthDBReleaseHashIterator(HashIterator *iterator);
+
+/* API Support */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+IX_ETH_DB_PUBLIC void ixEthDBMaximumFrameSizeAckCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
+
+/* DB Core functions */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBInit(void);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAdd(MacDescriptor *newRecordTemplate, IxEthDBPortMap updateTrigger);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemove(MacDescriptor *templateRecord, IxEthDBPortMap updateTrigger);
+IX_ETH_DB_PUBLIC HashNode* ixEthDBSearch(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPeek(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter);
+
+/* Learning support */
+IX_ETH_DB_PUBLIC UINT32 ixEthDBAddressCompare(UINT8 *mac1, UINT8 *mac2);
+IX_ETH_DB_PUBLIC BOOL ixEthDBAddressMatch(void *reference, void *entry);
+IX_ETH_DB_PUBLIC UINT32 ixEthDBEntryXORHash(void *macDescriptor);
+IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyXORHash(void *macAddress);
+
+/* Port updates */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBNPEUpdateHandler(IxEthDBPortId portID, IxEthDBRecordType type);
+IX_ETH_DB_PUBLIC void ixEthDBUpdatePortLearningTrees(IxEthDBPortMap triggerPorts);
+IX_ETH_DB_PUBLIC void ixEthDBNPEAccessRequest(IxEthDBPortId portID);
+IX_ETH_DB_PUBLIC void ixEthDBUpdateLock(void);
+IX_ETH_DB_PUBLIC void ixEthDBUpdateUnlock(void);
+IX_ETH_DB_PUBLIC MacTreeNode* ixEthDBQuery(MacTreeNode *searchTree, IxEthDBPortMap query, IxEthDBRecordType recordFilter, UINT32 maximumEntries);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFirewallUpdate(IxEthDBPortId portID, void *address, UINT32 epDelta);
+
+/* Init/unload */
+IX_ETH_DB_PUBLIC void ixEthDBPortSetAckCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBEventProcessorInit(void);
+IX_ETH_DB_PUBLIC void ixEthDBPortInit(IxEthDBPortId portID);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID);
+IX_ETH_DB_PUBLIC void ixEthDBNPEUpdateAreasInit(void);
+IX_ETH_DB_PUBLIC UINT32 ixEthDBMatchMethodsRegister(MatchFunction *matchFunctions);
+IX_ETH_DB_PUBLIC UINT32 ixEthDBRecordSerializeMethodsRegister(void);
+IX_ETH_DB_PUBLIC UINT32 ixEthDBUpdateTypeRegister(BOOL *typeArray);
+IX_ETH_DB_PUBLIC void ixEthDBNPEUpdateAreasUnload(void);
+IX_ETH_DB_PUBLIC void ixEthDBFeatureCapabilityScan(void);
+IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyTypeRegister(UINT32 *keyType);
+
+/* Event processing */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBDefaultEventCallbackEnable(IxEthDBPortId portID, BOOL enable);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBTriggerAddPortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBTriggerRemovePortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID);
+IX_ETH_DB_PUBLIC void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
+
+/* NPE adaptor */
+IX_ETH_DB_PUBLIC void ixEthDBGetMacDatabaseCbk(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
+IX_ETH_DB_PUBLIC void ixEthDBNpeMsgAck(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
+IX_ETH_DB_PUBLIC void ixEthDBNPESyncScan(IxEthDBPortId portID, void *eltBaseAddress, UINT32 eltSize);
+IX_ETH_DB_PUBLIC void ixEthDBNPETreeWrite(IxEthDBRecordType type, UINT32 totalSize, void *baseAddress, MacTreeNode *tree, UINT32 *blocks, UINT32 *startIndex);
+IX_ETH_DB_PUBLIC void ixEthDBNPEGatewayNodeWrite(void *address, MacTreeNode *node);
+
+/* Other public API functions */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStartLearningFunction(void);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStopLearningFunction(void);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate);
+
+/* Maximum Tx/Rx public functions */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringPortMaximumRxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumRxFrameSize);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringPortMaximumTxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumTxFrameSize);
+
+/* VLAN-related */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortVlanTableSet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet);
+
+/* Record search */
+IX_ETH_DB_PUBLIC BOOL ixEthDBAddressRecordMatch(void *untypedReference, void *untypedEntry);
+IX_ETH_DB_PUBLIC BOOL ixEthDBVlanRecordMatch(void *untypedReference, void *untypedEntry);
+IX_ETH_DB_PUBLIC BOOL ixEthDBPortRecordMatch(void *untypedReference, void *untypedEntry);
+IX_ETH_DB_PUBLIC BOOL ixEthDBNullMatch(void *reference, void *entry);
+IX_ETH_DB_PUBLIC HashNode* ixEthDBPortSearch(IxEthDBMacAddr *macAddress, IxEthDBPortId portID, IxEthDBRecordType typeFilter);
+IX_ETH_DB_PUBLIC HashNode* ixEthDBVlanSearch(IxEthDBMacAddr *macAddress, IxEthDBVlanId vlanID, IxEthDBRecordType typeFilter);
+
+/* Utilities */
+IX_ETH_DB_PUBLIC const char* mac2string(const unsigned char *mac);
+IX_ETH_DB_PUBLIC void showHashInfo(void);
+IX_ETH_DB_PUBLIC int ixEthDBAnalyzeHash(void);
+IX_ETH_DB_PUBLIC const char* errorString(IxEthDBStatus error);
+IX_ETH_DB_PUBLIC int numHashElements(void);
+IX_ETH_DB_PUBLIC void zapHashtable(void);
+IX_ETH_DB_PUBLIC BOOL ixEthDBCheckSingleBitValue(UINT32 value);
+
+/* Single Eth NPE Check */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBSingleEthNpeCheck(IxEthDBPortId portId);
+
+#endif /* IxEthDB_p_H */
+
diff --git a/cpu/ixp/npe/include/IxEthMii.h b/cpu/ixp/npe/include/IxEthMii.h
new file mode 100644
index 0000000..a1bfe06
--- /dev/null
+++ b/cpu/ixp/npe/include/IxEthMii.h
@@ -0,0 +1,270 @@
+/**
+ * @file IxEthMii.h
+ *
+ * @brief this file contains the public API of @ref IxEthMii component
+ *
+ * Design notes :
+ * The main intent of this API is to inplement MII high level fonctionalitoes
+ * to support the codelets provided with the IXP400 software releases. It
+ * superceedes previous interfaces provided with @ref IxEThAcc component.
+ *
+ * This API has been tested with the PHYs provided with the
+ * IXP400 development platforms. It may not work for specific Ethernet PHYs
+ * used on specific boards.
+ *
+ * This source code detects and interface the LXT972, LXT973 and KS6995
+ * Ethernet PHYs.
+ *
+ * This source code should be considered as an example which may need
+ * to be adapted for different hardware implementations.
+ *
+ * It is strongly recommended to use public domain and GPL utilities
+ * like libmii, mii-diag for MII interface support.
+ *
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxEthMii_H
+#define IxEthMii_H
+
+#include <IxTypes.h>
+
+/**
+ * @defgroup IxEthMii IXP400 Ethernet Phy Access (IxEthMii) API
+ *
+ * @brief ethMii is a library that does provides access to the
+ * Ethernet PHYs
+ *
+ *@{
+ */
+
+/**
+ * @ingroup IxEthMii
+ *
+ * @fn ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount)
+ *
+ * @brief Scan the MDIO bus for PHYs
+ * This function scans PHY addresses 0 through 31, and sets phyPresent[n] to
+ * TRUE if a phy is discovered at address n.
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
+ *
+ * @param phyPresent BOOL [in] - boolean array of IXP425_ETH_ACC_MII_MAX_ADDR entries
+ * @param maxPhyCount UINT32 [in] - number of PHYs to search for (the scan will stop when
+ * the indicated number of PHYs is found).
+ *
+ * @return IX_STATUS
+ * - IX_ETH_ACC_SUCCESS
+ * - IX_ETH_ACC_FAIL : invalid arguments.
+ *
+ * <hr>
+ */
+PUBLIC IX_STATUS ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount);
+
+/**
+ * @ingroup IxEthMii
+ *
+ * @fn ixEthMiiPhyConfig(UINT32 phyAddr,
+ BOOL speed100,
+ BOOL fullDuplex,
+ BOOL autonegotiate)
+ *
+ *
+ * @brief Configure a PHY
+ * Configure a PHY's speed, duplex and autonegotiation status
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
+ *
+ * @param phyAddr UINT32 [in]
+ * @param speed100 BOOL [in] - set to TRUE for 100Mbit/s operation, FALSE for 10Mbit/s
+ * @param fullDuplex BOOL [in] - set to TRUE for Full Duplex, FALSE for Half Duplex
+ * @param autonegotiate BOOL [in] - set to TRUE to enable autonegotiation
+ *
+ * @return IX_STATUS
+ * - IX_SUCCESS
+ * - IX_FAIL : invalid arguments.
+ *
+ * <hr>
+ */
+PUBLIC IX_STATUS ixEthMiiPhyConfig(UINT32 phyAddr,
+ BOOL speed100,
+ BOOL fullDuplex,
+ BOOL autonegotiate);
+
+/**
+ * @ingroup IxEthMii
+ *
+ * @fn ixEthMiiPhyLoopbackEnable(UINT32 phyAddr)
+ *
+ *
+ * @brief Enable PHY Loopback in a specific Eth MII port
+ *
+ * @note When PHY Loopback is enabled, frames sent out to the PHY from the
+ * IXP400 will be looped back to the IXP400. They will not be transmitted out
+ * on the wire.
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31)
+ *
+ * @return IX_STATUS
+ * - IX_SUCCESS
+ * - IX_FAIL : invalid arguments.
+ * <hr>
+ */
+PUBLIC IX_STATUS
+ixEthMiiPhyLoopbackEnable (UINT32 phyAddr);
+
+/**
+ * @ingroup IxEthMii
+ *
+ * @fn ixEthMiiPhyLoopbackDisable(UINT32 phyAddr)
+ *
+ *
+ * @brief Disable PHY Loopback in a specific Eth MII port
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31)
+ *
+ * @return IX_STATUS
+ * - IX_SUCCESS
+ * - IX_FAIL : invalid arguments.
+ * <hr>
+ */
+PUBLIC IX_STATUS
+ixEthMiiPhyLoopbackDisable (UINT32 phyAddr);
+
+/**
+ * @ingroup IxEthMii
+ *
+ * @fn ixEthMiiPhyReset(UINT32 phyAddr)
+ *
+ * @brief Reset a PHY
+ * Reset a PHY
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
+ *
+ * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31)
+ *
+ * @return IX_STATUS
+ * - IX_SUCCESS
+ * - IX_FAIL : invalid arguments.
+ *
+ * <hr>
+ */
+PUBLIC IX_STATUS ixEthMiiPhyReset(UINT32 phyAddr);
+
+
+/**
+ * @ingroup IxEthMii
+ *
+ * @fn ixEthMiiLinkStatus(UINT32 phyAddr,
+ BOOL *linkUp,
+ BOOL *speed100,
+ BOOL *fullDuplex,
+ BOOL *autoneg)
+ *
+ * @brief Retrieve the current status of a PHY
+ * Retrieve the link, speed, duplex and autonegotiation status of a PHY
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
+ *
+ * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31)
+ * @param linkUp BOOL [out] - set to TRUE if the link is up
+ * @param speed100 BOOL [out] - set to TRUE indicates 100Mbit/s, FALSE indicates 10Mbit/s
+ * @param fullDuplex BOOL [out] - set to TRUE indicates Full Duplex, FALSE indicates Half Duplex
+ * @param autoneg BOOL [out] - set to TRUE indicates autonegotiation is enabled, FALSE indicates autonegotiation is disabled
+ *
+ * @return IX_STATUS
+ * - IX_SUCCESS
+ * - IX_FAIL : invalid arguments.
+ *
+ * <hr>
+ */
+PUBLIC IX_STATUS ixEthMiiLinkStatus(UINT32 phyAddr,
+ BOOL *linkUp,
+ BOOL *speed100,
+ BOOL *fullDuplex,
+ BOOL *autoneg);
+
+/**
+ * @ingroup IxEthMii
+ *
+ * @fn ixEthMiiPhyShow (UINT32 phyAddr)
+ *
+ *
+ * @brief Display information on a specified PHY
+ * Display link status, speed, duplex and Auto Negotiation status
+ *
+ * - Reentrant - no
+ * - ISR Callable - no
+ *
+ * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
+ *
+ * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31)
+ *
+ * @return IX_STATUS
+ * - IX_SUCCESS
+ * - IX_FAIL : invalid arguments.
+ *
+ * <hr>
+ */
+PUBLIC IX_STATUS ixEthMiiPhyShow (UINT32 phyAddr);
+
+#endif /* ndef IxEthMii_H */
+/**
+ *@}
+ */
diff --git a/cpu/ixp/npe/include/IxEthMii_p.h b/cpu/ixp/npe/include/IxEthMii_p.h
new file mode 100644
index 0000000..104b65c
--- /dev/null
+++ b/cpu/ixp/npe/include/IxEthMii_p.h
@@ -0,0 +1,185 @@
+/**
+ * @file IxEthMii_p.h
+ *
+ * @author Intel Corporation
+ * @date
+ *
+ * @brief MII Header file
+ *
+ * Design Notes:
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxEthMii_p_H
+#define IxEthMii_p_H
+
+
+/* MII definitions - these have been verified against the LXT971 and
+ LXT972 PHYs*/
+
+#define IX_ETH_MII_MAX_REG_NUM 0x20 /* max number of registers */
+
+#define IX_ETH_MII_CTRL_REG 0x0 /* Control Register */
+#define IX_ETH_MII_STAT_REG 0x1 /* Status Register */
+#define IX_ETH_MII_PHY_ID1_REG 0x2 /* PHY identifier 1 Register */
+#define IX_ETH_MII_PHY_ID2_REG 0x3 /* PHY identifier 2 Register */
+#define IX_ETH_MII_AN_ADS_REG 0x4 /* Auto-Negotiation */
+ /* Advertisement Register */
+#define IX_ETH_MII_AN_PRTN_REG 0x5 /* Auto-Negotiation */
+ /* partner ability Register */
+#define IX_ETH_MII_AN_EXP_REG 0x6 /* Auto-Negotiation */
+ /* Expansion Register */
+#define IX_ETH_MII_AN_NEXT_REG 0x7 /* Auto-Negotiation */
+ /* next-page transmit Register */
+
+#define IX_ETH_MII_STAT2_REG 0x11 /* Status Register 2*/
+
+
+/* MII control register bit */
+
+#define IX_ETH_MII_CR_COLL_TEST 0x0080 /* collision test */
+#define IX_ETH_MII_CR_FDX 0x0100 /* FDX =1, half duplex =0 */
+#define IX_ETH_MII_CR_RESTART 0x0200 /* restart auto negotiation */
+#define IX_ETH_MII_CR_ISOLATE 0x0400 /* isolate PHY from MII */
+#define IX_ETH_MII_CR_POWER_DOWN 0x0800 /* power down */
+#define IX_ETH_MII_CR_AUTO_EN 0x1000 /* auto-negotiation enable */
+#define IX_ETH_MII_CR_100 0x2000 /* 0 = 10mb, 1 = 100mb */
+#define IX_ETH_MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
+#define IX_ETH_MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
+#define IX_ETH_MII_CR_NORM_EN 0x0000 /* just enable the PHY */
+#define IX_ETH_MII_CR_DEF_0_MASK 0xca7f /* they must return zero */
+#define IX_ETH_MII_CR_RES_MASK 0x007f /* reserved bits, return zero */
+
+/* MII Status register bit definitions */
+
+#define IX_ETH_MII_SR_LINK_STATUS 0x0004 /* link Status -- 1 = link */
+#define IX_ETH_MII_SR_AUTO_SEL 0x0008 /* auto speed select capable */
+#define IX_ETH_MII_SR_REMOTE_FAULT 0x0010 /* Remote fault detect */
+#define IX_ETH_MII_SR_AUTO_NEG 0x0020 /* auto negotiation complete */
+#define IX_ETH_MII_SR_10T_HALF_DPX 0x0800 /* 10BaseT HD capable */
+#define IX_ETH_MII_SR_10T_FULL_DPX 0x1000 /* 10BaseT FD capable */
+#define IX_ETH_MII_SR_TX_HALF_DPX 0x2000 /* TX HD capable */
+#define IX_ETH_MII_SR_TX_FULL_DPX 0x4000 /* TX FD capable */
+#define IX_ETH_MII_SR_T4 0x8000 /* T4 capable */
+#define IX_ETH_MII_SR_ABIL_MASK 0xff80 /* abilities mask */
+#define IX_ETH_MII_SR_EXT_CAP 0x0001 /* extended capabilities */
+
+
+/* LXT971/2 Status 2 register bit definitions */
+#define IX_ETH_MII_SR2_100 0x4000
+#define IX_ETH_MII_SR2_TX 0x2000
+#define IX_ETH_MII_SR2_RX 0x1000
+#define IX_ETH_MII_SR2_COL 0x0800
+#define IX_ETH_MII_SR2_LINK 0x0400
+#define IX_ETH_MII_SR2_FD 0x0200
+#define IX_ETH_MII_SR2_AUTO 0x0100
+#define IX_ETH_MII_SR2_AUTO_CMPLT 0x0080
+#define IX_ETH_MII_SR2_POLARITY 0x0020
+#define IX_ETH_MII_SR2_PAUSE 0x0010
+#define IX_ETH_MII_SR2_ERROR 0x0008
+
+/* MII Link Code word bit definitions */
+
+#define IX_ETH_MII_BP_FAULT 0x2000 /* remote fault */
+#define IX_ETH_MII_BP_ACK 0x4000 /* acknowledge */
+#define IX_ETH_MII_BP_NP 0x8000 /* nexp page is supported */
+
+/* MII Next Page bit definitions */
+
+#define IX_ETH_MII_NP_TOGGLE 0x0800 /* toggle bit */
+#define IX_ETH_MII_NP_ACK2 0x1000 /* acknowledge two */
+#define IX_ETH_MII_NP_MSG 0x2000 /* message page */
+#define IX_ETH_MII_NP_ACK1 0x4000 /* acknowledge one */
+#define IX_ETH_MII_NP_NP 0x8000 /* nexp page will follow */
+
+/* MII Expansion Register bit definitions */
+
+#define IX_ETH_MII_EXP_FAULT 0x0010 /* parallel detection fault */
+#define IX_ETH_MII_EXP_PRTN_NP 0x0008 /* link partner next-page able */
+#define IX_ETH_MII_EXP_LOC_NP 0x0004 /* local PHY next-page able */
+#define IX_ETH_MII_EXP_PR 0x0002 /* full page received */
+#define IX_ETH_MII_EXP_PRT_AN 0x0001 /* link partner auto neg able */
+
+/* technology ability field bit definitions */
+
+#define IX_ETH_MII_TECH_10BASE_T 0x0020 /* 10Base-T */
+#define IX_ETH_MII_TECH_10BASE_FD 0x0040 /* 10Base-T Full Duplex */
+#define IX_ETH_MII_TECH_100BASE_TX 0x0080 /* 100Base-TX */
+#define IX_ETH_MII_TECH_100BASE_TX_FD 0x0100 /* 100Base-TX Full Duplex */
+
+#define IX_ETH_MII_TECH_100BASE_T4 0x0200 /* 100Base-T4 */
+#define IX_ETH_MII_ADS_TECH_MASK 0x1fe0 /* technology abilities mask */
+#define IX_ETH_MII_TECH_MASK IX_ETH_MII_ADS_TECH_MASK
+#define IX_ETH_MII_ADS_SEL_MASK 0x001f /* selector field mask */
+
+#define IX_ETH_MII_AN_FAIL 0x10 /* auto-negotiation fail */
+#define IX_ETH_MII_STAT_FAIL 0x20 /* errors in the status register */
+#define IX_ETH_MII_PHY_NO_ABLE 0x40 /* the PHY lacks some abilities */
+
+/* Definitions for MII access routines*/
+
+#define IX_ETH_MII_GO BIT(31)
+#define IX_ETH_MII_WRITE BIT(26)
+#define IX_ETH_MII_TIMEOUT_10TH_SECS (5)
+#define IX_ETH_MII_10TH_SEC_IN_MILLIS (100)
+#define IX_ETH_MII_READ_FAIL BIT(31)
+
+/* When we reset the PHY we delay for 2 seconds to allow the reset to
+ complete*/
+#define IX_ETH_MII_RESET_DELAY_MS (2000)
+#define IX_ETH_MII_RESET_POLL_MS (50)
+
+#define IX_ETH_MII_REG_SHL 16
+#define IX_ETH_MII_ADDR_SHL 21
+
+/* supported PHYs */
+#define IX_ETH_MII_LXT971_PHY_ID 0x001378E0
+#define IX_ETH_MII_LXT972_PHY_ID 0x001378E2
+#define IX_ETH_MII_LXT973_PHY_ID 0x00137A10
+#define IX_ETH_MII_LXT973A3_PHY_ID 0x00137A11
+#define IX_ETH_MII_KS8995_PHY_ID 0x00221450
+#define IX_ETH_MII_LXT9785_PHY_ID 0x001378FF
+
+
+#define IX_ETH_MII_INVALID_PHY_ID 0x00000000
+#define IX_ETH_MII_UNKNOWN_PHY_ID 0xffffffff
+
+#endif /*IxEthAccMii_p_H*/
diff --git a/cpu/ixp/npe/include/IxEthNpe.h b/cpu/ixp/npe/include/IxEthNpe.h
new file mode 100644
index 0000000..21bdedc
--- /dev/null
+++ b/cpu/ixp/npe/include/IxEthNpe.h
@@ -0,0 +1,695 @@
+#ifndef __doxygen_HIDE /* This file is not part of the API */
+
+/**
+ * @file IxEthNpe.h
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxEthNpe IXP400 Ethernet NPE (IxEthNpe) API
+ *
+ * @brief Contains the API for Ethernet NPE.
+ *
+ * All messages given to NPE, get back an acknowledgment. The acknowledgment
+ * is identical to the message sent to the NPE (except for NPE_GETSTATUS message).
+ *
+ * @{
+ */
+
+
+/*--------------------------------------------------------------------------
+ * APB Message IDs - XScale->NPE
+ *------------------------------------------------------------------------*/
+
+/**
+ * @def IX_ETHNPE_NPE_GETSTATUS
+ *
+ * @brief Request from the XScale client for the NPE to return the firmware
+ * version of the currently executing image.
+ *
+ * Acknowledgment message id is same as the request message id.
+ * NPE returns the firmware version ID to XScale.
+ */
+#define IX_ETHNPE_NPE_GETSTATUS 0x00
+
+/**
+ * @def IX_ETHNPE_EDB_SETPORTADDRESS
+ *
+ * @brief Request from the XScale client for the NPE to set the Ethernet
+ * port's port ID and MAC address.
+ */
+#define IX_ETHNPE_EDB_SETPORTADDRESS 0x01
+
+/**
+ * @def IX_ETHNPE_EDB_GETMACADDRESSDATABASE
+ *
+ * @brief Request from XScale client to the NPE requesting upload of
+ * Ethernet Filtering Database or Header Conversion Database from NPE's
+ * data memory to XScale accessible SDRAM.
+ */
+#define IX_ETHNPE_EDB_GETMACADDRESSDATABASE 0x02
+
+/**
+ * @def IX_ETHNPE_EDB_SETMACADDRESSSDATABASE
+ *
+ * @brief Request from XScale client to the NPE requesting download of
+ * Ethernet Filtering Database or Header Conversion Database from SDRAM
+ * to the NPE's datamemory.
+ */
+#define IX_ETHNPE_EDB_SETMACADDRESSSDATABASE 0x03
+
+/**
+ * @def IX_ETHNPE_GETSTATS
+ *
+ * @brief Request from the XScale client for the current MAC port statistics
+ * data to be written to the (empty) statistics structure and the specified
+ * location in externa memory.
+ */
+#define IX_ETHNPE_GETSTATS 0x04
+
+/**
+ * @def IX_ETHNPE_RESETSTATS
+ *
+ * @brief Request from the XScale client to the NPE to reset all of its internal
+ * MAC port statistics state variables.
+ *
+ * As a side effect, this message entails an implicit request that the NPE
+ * write the current MAC port statistics into the MAC statistics structure
+ * at the specified location in external memory.
+ */
+#define IX_ETHNPE_RESETSTATS 0x05
+
+/**
+ * @def IX_ETHNPE_SETMAXFRAMELENGTHS
+ *
+ * @brief Request from the XScale client to the NPE to configure maximum framelengths
+ * and block sizes in receive and transmit direction.
+ */
+#define IX_ETHNPE_SETMAXFRAMELENGTHS 0x06
+
+/**
+ * @def IX_ETHNPE_VLAN_SETRXTAGMODE
+ *
+ * @brief Request from the XScale client to the NPE to configure VLAN frame type
+ * filtering and VLAN the tagging mode for the receiver.
+ */
+#define IX_ETHNPE_VLAN_SETRXTAGMODE 0x07
+
+/**
+ * @def IX_ETHNPE_VLAN_SETDEFAULTRXVID
+ *
+ * @brief Request from the XScale client to the NPE to set receiver's default
+ * VLAN tag (PVID)and internal traffic class.
+ */
+#define IX_ETHNPE_VLAN_SETDEFAULTRXVID 0x08
+
+/**
+ * @def IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY
+ *
+ * @brief Request from the XScale client to the NPE to configure VLAN Port
+ * membership and Tx tagging for 8 consecutive VLANID's.
+ */
+#define IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY 0x09
+
+/**
+ * @def IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE
+ *
+ * @brief Request from the XScale client to the NPE to configure VLAN Port
+ * membership and Tx tagging for a range of VLANID's.
+ */
+#define IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE 0x0A
+
+/**
+ * @def IX_ETHNPE_VLAN_SETRXQOSENTRY
+ *
+ * @brief Request from the XScale client to the NPE to map a user priority
+ * to QoS class and an AQM queue number.
+ */
+#define IX_ETHNPE_VLAN_SETRXQOSENTRY 0x0B
+
+/**
+ * @def IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE
+ *
+ * @brief Request from the XScale client to the NPE to enable or disable
+ * portID extraction from VLAN-tagged frames for the specified port.
+ */
+#define IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE 0x0C
+
+/**
+ * @def IX_ETHNPE_STP_SETBLOCKINGSTATE
+ *
+ * @brief Request from the XScale client to the NPE to block or unblock
+ * forwarding for spanning tree BPDUs.
+ */
+#define IX_ETHNPE_STP_SETBLOCKINGSTATE 0x0D
+
+/**
+ * @def IX_ETHNPE_FW_SETFIREWALLMODE
+ *
+ * @brief Request from the XScale client to the NPE to configure firewall
+ * services modes of operation and/or download Ethernet Firewall Database from
+ * SDRAM to NPE.
+ */
+#define IX_ETHNPE_FW_SETFIREWALLMODE 0x0E
+
+/**
+ * @def IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID
+ *
+ * @brief Request from the XScale client to the NPE to set global frame control
+ * and duration/ID field for the 802.3 to 802.11 protocol header conversion
+ * service.
+ */
+#define IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID 0x0F
+
+/**
+ * @def IX_ETHNPE_PC_SETBBSID
+ *
+ * @brief Request from the XScale client to the NPE to set global BBSID field
+ * value for the 802.3 to 802.11 protocol header conversion service.
+ */
+#define IX_ETHNPE_PC_SETBBSID 0x10
+
+/**
+ * @def IX_ETHNPE_PC_SETAPMACTABLE
+ *
+ * @brief Request from the XScale client to the NPE to update a block/section/
+ * range of the AP MAC Address Table.
+ */
+#define IX_ETHNPE_PC_SETAPMACTABLE 0x11
+
+/**
+ * @def IX_ETHNPE_SETLOOPBACK_MODE
+ *
+ * @brief Turn on or off the NPE frame loopback.
+ */
+#define IX_ETHNPE_SETLOOPBACK_MODE (0x12)
+
+/*--------------------------------------------------------------------------
+ * APB Message IDs - NPE->XScale
+ *------------------------------------------------------------------------*/
+
+/**
+ * @def IX_ETHNPE_NPE_GETSTATUS_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_NPE_GETSTATUS message. NPE firmware version
+ * id is returned in the message.
+ */
+#define IX_ETHNPE_NPE_GETSTATUS_ACK 0x00
+
+/**
+ * @def IX_ETHNPE_EDB_SETPORTADDRESS_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_EDB_SETPORTADDRESS message.
+ */
+#define IX_ETHNPE_EDB_SETPORTADDRESS_ACK 0x01
+
+/**
+ * @def IX_ETHNPE_EDB_GETMACADDRESSDATABASE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_EDB_GETMACADDRESSDATABASE message
+ */
+#define IX_ETHNPE_EDB_GETMACADDRESSDATABASE_ACK 0x02
+
+/**
+ * @def IX_ETHNPE_EDB_SETMACADDRESSSDATABASE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_EDB_SETMACADDRESSSDATABASE message.
+ */
+#define IX_ETHNPE_EDB_SETMACADDRESSSDATABASE_ACK 0x03
+
+/**
+ * @def IX_ETHNPE_GETSTATS_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_GETSTATS message.
+ */
+#define IX_ETHNPE_GETSTATS_ACK 0x04
+
+/**
+ * @def IX_ETHNPE_RESETSTATS_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_RESETSTATS message.
+ */
+#define IX_ETHNPE_RESETSTATS_ACK 0x05
+
+/**
+ * @def IX_ETHNPE_SETMAXFRAMELENGTHS_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_SETMAXFRAMELENGTHS message.
+ */
+#define IX_ETHNPE_SETMAXFRAMELENGTHS_ACK 0x06
+
+/**
+ * @def IX_ETHNPE_VLAN_SETRXTAGMODE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_VLAN_SETRXTAGMODE message.
+ */
+#define IX_ETHNPE_VLAN_SETRXTAGMODE_ACK 0x07
+
+/**
+ * @def IX_ETHNPE_VLAN_SETDEFAULTRXVID_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_VLAN_SETDEFAULTRXVID message.
+ */
+#define IX_ETHNPE_VLAN_SETDEFAULTRXVID_ACK 0x08
+
+/**
+ * @def IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY message.
+ */
+#define IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY_ACK 0x09
+
+/**
+ * @def IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE message.
+ */
+#define IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE_ACK 0x0A
+
+/**
+ * @def IX_ETHNPE_VLAN_SETRXQOSENTRY_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_VLAN_SETRXQOSENTRY message.
+ */
+#define IX_ETHNPE_VLAN_SETRXQOSENTRY_ACK 0x0B
+
+/**
+ * @def IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE message.
+ */
+#define IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE_ACK 0x0C
+
+/**
+ * @def IX_ETHNPE_STP_SETBLOCKINGSTATE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_STP_SETBLOCKINGSTATE message.
+ */
+#define IX_ETHNPE_STP_SETBLOCKINGSTATE_ACK 0x0D
+
+/**
+ * @def IX_ETHNPE_FW_SETFIREWALLMODE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_FW_SETFIREWALLMODE message.
+ */
+#define IX_ETHNPE_FW_SETFIREWALLMODE_ACK 0x0E
+
+/**
+ * @def IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID message.
+ */
+#define IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID_ACK 0x0F
+
+/**
+ * @def IX_ETHNPE_PC_SETBBSID_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_PC_SETBBSID message.
+ */
+#define IX_ETHNPE_PC_SETBBSID_ACK 0x10
+
+/**
+ * @def IX_ETHNPE_PC_SETAPMACTABLE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_PC_SETAPMACTABLE message.
+ */
+#define IX_ETHNPE_PC_SETAPMACTABLE_ACK 0x11
+
+/**
+ * @def IX_ETHNPE_SETLOOPBACK_MODE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_SETLOOPBACK_MODE message.
+ */
+#define IX_ETHNPE_SETLOOPBACK_MODE_ACK (0x12)
+
+/*--------------------------------------------------------------------------
+ * Queue Manager Queue entry bit field boundary definitions
+ *------------------------------------------------------------------------*/
+
+/**
+ * @def MASK(hi,lo)
+ *
+ * @brief Macro for mask
+ */
+#define MASK(hi,lo) (((1 << (1 + ((hi) - (lo)))) - 1) << (lo))
+
+/**
+ * @def BITS(x,hi,lo)
+ *
+ * @brief Macro for bits
+ */
+#define BITS(x,hi,lo) (((x) & MASK(hi,lo)) >> (lo))
+
+/**
+ * @def IX_ETHNPE_QM_Q_RXENET_LENGTH_MASK
+ *
+ * @brief QMgr Queue LENGTH field mask
+ */
+#define IX_ETHNPE_QM_Q_RXENET_LENGTH_MASK 0x3fff
+
+/**
+ * @def IX_ETHNPE_QM_Q_FIELD_FLAG_R
+ *
+ * @brief QMgr Queue FLAG field right boundary
+ */
+#define IX_ETHNPE_QM_Q_FIELD_FLAG_R 20
+
+/**
+ * @def IX_ETHNPE_QM_Q_FIELD_FLAG_MASK
+ *
+ * @brief QMgr Queue FLAG field mask
+ *
+ * Multicast bit : BIT(4)
+ * Broadcast bit : BIT(5)
+ * IP bit : BIT(6) (linux only)
+ *
+ */
+#ifdef __vxworks
+#define IX_ETHNPE_QM_Q_FIELD_FLAG_MASK 0x30
+#else
+#define IX_ETHNPE_QM_Q_FIELD_FLAG_MASK 0x70
+#endif
+
+
+/**
+ * @def IX_ETHNPE_QM_Q_FIELD_NPEID_L
+ *
+ * @brief QMgr Queue NPE ID field left boundary
+ */
+#define IX_ETHNPE_QM_Q_FIELD_NPEID_L 1
+
+/**
+ * @def IX_ETHNPE_QM_Q_FIELD_NPEID_R
+ *
+ * @brief QMgr Queue NPE ID field right boundary
+ */
+#define IX_ETHNPE_QM_Q_FIELD_NPEID_R 0
+
+/**
+ * @def IX_ETHNPE_QM_Q_FIELD_PRIOR_L
+ *
+ * @brief QMgr Queue Priority field left boundary
+ */
+#define IX_ETHNPE_QM_Q_FIELD_PRIOR_L 2
+
+/**
+ * @def IX_ETHNPE_QM_Q_FIELD_PRIOR_R
+ *
+ * @brief QMgr Queue Priority field right boundary
+ */
+#define IX_ETHNPE_QM_Q_FIELD_PRIOR_R 0
+
+/**
+ * @def IX_ETHNPE_QM_Q_FIELD_ADDR_L
+ *
+ * @brief QMgr Queue Address field left boundary
+ */
+#define IX_ETHNPE_QM_Q_FIELD_ADDR_L 31
+
+/**
+ * @def IX_ETHNPE_QM_Q_FIELD_ADDR_R
+ *
+ * @brief QMgr Queue Address field right boundary
+ */
+#define IX_ETHNPE_QM_Q_FIELD_ADDR_R 5
+
+/*--------------------------------------------------------------------------
+ * Queue Manager Queue entry bit field masks
+ *------------------------------------------------------------------------*/
+
+/**
+ * @def IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK
+ *
+ * @brief Macro to mask the Address field of the FreeEnet Queue Manager Entry
+ */
+#define IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK \
+ MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \
+ IX_ETHNPE_QM_Q_FIELD_ADDR_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_RXENET_NPEID_MASK
+ *
+ * @brief Macro to mask the NPE ID field of the RxEnet Queue Manager Entry
+ */
+#define IX_ETHNPE_QM_Q_RXENET_NPEID_MASK \
+ MASK (IX_ETHNPE_QM_Q_FIELD_NPEID_L, \
+ IX_ETHNPE_QM_Q_FIELD_NPEID_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_RXENET_ADDR_MASK
+ *
+ * @brief Macro to mask the Mbuf Address field of the RxEnet Queue Manager Entry
+ */
+#define IX_ETHNPE_QM_Q_RXENET_ADDR_MASK \
+ MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \
+ IX_ETHNPE_QM_Q_FIELD_ADDR_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_TXENET_PRIOR_MASK
+ *
+ * @brief Macro to mask the Priority field of the TxEnet Queue Manager Entry
+ */
+#define IX_ETHNPE_QM_Q_TXENET_PRIOR_MASK \
+ MASK (IX_ETHNPE_QM_Q_FIELD_PRIOR_L, \
+ IX_ETHNPE_QM_Q_FIELD_PRIOR_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_TXENET_ADDR_MASK
+ *
+ * @brief Macro to mask the Mbuf Address field of the TxEnet Queue Manager Entry
+ */
+#define IX_ETHNPE_QM_Q_TXENET_ADDR_MASK \
+ MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \
+ IX_ETHNPE_QM_Q_FIELD_ADDR_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK
+ *
+ * @brief Macro to mask the NPE ID field of the TxEnetDone Queue Manager Entry
+ */
+#define IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK \
+ MASK (IX_ETHNPE_QM_Q_FIELD_NPEID_L, \
+ IX_ETHNPE_QM_Q_FIELD_NPEID_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK
+ *
+ * @brief Macro to mask the Mbuf Address field of the TxEnetDone Queue Manager
+ * Entry
+ */
+#define IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK \
+ MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \
+ IX_ETHNPE_QM_Q_FIELD_ADDR_R)
+
+/*--------------------------------------------------------------------------
+ * Queue Manager Queue entry bit field value extraction macros
+ *------------------------------------------------------------------------*/
+
+/**
+ * @def IX_ETHNPE_QM_Q_FREEENET_ADDR_VAL(x)
+ *
+ * @brief Extraction macro for Address field of FreeNet Queue Manager Entry
+ *
+ * Pointer to an mbuf buffer descriptor
+ */
+#define IX_ETHNPE_QM_Q_FREEENET_ADDR_VAL(x) \
+ ((x) & IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK)
+
+/**
+ * @def IX_ETHNPE_QM_Q_RXENET_NPEID_VAL(x)
+ *
+ * @brief Extraction macro for NPE ID field of RxEnet Queue Manager Entry
+ *
+ * Set to 0 for entries originating from the Eth0 NPE;
+ * Set to 1 for entries originating from the Eth1 NPE.
+ */
+#define IX_ETHNPE_QM_Q_RXENET_NPEID_VAL(x) \
+ BITS (x, IX_ETHNPE_QM_Q_FIELD_NPEID_L, \
+ IX_ETHNPE_QM_Q_FIELD_NPEID_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_RXENET_PORTID_VAL(x)
+ *
+ * @brief Extraction macro for Port ID field of RxEnet Queue Manager Entry
+ *
+ * 0-5: Assignable (by the XScale client) to any of the physical ports.
+ * 6: It is reserved
+ * 7: Indication that the NPE did not find the associated frame's destination MAC address within
+ * its internal filtering database.
+ */
+#define IX_ETHNPE_QM_Q_RXENET_PORTID_VAL(x) \
+ BITS (x, IX_ETHNPE_QM_Q_FIELD_PORTID_L, \
+ IX_ETHNPE_QM_Q_Field_PortID_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_RXENET_ADDR_VAL(x)
+ *
+ * @brief Extraction macro for Address field of RxEnet Queue Manager Entry
+ *
+ * Pointer to an mbuf buffer descriptor
+ */
+#define IX_ETHNPE_QM_Q_RXENET_ADDR_VAL(x) \
+ ((x) & IX_ETHNPE_QM_Q_RXENET_ADDR_MASK)
+
+/**
+ * @def IX_ETHNPE_QM_Q_TXENET_PRIOR_VAL(x)
+ *
+ * @brief Extraction macro for Priority field of TxEnet Queue Manager Entry
+ *
+ * Priority of the packet (as described in IEEE 802.1D). This field is
+ * cleared upon return from the Ethernet NPE to the TxEnetDone queue.
+ */
+#define IX_ETHNPE_QM_Q_TXENET_PRIOR_VAL(x) \
+ BITS (x, IX_ETHNPE_QM_Q_FIELD_PRIOR_L, \
+ IX_ETHNPE_QM_Q_FIELD_PRIOR_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_TXENET_ADDR_VAL(x)
+ *
+ * @brief Extraction macro for Address field of Queue Manager TxEnet Queue
+ * Manager Entry
+ *
+ * Pointer to an mbuf buffer descriptor
+ */
+#define IX_ETHNPE_QM_Q_TXENET_ADDR_VAL(x) \
+ ((x) & IX_ETHNPE_QM_Q_TXENET_ADDR_MASK)
+
+/**
+ * @def IX_ETHNPE_QM_Q_TXENETDONE_NPEID_VAL(x)
+ *
+ * @brief Extraction macro for NPE ID field of TxEnetDone Queue Manager Entry
+ *
+ * Set to 0 for entries originating from the Eth0 NPE; set to 1 for en-tries
+ * originating from the Eth1 NPE.
+ */
+#define IX_ETHNPE_QM_Q_TXENETDONE_NPEID_VAL(x) \
+ BITS (x, IX_ETHNPE_QM_Q_FIELD_NPEID_L, \
+ IX_ETHNPE_QM_Q_FIELD_NPEID_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_TXENETDONE_ADDR_VAL(x)
+ *
+ * @brief Extraction macro for Address field of TxEnetDone Queue Manager Entry
+ *
+ * Pointer to an mbuf buffer descriptor
+ */
+#define IX_ETHNPE_QM_Q_TXENETDONE_ADDR_VAL(x) \
+ ((x) & IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK)
+
+
+/*--------------------------------------------------------------------------
+ * NPE limits
+ *------------------------------------------------------------------------*/
+
+/**
+ * @def IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN
+ *
+ * @brief Macro to check the minimum length of a rx free buffer
+ */
+#define IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN (64)
+
+/**
+ * @def IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK
+ *
+ * @brief Mask to apply to the mbuf length before submitting it to the NPE
+ * (the NPE handles only rx free mbufs which are multiple of 64)
+ *
+ * @sa IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK
+ */
+#define IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK (~63)
+
+/**
+ * @def IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_UP(size)
+ *
+ * @brief Round up to get the size necessary to receive without chaining
+ * the frames which are (size) bytes (the NPE operates by multiple of 64)
+ * e.g. To receive 1514 bytes frames, the size of the buffers in replenish
+ * has to be at least (1514+63)&(~63) = 1536 bytes.
+ *
+ */
+#define IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_UP(size) (((size) + 63) & ~63)
+
+/**
+ * @def IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_DOWN(size)
+ *
+ * @brief Round down to apply to the mbuf length before submitting
+ * it to the NPE. (the NPE operates by multiple of 64)
+ *
+ */
+#define IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_DOWN(size) ((size) & ~63)
+
+/**
+ * @def IX_ETHNPE_ACC_FRAME_LENGTH_MAX
+ *
+ * @brief maximum mbuf length supported by the NPE
+ *
+ * @sa IX_ETHNPE_ACC_FRAME_LENGTH_MAX
+ */
+#define IX_ETHNPE_ACC_FRAME_LENGTH_MAX (16320)
+
+/**
+ * @def IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT
+ *
+ * @brief default mbuf length supported by the NPE
+ *
+ * @sa IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT
+ */
+#define IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT (1522)
+
+/**
+ * @def IX_ETHNPE_ACC_LENGTH_OFFSET
+ *
+ * @brief Offset of the cluster length field in the word shared with the NPEs
+ */
+#define IX_ETHNPE_ACC_LENGTH_OFFSET 16
+
+/**
+ * @def IX_ETHNPE_ACC_PKTLENGTH_MASK
+ *
+ * @brief Mask of the cluster length field in the word shared with the NPEs
+ */
+#define IX_ETHNPE_ACC_PKTLENGTH_MASK 0x3fff
+
+
+/**
+ *@}
+ */
+
+#endif /* __doxygen_HIDE */
diff --git a/cpu/ixp/npe/include/IxFeatureCtrl.h b/cpu/ixp/npe/include/IxFeatureCtrl.h
new file mode 100644
index 0000000..dabc38e
--- /dev/null
+++ b/cpu/ixp/npe/include/IxFeatureCtrl.h
@@ -0,0 +1,742 @@
+/**
+ * @file IxFeatureCtrl.h
+ *
+ * @date 30-Jan-2003
+
+ * @brief This file contains the public API of the IXP400 Feature Control
+ * component.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+/* ------------------------------------------------------
+ Doxygen group definitions
+ ------------------------------------------------------ */
+/**
+ * @defgroup IxFeatureCtrlAPI IXP400 Feature Control (IxFeatureCtrl) API
+ *
+ * @brief The Public API for the IXP400 Feature Control.
+ *
+ * @{
+ */
+
+#ifndef IXFEATURECTRL_H
+#define IXFEATURECTRL_H
+
+/*
+ * User defined include files
+ */
+#include "IxOsal.h"
+
+/*
+ * #defines and macros
+ */
+
+/*************************************************************
+ * The following are IxFeatureCtrlComponentCheck return values.
+ ************************************************************/
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURE_CTRL_COMPONENT_DISABLED
+ *
+ * @brief Hardware Component is disabled/unavailable.
+ * Return status by ixFeatureCtrlComponentCheck()
+ */
+#define IX_FEATURE_CTRL_COMPONENT_DISABLED 0
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURE_CTRL_COMPONENT_ENABLED
+ *
+ * @brief Hardware Component is available.
+ * Return status by ixFeatureCtrlComponentCheck()
+ */
+#define IX_FEATURE_CTRL_COMPONENT_ENABLED 1
+
+/***********************************************************************************
+ * Product ID in XScale CP15 - Register 0
+ * - It contains information on the maximum XScale Core Frequency and
+ * Silicon Stepping.
+ * - XScale Core Frequency Id indicates only the maximum XScale frequency
+ * achievable and not the running XScale frequency (maybe stepped down).
+ * - The register is read by using ixFeatureCtrlProductIdRead.
+ * - Usage example:
+ * productId = ixFeatureCtrlProductIdRead();
+ * if( (productId & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) ==
+ * IX_FEATURE_CTRL_SILICON_TYPE_A0 )
+ * if( (productId & IX_FEATURE_CTRL_XSCALE_FREQ_MASK) ==
+ * IX_FEATURE_CTRL_XSCALE_FREQ_533 )
+ *
+ * 31 28 27 24 23 20 19 16 15 12 11 9 8 4 3 0
+ * --------------------------------------------------------------------------------
+ * | 0x6 | 0x9 | 0x0 | 0x5 | 0x4 | Device ID | XScale Core Freq Id | Si Stepping Id |
+ * --------------------------------------------------------------------------------
+ *
+ * Maximum Achievable XScale Core Frequency Id : 533MHz - 0x1C
+ * 400MHz - 0x1D
+ * 266MHz - 0x1F
+ *
+ * <b>THE CORE FREQUENCY ID IS NOT APPLICABLE TO IXP46X <\b>
+ *
+ * The above is applicable to IXP42X only. CP15 in IXP46X does not contain any
+ * Frequency ID.
+ *
+ * Si Stepping Id : A - 0x0
+ * B - 0x1
+ *
+ * XScale Core freq Id - Device ID [11:9] : IXP42X - 0x0
+ * IXP46X - 0x1
+ *************************************************************************************/
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURE_CTRL_SILICON_TYPE_A0
+ *
+ * @brief This is the value of A0 Silicon in product ID.
+ */
+#define IX_FEATURE_CTRL_SILICON_TYPE_A0 0
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURE_CTRL_SILICON_TYPE_B0
+ *
+ * @brief This is the value of B0 Silicon in product ID.
+ */
+#define IX_FEATURE_CTRL_SILICON_TYPE_B0 1
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURE_CTRL_SILICON_STEPPING_MASK
+ *
+ * @brief This is the mask of silicon stepping in product ID.
+ */
+#define IX_FEATURE_CTRL_SILICON_STEPPING_MASK 0xF
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURE_CTRL_DEVICE_TYPE_MASK
+ *
+ * @brief This is the mask of silicon stepping in product ID.
+ */
+#define IX_FEATURE_CTRL_DEVICE_TYPE_MASK (0x7)
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET
+ *
+ * @brief This is the mask of silicon stepping in product ID.
+ */
+#define IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET 9
+
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURE_CTRL_XSCALE_FREQ_533
+ *
+ * @brief This is the value of 533MHz XScale Core in product ID.
+ */
+#define IX_FEATURE_CTRL_XSCALE_FREQ_533 ((0x1C)<<4)
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURE_CTRL_XSCALE_FREQ_400
+ *
+ * @brief This is the value of 400MHz XScale Core in product ID.
+ */
+#define IX_FEATURE_CTRL_XSCALE_FREQ_400 ((0x1D)<<4)
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURE_CTRL_XSCALE_FREQ_266
+ *
+ * @brief This is the value of 266MHz XScale Core in product ID.
+ */
+#define IX_FEATURE_CTRL_XSCALE_FREQ_266 ((0x1F)<<4)
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURE_CTRL_XSCALE_FREQ_MASK
+ *
+ * @brief This is the mask of XScale Core in product ID.
+ */
+#define IX_FEATURE_CTRL_XSCALE_FREQ_MASK ((0xFF)<<4)
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURECTRL_REG_UTOPIA_32PHY
+ *
+ * @brief Maximum UTOPIA PHY available is 32.
+ *
+ */
+#define IX_FEATURECTRL_REG_UTOPIA_32PHY 0x0
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURECTRL_REG_UTOPIA_16PHY
+ *
+ * @brief Maximum UTOPIA PHY available is 16.
+ *
+ */
+#define IX_FEATURECTRL_REG_UTOPIA_16PHY 0x1
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURECTRL_REG_UTOPIA_8PHY
+ *
+ * @brief Maximum UTOPIA PHY available to is 8.
+ *
+ */
+#define IX_FEATURECTRL_REG_UTOPIA_8PHY 0x2
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURECTRL_REG_UTOPIA_4PHY
+ *
+ * @brief Maximum UTOPIA PHY available to is 4.
+ *
+ */
+#define IX_FEATURECTRL_REG_UTOPIA_4PHY 0x3
+
+#ifdef __ixp46X
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURECTRL_REG_XSCALE_533FREQ
+ *
+ * @brief Maximum frequency available to IXP46x is 533 MHz.
+ *
+ */
+#define IX_FEATURECTRL_REG_XSCALE_533FREQ 0x0
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURECTRL_REG_XSCALE_667FREQ
+ *
+ * @brief Maximum frequency available to IXP46x is 667 MHz.
+ *
+ */
+#define IX_FEATURECTRL_REG_XSCALE_667FREQ 0x1
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURECTRL_REG_XSCALE_400FREQ
+ *
+ * @brief Maximum frequency available to IXP46x is 400 MHz.
+ *
+ */
+#define IX_FEATURECTRL_REG_XSCALE_400FREQ 0x2
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURECTRL_REG_XSCALE_266FREQ
+ *
+ * @brief Maximum frequency available to IXP46x is 266 MHz.
+ *
+ */
+#define IX_FEATURECTRL_REG_XSCALE_266FREQ 0x3
+
+#endif /* __ixp46X */
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE
+ *
+ * @brief Component selected is not available for device
+ *
+ */
+#define IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE 0x0000
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE
+ *
+ * @brief Component selected is not available for device
+ *
+ */
+#define IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE 0xffff
+
+/**
+ * @defgroup IxFeatureCtrlSwConfig Software Configuration for Access Component
+ *
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @brief This section describes software configuration in access component. The
+ * configuration can be changed at run-time. ixFeatureCtrlSwConfigurationCheck( )
+ * will be used across applicable access component to check the configuration.
+ * ixFeatureCtrlSwConfigurationWrite( ) is used to write the software configuration.
+ *
+ * @note <b>All software configurations are default to be enabled.</b>
+ *
+ * @{
+ */
+/**
+ * @ingroup IxFeatureCtrlSwConfig
+ *
+ * @def IX_FEATURE_CTRL_SWCONFIG_DISABLED
+ *
+ * @brief Software configuration is disabled.
+ *
+ */
+#define IX_FEATURE_CTRL_SWCONFIG_DISABLED 0
+
+/**
+ * @ingroup IxFeatureCtrlSwConfig
+ *
+ * @def IX_FEATURE_CTRL_SWCONFIG_ENABLED
+ *
+ * @brief Software configuration is enabled.
+ *
+ */
+#define IX_FEATURE_CTRL_SWCONFIG_ENABLED 1
+
+/**
+ * Section for enums
+ **/
+
+/**
+ * @ingroup IxFeatureCtrlBuildDevice
+ *
+ * @enum IxFeatureCtrlBuildDevice
+ *
+ * @brief Indicates software build type.
+ *
+ * Default build type is IXP42X
+ *
+ */
+typedef enum
+{
+ IX_FEATURE_CTRL_SW_BUILD_IXP42X = 0, /**<Build type is IXP42X */
+ IX_FEATURE_CTRL_SW_BUILD_IXP46X /**<Build type is IXP46X */
+} IxFeatureCtrlBuildDevice;
+
+/**
+ * @ingroup IxFeatureCtrlSwConfig
+ *
+ * @enum IxFeatureCtrlSwConfig
+ *
+ * @brief Enumeration for software configuration in access components.
+ *
+ * Entry for new run-time software configuration should be added here.
+ */
+typedef enum
+{
+ IX_FEATURECTRL_ETH_LEARNING = 0, /**< EthDB Learning Feature */
+ IX_FEATURECTRL_ORIGB0_DISPATCHER, /**< IXP42X B0 and IXP46X dispatcher without
+ livelock prevention functionality Feature */
+ IX_FEATURECTRL_SWCONFIG_MAX /**< Maximum boudary for IxFeatureCtrlSwConfig */
+} IxFeatureCtrlSwConfig;
+
+
+/************************************************************************
+ * IXP400 Feature Control Register
+ * - It contains the information (available/unavailable) of IXP425&IXP46X
+ * hardware components in their corresponding bit location.
+ * - Bit value of 0 means the hardware component is available
+ * or not software disabled. Hardware component that is available
+ * can be software disabled.
+ * - Bit value of 1 means the hardware is unavailable or software
+ * disabled.Hardware component that is unavailable cannot be software
+ * enabled.
+ * - Use ixFeatureCtrlHwCapabilityRead() to read the hardware component's
+ * availability.
+ * - Use ixFeatureCtrlRead() to get the current IXP425/IXP46X feature control
+ * register value.
+ *
+ * Bit Field Description (Hardware Component Availability)
+ * --- ---------------------------------------------------
+ * 0 RComp Circuitry
+ * 1 USB Controller
+ * 2 Hashing Coprocessor
+ * 3 AES Coprocessor
+ * 4 DES Coprocessor
+ * 5 HDLC Coprocessor
+ * 6 AAL Coprocessor - Always available in IXP46X
+ * 7 HSS Coprocesspr
+ * 8 Utopia Coprocessor
+ * 9 Ethernet 0 Coprocessor
+ * 10 Ethernet 1 Coprocessor
+ * 11 NPE A
+ * 12 NPE B
+ * 13 NPE C
+ * 14 PCI Controller
+ * 15 ECC/TimeSync Coprocessor - Only applicable to IXP46X
+ * 16-17 Utopia PHY Limit Status : 0x0 - 32 PHY
+ * 0x1 - 16 PHY
+ * 0x2 - 8 PHY
+ * 0x3 - 4 PHY
+ *
+ * Portions below are only applicable to IXP46X
+ * 18 USB Host Coprocessor
+ * 19 NPE A Ethernet - 0 for Enable if Utopia = 1
+ * 20 NPE B Ethernet coprocessor 1-3.
+ * 21 RSA Crypto Block coprocessor.
+ * 22-23 Processor frequency : 0x0 - 533 MHz
+ * 0x1 - 667 MHz
+ * 0x2 - 400 MHz
+ * 0x3 - 266 MHz
+ * 24-31 Reserved
+ *
+ ************************************************************************/
+/*Section generic to both IXP42X and IXP46X*/
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @enum IxFeatureCtrlComponentType
+ *
+ * @brief Enumeration for components availavble
+ *
+ */
+typedef enum
+{
+ IX_FEATURECTRL_RCOMP = 0, /**<bit location for RComp Circuitry*/
+ IX_FEATURECTRL_USB, /**<bit location for USB Controller*/
+ IX_FEATURECTRL_HASH, /**<bit location for Hashing Coprocessor*/
+ IX_FEATURECTRL_AES, /**<bit location for AES Coprocessor*/
+ IX_FEATURECTRL_DES, /**<bit location for DES Coprocessor*/
+ IX_FEATURECTRL_HDLC, /**<bit location for HDLC Coprocessor*/
+ IX_FEATURECTRL_AAL, /**<bit location for AAL Coprocessor*/
+ IX_FEATURECTRL_HSS, /**<bit location for HSS Coprocessor*/
+ IX_FEATURECTRL_UTOPIA, /**<bit location for UTOPIA Coprocessor*/
+ IX_FEATURECTRL_ETH0, /**<bit location for Ethernet 0 Coprocessor*/
+ IX_FEATURECTRL_ETH1, /**<bit location for Ethernet 1 Coprocessor*/
+ IX_FEATURECTRL_NPEA, /**<bit location for NPE A*/
+ IX_FEATURECTRL_NPEB, /**<bit location for NPE B*/
+ IX_FEATURECTRL_NPEC, /**<bit location for NPE C*/
+ IX_FEATURECTRL_PCI, /**<bit location for PCI Controller*/
+ IX_FEATURECTRL_ECC_TIMESYNC, /**<bit location for TimeSync Coprocessor*/
+ IX_FEATURECTRL_UTOPIA_PHY_LIMIT, /**<bit location for Utopia PHY Limit Status*/
+ IX_FEATURECTRL_UTOPIA_PHY_LIMIT_BIT2, /**<2nd bit of PHY limit status*/
+ IX_FEATURECTRL_USB_HOST_CONTROLLER, /**<bit location for USB host controller*/
+ IX_FEATURECTRL_NPEA_ETH, /**<bit location for NPE-A Ethernet Disable*/
+ IX_FEATURECTRL_NPEB_ETH, /**<bit location for NPE-B Ethernet 1-3 Coprocessors Disable*/
+ IX_FEATURECTRL_RSA, /**<bit location for RSA Crypto block Coprocessors Disable*/
+ IX_FEATURECTRL_XSCALE_MAX_FREQ, /**<bit location for XScale max frequency*/
+ IX_FEATURECTRL_XSCALE_MAX_FREQ_BIT2, /**<2nd xscale max freq bit NOT TO BE USED */
+ IX_FEATURECTRL_MAX_COMPONENTS
+} IxFeatureCtrlComponentType;
+
+/**
+ * @ingroup IxFeatureCtrlDeviceId
+ *
+ * @enum IxFeatureCtrlDeviceId
+ *
+ * @brief Enumeration for device type.
+ *
+ * @warning This enum is closely related to the npe image. Its format should comply
+ * with formats used in the npe image ImageID. This is indicated by the
+ * first nibble of the image ID. This should also be in sync with the
+ * with what is defined in CP15. Current available formats are
+ * - IXP42X - 0000
+ * - IXP46X - 0001
+ *
+ */
+typedef enum
+{
+ IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X = 0, /**<Device type is IXP42X */
+ IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X, /**<Device type is IXP46X */
+ IX_FEATURE_CTRL_DEVICE_TYPE_MAX /**<Max devices */
+} IxFeatureCtrlDeviceId;
+
+
+/**
+ * @} addtogroup IxFeatureCtrlSwConfig
+ */
+
+/*
+ * Typedefs
+ */
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @typedef IxFeatureCtrlReg
+ *
+ * @brief Feature Control Register that contains hardware components'
+ * availability information.
+ */
+typedef UINT32 IxFeatureCtrlReg;
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @typedef IxFeatureCtrlProductId
+ *
+ * @brief Product ID of Silicon that contains Silicon Stepping and
+ * Maximum XScale Core Frequency information.
+ */
+typedef UINT32 IxFeatureCtrlProductId;
+
+/*
+ * Prototypes for interface functions
+ */
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @fn IxFeatureCtrlReg ixFeatureCtrlRead (void)
+ *
+ * @brief This function reads out the CURRENT value of Feature Control Register.
+ * The current value may not be the same as that of the hardware component
+ * availability.
+ *
+ * The bit location of each hardware component is defined above.
+ * A value of '1' in bit means the hardware component is not available. A value of '0'
+ * means the hardware component is available.
+ *
+ * @return
+ * - IxFeatureCtrlReg - the current value of IXP400 Feature Control Register
+ */
+PUBLIC IxFeatureCtrlReg
+ixFeatureCtrlRead (void);
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @fn IxFeatureDeviceId ixFeatureCtrlDeviceRead (void)
+ *
+ * @brief This function gets the type of device that the software is currently running
+ * on
+ *
+ * This function reads the feature Ctrl register specifically to obtain the device id.
+ * The definitions of the avilable IDs are as above.
+ *
+ * @return
+ * - IxFeatureCtrlDeviceId - the type of device currently running
+ */
+IxFeatureCtrlDeviceId
+ixFeatureCtrlDeviceRead (void);
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @fn IxFeatureCtrlBuildDevice ixFeatureCtrlSoftwareBuildGet (void)
+ *
+ * @brief This function refers to the value set by the compiler flag to determine
+ * the type of device the software is built for.
+ *
+ * The function reads the compiler flag to determine the device the software is
+ * built for. When the user executes build in the command line,
+ * a compile time flag (__ixp42X/__ixp46X is set. This API reads this
+ * flag and returns the software build type to the calling client.
+ *
+ * @return
+ * - IxFeatureCtrlBuildDevice - the type of device software is built for.
+ */
+IxFeatureCtrlBuildDevice
+ixFeatureCtrlSoftwareBuildGet (void);
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @fn IxFeatureCtrlReg ixFeatureCtrlHwCapabilityRead (void)
+ *
+ * @brief This function reads out the hardware capability of a silicon type as defined in
+ * feature control register.This value is different from that returned by
+ * ixFeatureCtrlRead() because this function returns the actual hardware component
+ * availability.
+ *
+ * The bit location of each hardware component is defined above.
+ * A value of '1' in bit means the hardware component is not available. A value of '0'
+ * means the hardware component is available.
+ *
+ * @return
+ * - IxFeatureCtrlReg - the hardware capability of IXP400.
+ *
+ * @warning
+ * - This function must not be called when IXP400 is running as the result
+ * is undefined.
+ */
+PUBLIC IxFeatureCtrlReg
+ixFeatureCtrlHwCapabilityRead (void);
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @fn void ixFeatureCtrlWrite (IxFeatureCtrlReg expUnitReg)
+ *
+ * @brief This function write the value stored in IxFeatureCtrlReg expUnitReg
+ * to the Feature Control Register.
+ *
+ * The bit location of each hardware component is defined above.
+ * The write is only effective on available hardware components. Writing '1' in a
+ * bit will software disable the respective hardware component. A '0' will mean that
+ * the hardware component will remain to be operable.
+ *
+ * @param expUnitReg @ref IxFeatureCtrlReg [in] - The value to be written to feature control
+ * register.
+ *
+ * @return none
+ *
+ */
+PUBLIC void
+ixFeatureCtrlWrite (IxFeatureCtrlReg expUnitReg);
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @fn IX_STATUS ixFeatureCtrlComponentCheck (IxFeatureCtrlComponentType componentType)
+ *
+ * @brief This function will check the availability of hardware component specified
+ * as componentType value.
+ *
+ * Usage Example:<br>
+ * - if(IX_FEATURE_CTRL_COMPONENT_DISABLED !=
+ * ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0)) <br>
+ * - if(IX_FEATURE_CTRL_COMPONENT_ENABLED ==
+ * ixFeatureCtrlComponentCheck(IX_FEATURECTRL_PCI)) <br>
+ *
+ * This function is typically called during component initialization time.
+ *
+ * @param componentType @ref IxFeatureCtrlComponentType [in] - the type of a component as
+ * defined above as IX_FEATURECTRL_XXX (Exp: IX_FEATURECTRL_PCI, IX_FEATURECTRL_ETH0)
+
+ *
+ * @return
+ * - IX_FEATURE_CTRL_COMPONENT_ENABLED if component is available
+ * - IX_FEATURE_CTRL_COMPONENT_DISABLED if component is unavailable
+ */
+PUBLIC IX_STATUS
+ixFeatureCtrlComponentCheck (IxFeatureCtrlComponentType componentType);
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @fn IxFeatureCtrlProductId ixFeatureCtrlProductIdRead (void)
+ *
+ * @brief This function will return IXP400 product ID i.e. CP15,
+ * Register 0.
+ *
+ * @return
+ * - IxFeatureCtrlProductId - the value of product ID.
+ *
+ */
+PUBLIC IxFeatureCtrlProductId
+ixFeatureCtrlProductIdRead (void) ;
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @fn IX_STATUS ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType)
+ *
+ * @brief This function checks whether the specified software configuration is
+ * enabled or disabled.
+ *
+ * Usage Example:<br>
+ * - if(IX_FEATURE_CTRL_SWCONFIG_DISABLED !=
+ * ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING)) <br>
+ * - if(IX_FEATURE_CTRL_SWCONFIG_ENABLED ==
+ * ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING)) <br>
+ *
+ * This function is typically called during access component initialization time.
+ *
+ * @param swConfigType @ref IxFeatureCtrlSwConfig [in] - the type of a software configuration
+ * defined in IxFeatureCtrlSwConfig enumeration.
+ *
+ * @return
+ * - IX_FEATURE_CTRL_SWCONFIG_ENABLED if software configuration is enabled.
+ * - IX_FEATURE_CTRL_SWCONFIG_DISABLED if software configuration is disabled.
+ */
+PUBLIC IX_STATUS
+ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType);
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @fn void ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled)
+ *
+ * @brief This function enable/disable the specified software configuration.
+ *
+ * Usage Example:<br>
+ * - ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, TRUE) is used
+ * to enable Ethernet Learning Feature <br>
+ * - ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, FALSE) is used
+ * to disable Ethernet Learning Feature <br>
+ *
+ * @param swConfigType IxFeatureCtrlSwConfig [in] - the type of a software configuration
+ * defined in IxFeatureCtrlSwConfig enumeration.
+ * @param enabled BOOL [in] - To enable(TRUE) / disable (FALSE) the specified software
+ * configuration.
+ *
+ * @return none
+ *
+ */
+PUBLIC void
+ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled);
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @fn void ixFeatureCtrlIxp400SwVersionShow (void)
+ *
+ * @brief This function shows the current software release information for IXP400
+ *
+ * @return none
+ *
+ */
+PUBLIC void
+ixFeatureCtrlIxp400SwVersionShow (void);
+
+#endif /* IXFEATURECTRL_H */
+
+/**
+ * @} defgroup IxFeatureCtrlAPI
+ */
diff --git a/cpu/ixp/npe/include/IxHssAcc.h b/cpu/ixp/npe/include/IxHssAcc.h
new file mode 100644
index 0000000..07bb119
--- /dev/null
+++ b/cpu/ixp/npe/include/IxHssAcc.h
@@ -0,0 +1,1316 @@
+/**
+ * @file IxHssAcc.h
+ *
+ * @date 07-DEC-2001
+ *
+ * @brief This file contains the public API of the IXP400 HSS Access
+ * component
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/* ------------------------------------------------------
+ Doxygen group definitions
+ ------------------------------------------------------ */
+/**
+ * @defgroup IxHssAccAPI IXP400 HSS Access (IxHssAcc) API
+ *
+ * @brief The public API for the IXP400 HssAccess component
+ *
+ * IxHssAcc is the access layer to the HSS packetised and channelised
+ * services
+ *
+ * <b> Design Notes </b><br>
+ * <UL>
+ * <LI>When a packet-pipe is configured for 56Kbps RAW mode, byte alignment of
+ * the transmitted data is not preserved. All raw data that is transmitted
+ * will be received in proper order by the receiver, but the first bit of
+ * the packet may be seen at any offset within a byte; all subsequent bytes
+ * will have the same offset for the duration of the packet. The same offset
+ * also applies to all subsequent packets received on the packet-pipe too.
+ * (Similar results will occur for data received from remote end.) While
+ * this behavior will also occur for 56Kbps HDLC mode, the HDLC
+ * encoding/decoding will preserve the original byte alignment at the
+ * receiver end.
+ * </UL>
+ *
+ * <b> 56Kbps Packetised Service Bandwidth Limitation </b><br>
+ * <UL>
+ * <LI>IxHssAcc supports 56Kbps packetised service at a maximum aggregate rate
+ * for all HSS ports/HDLC channels of 12.288Mbps[1] in each direction, i.e.
+ * it supports 56Kbps packetised service on up to 8 T1 trunks. It does
+ * not support 56Kbps packetised service on 8 E1 trunks (i.e. 4 trunks per
+ * HSS port) unless those trunks are running 'fractional E1' with maximum
+ * aggregate rate of 12.288 Mbps in each direction.<br>
+ * [1] 12.288Mbps = 1.536Mbp * 8 T1
+ * </UL>
+ * @{ */
+
+#ifndef IXHSSACC_H
+#define IXHSSACC_H
+
+#include "IxOsal.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+/**
+ * @def IX_HSSACC_TSLOTS_PER_HSS_PORT
+ *
+ * @brief The max number of TDM timeslots supported per HSS port - 4E1's =
+ * 32x4 = 128
+ */
+#define IX_HSSACC_TSLOTS_PER_HSS_PORT 128
+
+/* -----------------------------------------------------------
+ The following are HssAccess return values returned through
+ service interfaces. The globally defined IX_SUCCESS (0) and
+ IX_FAIL (1) in IxOsalTypes.h are also used.
+ ----------------------------------------------------------- */
+/**
+ * @def IX_HSSACC_PARAM_ERR
+ *
+ * @brief HssAccess function return value for a parameter error
+ */
+#define IX_HSSACC_PARAM_ERR 2
+
+/**
+ * @def IX_HSSACC_RESOURCE_ERR
+ *
+ * @brief HssAccess function return value for a resource error
+ */
+#define IX_HSSACC_RESOURCE_ERR 3
+
+/**
+ * @def IX_HSSACC_PKT_DISCONNECTING
+ *
+ * @brief Indicates that a disconnect call is progressing and will
+ * disconnect soon
+ */
+#define IX_HSSACC_PKT_DISCONNECTING 4
+
+/**
+ * @def IX_HSSACC_Q_WRITE_OVERFLOW
+ *
+ * @brief Indicates that an attempt to Tx or to replenish an
+ * RxFree Q failed due to Q overflow.
+ */
+#define IX_HSSACC_Q_WRITE_OVERFLOW 5
+
+/* -------------------------------------------------------------------
+ The following errors are HSS/NPE errors returned on error retrieval
+ ------------------------------------------------------------------- */
+/**
+ * @def IX_HSSACC_NO_ERROR
+ *
+ * @brief HSS port no error present
+ */
+#define IX_HSSACC_NO_ERROR 0
+
+/**
+ * @def IX_HSSACC_TX_FRM_SYNC_ERR
+ *
+ * @brief HSS port TX Frame Sync error
+ */
+#define IX_HSSACC_TX_FRM_SYNC_ERR 1
+
+/**
+ * @def IX_HSSACC_TX_OVER_RUN_ERR
+ *
+ * @brief HSS port TX over-run error
+ */
+#define IX_HSSACC_TX_OVER_RUN_ERR 2
+
+/**
+ * @def IX_HSSACC_CHANNELISED_SW_TX_ERR
+ *
+ * @brief NPE software error in channelised TX
+ */
+#define IX_HSSACC_CHANNELISED_SW_TX_ERR 3
+
+/**
+ * @def IX_HSSACC_PACKETISED_SW_TX_ERR
+ *
+ * @brief NPE software error in packetised TX
+ */
+#define IX_HSSACC_PACKETISED_SW_TX_ERR 4
+
+/**
+ * @def IX_HSSACC_RX_FRM_SYNC_ERR
+ *
+ * @brief HSS port RX Frame Sync error
+ */
+#define IX_HSSACC_RX_FRM_SYNC_ERR 5
+
+/**
+ * @def IX_HSSACC_RX_OVER_RUN_ERR
+ *
+ * @brief HSS port RX over-run error
+ */
+#define IX_HSSACC_RX_OVER_RUN_ERR 6
+
+/**
+ * @def IX_HSSACC_CHANNELISED_SW_RX_ERR
+ *
+ * @brief NPE software error in channelised RX
+ */
+#define IX_HSSACC_CHANNELISED_SW_RX_ERR 7
+
+/**
+ * @def IX_HSSACC_PACKETISED_SW_RX_ERR
+ *
+ * @brief NPE software error in packetised TX
+ */
+#define IX_HSSACC_PACKETISED_SW_RX_ERR 8
+
+/* -----------------------------------
+ Packetised service specific defines
+ ----------------------------------- */
+
+/**
+ * @def IX_HSSACC_PKT_MIN_RX_MBUF_SIZE
+ *
+ * @brief Minimum size of the Rx mbuf in bytes which the client must supply
+ * to the component.
+ */
+#define IX_HSSACC_PKT_MIN_RX_MBUF_SIZE 64
+
+/* --------------------------------------------------------------------
+ Enumerated Types - these enumerated values may be used in setting up
+ the contents of hardware registers
+ -------------------------------------------------------------------- */
+/**
+ * @enum IxHssAccHssPort
+ * @brief The HSS port ID - There are two identical ports (0-1).
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_HSS_PORT_0, /**< HSS Port 0 */
+ IX_HSSACC_HSS_PORT_1, /**< HSS Port 1 */
+ IX_HSSACC_HSS_PORT_MAX /**< Delimiter for error checks */
+} IxHssAccHssPort;
+
+/**
+ * @enum IxHssAccHdlcPort
+ * @brief The HDLC port ID - There are four identical HDLC ports (0-3) per
+ * HSS port and they correspond to the 4 E1/T1 trunks.
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_HDLC_PORT_0, /**< HDLC Port 0 */
+ IX_HSSACC_HDLC_PORT_1, /**< HDLC Port 1 */
+ IX_HSSACC_HDLC_PORT_2, /**< HDLC Port 2 */
+ IX_HSSACC_HDLC_PORT_3, /**< HDLC Port 3 */
+ IX_HSSACC_HDLC_PORT_MAX /**< Delimiter for error checks */
+} IxHssAccHdlcPort;
+
+/**
+ * @enum IxHssAccTdmSlotUsage
+ * @brief The HSS TDM stream timeslot assignment types
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_TDMMAP_UNASSIGNED, /**< Unassigned */
+ IX_HSSACC_TDMMAP_HDLC, /**< HDLC - packetised */
+ IX_HSSACC_TDMMAP_VOICE56K, /**< Voice56K - channelised */
+ IX_HSSACC_TDMMAP_VOICE64K, /**< Voice64K - channelised */
+ IX_HSSACC_TDMMAP_MAX /**< Delimiter for error checks */
+} IxHssAccTdmSlotUsage;
+
+/**
+ * @enum IxHssAccFrmSyncType
+ * @brief The HSS frame sync pulse type
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_FRM_SYNC_ACTIVE_LOW, /**< Frame sync is sampled low */
+ IX_HSSACC_FRM_SYNC_ACTIVE_HIGH, /**< sampled high */
+ IX_HSSACC_FRM_SYNC_FALLINGEDGE, /**< sampled on a falling edge */
+ IX_HSSACC_FRM_SYNC_RISINGEDGE, /**< sampled on a rising edge */
+ IX_HSSACC_FRM_SYNC_TYPE_MAX /**< Delimiter for error checks */
+} IxHssAccFrmSyncType;
+
+/**
+ * @enum IxHssAccFrmSyncEnable
+ * @brief The IxHssAccFrmSyncEnable determines how the frame sync pulse is
+ * used
+ * */
+typedef enum
+{
+ IX_HSSACC_FRM_SYNC_INPUT, /**< Frame sync is sampled as an input */
+ IX_HSSACC_FRM_SYNC_INVALID_VALUE, /**< 1 is not used */
+ IX_HSSACC_FRM_SYNC_OUTPUT_FALLING, /**< Frame sync is an output generated
+ off a falling clock edge */
+ IX_HSSACC_FRM_SYNC_OUTPUT_RISING, /**< Frame sync is an output generated
+ off a rising clock edge */
+ IX_HSSACC_FRM_SYNC_ENABLE_MAX /**< Delimiter for error checks */
+} IxHssAccFrmSyncEnable;
+
+/**
+ * @enum IxHssAccClkEdge
+ * @brief IxHssAccClkEdge is used to determine the clk edge to use for
+ * framing and data
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_CLK_EDGE_FALLING, /**< Clock sampled off a falling edge */
+ IX_HSSACC_CLK_EDGE_RISING, /**< Clock sampled off a rising edge */
+ IX_HSSACC_CLK_EDGE_MAX /**< Delimiter for error checks */
+} IxHssAccClkEdge;
+
+/**
+ * @enum IxHssAccClkDir
+ * @brief The HSS clock direction
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_SYNC_CLK_DIR_INPUT, /**< Clock is an input */
+ IX_HSSACC_SYNC_CLK_DIR_OUTPUT, /**< Clock is an output */
+ IX_HSSACC_SYNC_CLK_DIR_MAX /**< Delimiter for error checks */
+} IxHssAccClkDir;
+
+/**
+ * @enum IxHssAccFrmPulseUsage
+ * @brief The HSS frame pulse usage
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_FRM_PULSE_ENABLED, /**< Generate/Receive frame pulses */
+ IX_HSSACC_FRM_PULSE_DISABLED, /**< Disregard frame pulses */
+ IX_HSSACC_FRM_PULSE_MAX /**< Delimiter for error checks */
+} IxHssAccFrmPulseUsage;
+
+/**
+ * @enum IxHssAccDataRate
+ * @brief The HSS Data rate in relation to the clock
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_CLK_RATE, /**< Data rate is at the configured clk speed */
+ IX_HSSACC_HALF_CLK_RATE, /**< Data rate is half the configured clk speed */
+ IX_HSSACC_DATA_RATE_MAX /**< Delimiter for error checks */
+} IxHssAccDataRate;
+
+/**
+ * @enum IxHssAccDataPolarity
+ * @brief The HSS data polarity type
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_DATA_POLARITY_SAME, /**< Don't invert data between NPE and
+ HSS FIFOs */
+ IX_HSSACC_DATA_POLARITY_INVERT, /**< Invert data between NPE and HSS
+ FIFOs */
+ IX_HSSACC_DATA_POLARITY_MAX /**< Delimiter for error checks */
+} IxHssAccDataPolarity;
+
+/**
+ * @enum IxHssAccBitEndian
+ * @brief HSS Data endianness
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_LSB_ENDIAN, /**< TX/RX Least Significant Bit first */
+ IX_HSSACC_MSB_ENDIAN, /**< TX/RX Most Significant Bit first */
+ IX_HSSACC_ENDIAN_MAX /**< Delimiter for the purposes of error checks */
+} IxHssAccBitEndian;
+
+
+/**
+ * @enum IxHssAccDrainMode
+ * @brief Tx pin open drain mode
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_TX_PINS_NORMAL, /**< Normal mode */
+ IX_HSSACC_TX_PINS_OPEN_DRAIN, /**< Open Drain mode */
+ IX_HSSACC_TX_PINS_MAX /**< Delimiter for error checks */
+} IxHssAccDrainMode;
+
+/**
+ * @enum IxHssAccSOFType
+ * @brief HSS start of frame types
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_SOF_FBIT, /**< Framing bit transmitted and expected on rx */
+ IX_HSSACC_SOF_DATA, /**< Framing bit not transmitted nor expected on rx */
+ IX_HSSACC_SOF_MAX /**< Delimiter for error checks */
+} IxHssAccSOFType;
+
+/**
+ * @enum IxHssAccDataEnable
+ * @brief IxHssAccDataEnable is used to determine whether or not to drive
+ * the data pins
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_DE_TRI_STATE, /**< TRI-State the data pins */
+ IX_HSSACC_DE_DATA, /**< Push data out the data pins */
+ IX_HSSACC_DE_MAX /**< Delimiter for error checks */
+} IxHssAccDataEnable;
+
+/**
+ * @enum IxHssAccTxSigType
+ * @brief IxHssAccTxSigType is used to determine how to drive the data pins
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_TXSIG_LOW, /**< Drive the data pins low */
+ IX_HSSACC_TXSIG_HIGH, /**< Drive the data pins high */
+ IX_HSSACC_TXSIG_HIGH_IMP, /**< Drive the data pins with high impedance */
+ IX_HSSACC_TXSIG_MAX /**< Delimiter for error checks */
+} IxHssAccTxSigType;
+
+/**
+ * @enum IxHssAccFbType
+ * @brief IxHssAccFbType determines how to drive the Fbit
+ *
+ * @warning This will only be used for T1 @ 1.544MHz
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_FB_FIFO, /**< Fbit is dictated in FIFO */
+ IX_HSSACC_FB_HIGH_IMP, /**< Fbit is high impedance */
+ IX_HSSACC_FB_MAX /**< Delimiter for error checks */
+} IxHssAccFbType;
+
+/**
+ * @enum IxHssAcc56kEndianness
+ * @brief 56k data endianness when using the 56k type
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_56KE_BIT_7_UNUSED, /**< High bit is unused */
+ IX_HSSACC_56KE_BIT_0_UNUSED, /**< Low bit is unused */
+ IX_HSSACC_56KE_MAX /**< Delimiter for error checks */
+} IxHssAcc56kEndianness;
+
+/**
+ * @enum IxHssAcc56kSel
+ * @brief 56k data transmission type when using the 56k type
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_56KS_32_8_DATA, /**< 32/8 bit data */
+ IX_HSSACC_56KS_56K_DATA, /**< 56K data */
+ IX_HSSACC_56KS_MAX /**< Delimiter for error checks */
+} IxHssAcc56kSel;
+
+
+/**
+ * @enum IxHssAccClkSpeed
+ * @brief IxHssAccClkSpeed represents the HSS clock speeds available
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_CLK_SPEED_512KHZ, /**< 512KHz */
+ IX_HSSACC_CLK_SPEED_1536KHZ, /**< 1.536MHz */
+ IX_HSSACC_CLK_SPEED_1544KHZ, /**< 1.544MHz */
+ IX_HSSACC_CLK_SPEED_2048KHZ, /**< 2.048MHz */
+ IX_HSSACC_CLK_SPEED_4096KHZ, /**< 4.096MHz */
+ IX_HSSACC_CLK_SPEED_8192KHZ, /**< 8.192MHz */
+ IX_HSSACC_CLK_SPEED_MAX /**< Delimiter for error checking */
+} IxHssAccClkSpeed;
+
+/**
+ * @enum IxHssAccPktStatus
+ * @brief Indicates the status of packets passed to the client
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_PKT_OK, /**< Error free.*/
+ IX_HSSACC_STOP_SHUTDOWN_ERROR, /**< Errored due to stop or shutdown
+ occurrance.*/
+ IX_HSSACC_HDLC_ALN_ERROR, /**< HDLC alignment error */
+ IX_HSSACC_HDLC_FCS_ERROR, /**< HDLC Frame Check Sum error.*/
+ IX_HSSACC_RXFREE_Q_EMPTY_ERROR, /**< RxFree Q became empty
+ while receiving this packet.*/
+ IX_HSSACC_HDLC_MAX_FRAME_SIZE_EXCEEDED, /**< HDLC frame size
+ received is greater than
+ max specified at connect.*/
+ IX_HSSACC_HDLC_ABORT_ERROR, /**< HDLC frame received is invalid due to an
+ abort sequence received.*/
+ IX_HSSACC_DISCONNECT_IN_PROGRESS /**< Packet returned
+ because a disconnect is in progress */
+} IxHssAccPktStatus;
+
+
+/**
+ * @enum IxHssAccPktCrcType
+ * @brief HDLC CRC type
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_PKT_16_BIT_CRC = 16, /**< 16 bit CRC is being used */
+ IX_HSSACC_PKT_32_BIT_CRC = 32 /**< 32 bit CRC is being used */
+} IxHssAccPktCrcType;
+
+/**
+ * @enum IxHssAccPktHdlcIdleType
+ * @brief HDLC idle transmission type
+ *
+ */
+typedef enum
+{
+ IX_HSSACC_HDLC_IDLE_ONES, /**< idle tx/rx will be a succession of ones */
+ IX_HSSACC_HDLC_IDLE_FLAGS /**< idle tx/rx will be repeated flags */
+} IxHssAccPktHdlcIdleType;
+
+/**
+ * @brief Structure containing HSS port configuration parameters
+ *
+ * Note: All of these are used for TX. Only some are specific to RX.
+ *
+ */
+typedef struct
+{
+ IxHssAccFrmSyncType frmSyncType; /**< frame sync pulse type (tx/rx) */
+ IxHssAccFrmSyncEnable frmSyncIO; /**< how the frame sync pulse is
+ used (tx/rx) */
+ IxHssAccClkEdge frmSyncClkEdge; /**< frame sync clock edge type
+ (tx/rx) */
+ IxHssAccClkEdge dataClkEdge; /**< data clock edge type (tx/rx) */
+ IxHssAccClkDir clkDirection; /**< clock direction (tx/rx) */
+ IxHssAccFrmPulseUsage frmPulseUsage; /**< whether to use the frame sync
+ pulse or not (tx/rx) */
+ IxHssAccDataRate dataRate; /**< data rate in relation to the
+ clock (tx/rx) */
+ IxHssAccDataPolarity dataPolarity; /**< data polarity type (tx/rx) */
+ IxHssAccBitEndian dataEndianness; /**< data endianness (tx/rx) */
+ IxHssAccDrainMode drainMode; /**< tx pin open drain mode (tx) */
+ IxHssAccSOFType fBitUsage; /**< start of frame types (tx/rx) */
+ IxHssAccDataEnable dataEnable; /**< whether or not to drive the data
+ pins (tx) */
+ IxHssAccTxSigType voice56kType; /**< how to drive the data pins for
+ voice56k type (tx) */
+ IxHssAccTxSigType unassignedType; /**< how to drive the data pins for
+ unassigned type (tx) */
+ IxHssAccFbType fBitType; /**< how to drive the Fbit (tx) */
+ IxHssAcc56kEndianness voice56kEndian;/**< 56k data endianness when using
+ the 56k type (tx) */
+ IxHssAcc56kSel voice56kSel; /**< 56k data transmission type when
+ using the 56k type (tx) */
+ unsigned frmOffset; /**< frame pulse offset in bits wrt
+ the first timeslot (0-1023) (tx/rx) */
+ unsigned maxFrmSize; /**< frame size in bits (1-1024)
+ (tx/rx) */
+} IxHssAccPortConfig;
+
+/**
+ * @brief Structure containing HSS configuration parameters
+ *
+ */
+typedef struct
+{
+ IxHssAccPortConfig txPortConfig; /**< HSS tx port configuration */
+ IxHssAccPortConfig rxPortConfig; /**< HSS rx port configuration */
+ unsigned numChannelised; /**< The number of channelised
+ timeslots (0-32) */
+ unsigned hssPktChannelCount; /**< The number of packetised
+ clients (0 - 4) */
+ UINT8 channelisedIdlePattern; /**< The byte to be transmitted on
+ channelised service when there
+ is no client data to tx */
+ BOOL loopback; /**< The HSS loopback state */
+ unsigned packetizedIdlePattern; /**< The data to be transmitted on
+ packetised service when there is
+ no client data to tx */
+ IxHssAccClkSpeed clkSpeed; /**< The HSS clock speed */
+} IxHssAccConfigParams;
+
+/**
+ * @brief This structure contains 56Kbps, HDLC-mode configuration parameters
+ *
+ */
+typedef struct
+{
+ BOOL hdlc56kMode; /**< 56kbps(TRUE)/64kbps(FALSE) HDLC */
+ IxHssAcc56kEndianness hdlc56kEndian; /**< 56kbps data endianness
+ - ignored if hdlc56kMode is FALSE*/
+ BOOL hdlc56kUnusedBitPolarity0; /**< The polarity '0'(TRUE)/'1'(FALSE) of the unused
+ bit while in 56kbps mode
+ - ignored if hdlc56kMode is FALSE*/
+} IxHssAccHdlcMode;
+
+/**
+ * @brief This structure contains information required by the NPE to
+ * configure the HDLC co-processor
+ *
+ */
+typedef struct
+{
+ IxHssAccPktHdlcIdleType hdlcIdleType; /**< What to transmit when a HDLC port is idle */
+ IxHssAccBitEndian dataEndian; /**< The HDLC data endianness */
+ IxHssAccPktCrcType crcType; /**< The CRC type to be used for this HDLC port */
+} IxHssAccPktHdlcFraming;
+
+/**
+ * @typedef UINT32 IxHssAccPktUserId
+ *
+ * @brief The client supplied value which will be supplied as a parameter
+ * with a given callback.
+ *
+ * This value will be passed into the ixHssAccPktPortConnect function once each
+ * with given callbacks. This value will then be passed back to the client
+ * as one of the parameters to each of these callbacks,
+ * when these callbacks are called.
+ */
+typedef UINT32 IxHssAccPktUserId;
+
+
+/**
+ * @typedef IxHssAccLastErrorCallback
+ * @brief Prototype of the clients function to accept notification of the
+ * last error
+ *
+ * This function is registered through the config. The client will initiate
+ * the last error retrieval. The HssAccess component will send a message to
+ * the NPE through the NPE Message Handler. When a response to the read is
+ * received, the NPE Message Handler will callback the HssAccess component
+ * which will execute this function in the same IxNpeMh context. The client
+ * will be passed the last error and the related service port (packetised
+ * 0-3, channelised 0)
+ *
+ * @param lastHssError unsigned [in] - The last Hss error registered that
+ * has been registered.
+ * @param servicePort unsigned [in] - This is the service port number.
+ * (packetised 0-3, channelised 0)
+ *
+ * @return void
+ */
+typedef void (*IxHssAccLastErrorCallback) (unsigned lastHssError,
+ unsigned servicePort);
+
+/**
+ * @typedef IxHssAccPktRxCallback
+ * @brief Prototype of the clients function to accept notification of
+ * packetised rx
+ *
+ * This function is registered through the ixHssAccPktPortConnect. hssPktAcc will pass
+ * received data in the form of mbufs to the client. The mbuf passed back
+ * to the client could contain a chain of buffers, depending on the packet
+ * size received.
+ *
+ * @param *buffer @ref IX_OSAL_MBUF [in] - This is the mbuf which contains the
+ * payload received.
+ * @param numHssErrs unsigned [in] - This is the number of hssErrors
+ * the Npe has received
+ * @param pktStatus @ref IxHssAccPktStatus [in] - This is the status of the
+ * mbuf that has been received.
+ * @param rxUserId @ref IxHssAccPktUserId [in] - This is the client supplied value
+ * passed in at ixHssAccPktPortConnect time which is now returned to the client.
+ *
+ * @return void
+ */
+typedef void (*IxHssAccPktRxCallback) (IX_OSAL_MBUF *buffer,
+ unsigned numHssErrs,
+ IxHssAccPktStatus pktStatus,
+ IxHssAccPktUserId rxUserId);
+
+/**
+ * @typedef IxHssAccPktRxFreeLowCallback
+ * @brief Prototype of the clients function to accept notification of
+ * requirement of more Rx Free buffers
+ *
+ * The client can choose to register a callback of this type when
+ * calling a connecting. This function is registered through the ixHssAccPktPortConnect.
+ * If defined, the access layer will provide the trigger for
+ * this callback. The callback will be responsible for supplying mbufs to
+ * the access layer for use on the receive path from the HSS using
+ * ixHssPktAccFreeBufReplenish.
+ *
+ * @return void
+ */
+typedef void (*IxHssAccPktRxFreeLowCallback) (IxHssAccPktUserId rxFreeLowUserId);
+
+/**
+ * @typedef IxHssAccPktTxDoneCallback
+ * @brief Prototype of the clients function to accept notification of
+ * completion with Tx buffers
+ *
+ * This function is registered through the ixHssAccPktPortConnect. It enables
+ * the hssPktAcc to pass buffers back to the client
+ * when transmission is complete.
+ *
+ * @param *buffer @ref IX_OSAL_MBUF [in] - This is the mbuf which contained
+ * the payload that was for Tx.
+ * @param numHssErrs unsigned [in] - This is the number of hssErrors
+ * the Npe has received
+ * @param pktStatus @ref IxHssAccPktStatus [in] - This is the status of the
+ * mbuf that has been transmitted.
+ * @param txDoneUserId @ref IxHssAccPktUserId [in] - This is the client supplied value
+ * passed in at ixHssAccPktPortConnect time which is now returned to the client.
+ *
+ * @return void
+ */
+typedef void (*IxHssAccPktTxDoneCallback) (IX_OSAL_MBUF *buffer,
+ unsigned numHssErrs,
+ IxHssAccPktStatus pktStatus,
+ IxHssAccPktUserId txDoneUserId);
+
+/**
+ * @typedef IxHssAccChanRxCallback
+ * @brief Prototype of the clients function to accept notification of
+ * channelised rx
+ *
+ * This callback, if defined by the client in the connect, will get called
+ * in the context of an IRQ. The IRQ will be triggered when the hssSyncQMQ
+ * is not empty. The queued entry will be dequeued and this function will
+ * be executed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort - The HSS port Id. There are two
+ * identical ports (0-1).
+ * @param txOffset unsigned [in] - an offset indicating from where within
+ * the txPtrList the NPE is currently transmitting from.
+ * @param rxOffset unsigned [in] - an offset indicating where within the
+ * receive buffers the NPE has just written the received data to.
+ * @param numHssErrs unsigned [in] - This is the number of hssErrors
+ * the Npe has received
+ *
+ * @return void
+ */
+typedef void (*IxHssAccChanRxCallback) (IxHssAccHssPort hssPortId,
+ unsigned rxOffset,
+ unsigned txOffset,
+ unsigned numHssErrs);
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccPortInit (IxHssAccHssPort hssPortId,
+ IxHssAccConfigParams *configParams,
+ IxHssAccTdmSlotUsage *tdmMap,
+ IxHssAccLastErrorCallback lastHssErrorCallback)
+ *
+ * @brief Initialise a HSS port. No channelised or packetised connections
+ * should exist in the HssAccess layer while this interface is being called.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1).
+ * @param *configParams @ref IxHssAccConfigParams [in] - A pointer to the HSS
+ * configuration structure
+ * @param *tdmMap @ref IxHssAccTdmSlotUsage [in] - A pointer to an array of size
+ * IX_HSSACC_TSLOTS_PER_HSS_PORT, defining the slot usage over the HSS port
+ * @param lastHssErrorCallback @ref IxHssAccLastErrorCallback [in] - Client
+ * callback to report last error
+ *
+ * @return
+ * - IX_SUCCESS The function executed successfully
+ * - IX_FAIL The function did not execute successfully
+ * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ * parameter error
+ */
+PUBLIC IX_STATUS
+ixHssAccPortInit (IxHssAccHssPort hssPortId,
+ IxHssAccConfigParams *configParams,
+ IxHssAccTdmSlotUsage *tdmMap,
+ IxHssAccLastErrorCallback lastHssErrorCallback);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccLastErrorRetrievalInitiate (
+ IxHssAccHssPort hssPortId)
+ *
+ * @brief Initiate the retrieval of the last HSS error. The HSS port
+ * should be configured before attempting to call this interface.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - the HSS port ID
+ *
+ * @return
+ * - IX_SUCCESS The function executed successfully
+ * - IX_FAIL The function did not execute successfully
+ * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ * parameter error
+ */
+PUBLIC IX_STATUS
+ixHssAccLastErrorRetrievalInitiate (IxHssAccHssPort hssPortId);
+
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccInit ()
+ *
+ * @brief This function is responsible for initialising resources for use
+ * by the packetised and channelised clients. It should be called after
+ * HSS NPE image has been downloaded into NPE-A and before any other
+ * HssAccess interface is called.
+ * No other HssAccPacketised interface should be called while this interface
+ * is being processed.
+ *
+ * @return
+ * - IX_SUCCESS The function executed successfully
+ * - IX_FAIL The function did not execute successfully
+ * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due
+ * to a resource error
+ */
+PUBLIC IX_STATUS
+ixHssAccInit (void);
+
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn ixHssAccPktPortConnect (IxHssAccHssPort hssPortId,
+ IxHssAccHdlcPort hdlcPortId,
+ BOOL hdlcFraming,
+ IxHssAccHdlcMode hdlcMode,
+ BOOL hdlcBitInvert,
+ unsigned blockSizeInWords,
+ UINT32 rawIdleBlockPattern,
+ IxHssAccPktHdlcFraming hdlcTxFraming,
+ IxHssAccPktHdlcFraming hdlcRxFraming,
+ unsigned frmFlagStart,
+ IxHssAccPktRxCallback rxCallback,
+ IxHssAccPktUserId rxUserId,
+ IxHssAccPktRxFreeLowCallback rxFreeLowCallback,
+ IxHssAccPktUserId rxFreeLowUserId,
+ IxHssAccPktTxDoneCallback txDoneCallback,
+ IxHssAccPktUserId txDoneUserId)
+ *
+ * @brief This function is responsible for connecting a client to one of
+ * the 4 available HDLC ports. The HSS port should be configured before
+ * attempting a connect. No other HssAccPacketised interface should be
+ * called while this connect is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1).
+ * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port and
+ * it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3
+ * @param hdlcFraming BOOL [in] - This value determines whether the service
+ * will use HDLC data or the debug, raw data type i.e. no HDLC processing
+ * @param hdlcMode @ref IxHssAccHdlcMode [in] - This structure contains 56Kbps, HDLC-mode
+ * configuration parameters
+ * @param hdlcBitInvert BOOL [in] - This value determines whether bit inversion
+ * will occur between HDLC and HSS co-processors i.e. post-HDLC processing for
+ * transmit and pre-HDLC processing for receive, for the specified HDLC Termination
+ * Point
+ * @param blockSizeInWords unsigned [in] - The max tx/rx block size
+ * @param rawIdleBlockPattern UINT32 [in] - Tx idle pattern in raw mode
+ * @param hdlcTxFraming @ref IxHssAccPktHdlcFraming [in] - This structure contains
+ * the following information required by the NPE to configure the HDLC
+ * co-processor for TX
+ * @param hdlcRxFraming @ref IxHssAccPktHdlcFraming [in] - This structure contains
+ * the following information required by the NPE to configure the HDLC
+ * co-processor for RX
+ * @param frmFlagStart unsigned - Number of flags to precede to
+ * transmitted flags (0-2).
+ * @param rxCallback @ref IxHssAccPktRxCallback [in] - Pointer to
+ * the clients packet receive function.
+ * @param rxUserId @ref IxHssAccPktUserId [in] - The client supplied rx value
+ * to be passed back as an argument to the supplied rxCallback
+ * @param rxFreeLowCallback @ref IxHssAccPktRxFreeLowCallback [in] - Pointer to
+ * the clients Rx free buffer request function. If NULL, assume client will
+ * trigger independently.
+ * @param rxFreeLowUserId @ref IxHssAccPktUserId [in] - The client supplied RxFreeLow value
+ * to be passed back as an argument to the supplied rxFreeLowCallback
+ * @param txDoneCallback @ref IxHssAccPktTxDoneCallback [in] - Pointer to the
+ * clients Tx done callback function
+ * @param txDoneUserId @ref IxHssAccPktUserId [in] - The client supplied txDone value
+ * to be passed back as an argument to the supplied txDoneCallback
+ *
+ * @return
+ * - IX_SUCCESS The function executed successfully
+ * - IX_FAIL The function did not execute successfully
+ * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ * parameter error
+ * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due
+ * to a resource error
+ */
+PUBLIC IX_STATUS
+ixHssAccPktPortConnect (IxHssAccHssPort hssPortId,
+ IxHssAccHdlcPort hdlcPortId,
+ BOOL hdlcFraming,
+ IxHssAccHdlcMode hdlcMode,
+ BOOL hdlcBitInvert,
+ unsigned blockSizeInWords,
+ UINT32 rawIdleBlockPattern,
+ IxHssAccPktHdlcFraming hdlcTxFraming,
+ IxHssAccPktHdlcFraming hdlcRxFraming,
+ unsigned frmFlagStart,
+ IxHssAccPktRxCallback rxCallback,
+ IxHssAccPktUserId rxUserId,
+ IxHssAccPktRxFreeLowCallback rxFreeLowCallback,
+ IxHssAccPktUserId rxFreeLowUserId,
+ IxHssAccPktTxDoneCallback txDoneCallback,
+ IxHssAccPktUserId txDoneUserId);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccPktPortEnable (IxHssAccHssPort hssPortId,
+ IxHssAccHdlcPort hdlcPortId)
+ *
+ * @brief This function is responsible for enabling a packetised service
+ * for the specified HSS/HDLC port combination. It enables the RX flow. The
+ * client must have already connected to a packetised service and is responsible
+ * for ensuring an adequate amount of RX mbufs have been supplied to the access
+ * component before enabling the packetised service. This function must be called
+ * on a given port before any call to ixHssAccPktPortTx on the same port.
+ * No other HssAccPacketised interface should be called while this interface is
+ * being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1).
+ * @param hdlcPortId @ref IxHssAccHdlcPort [in] - The port id (0,1,2,3) to enable the service
+ * on.
+ *
+ * @return
+ * - IX_SUCCESS The function executed successfully
+ * - IX_FAIL The function did not execute successfully
+ * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ * parameter error
+ */
+PUBLIC IX_STATUS
+ixHssAccPktPortEnable (IxHssAccHssPort hssPortId,
+ IxHssAccHdlcPort hdlcPortId);
+
+/**
+ * @fn IX_STATUS ixHssAccPktPortDisable (IxHssAccHssPort hssPortId,
+ IxHssAccHdlcPort hdlcPortId)
+ *
+ * @brief This function is responsible for disabling a packetised service
+ * for the specified HSS/HDLC port combination. It disables the RX flow.
+ * The client must have already connected to and enabled a packetised service
+ * for the specified HDLC port. This disable interface can be called before a
+ * disconnect, but is not required to.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1).
+ * @param hdlcPortId @ref IxHssAccHdlcPort [in] - The port id (0,1,2,3) to disable
+ * the service on.
+ *
+ * @return
+ * - IX_SUCCESS The function executed successfully
+ * - IX_FAIL The function did not execute successfully
+ * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ * parameter error
+ */
+PUBLIC IX_STATUS
+ixHssAccPktPortDisable (IxHssAccHssPort hssPortId,
+ IxHssAccHdlcPort hdlcPortId);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccPktPortDisconnect (IxHssAccHssPort hssPortId,
+ IxHssAccHdlcPort hdlcPortId)
+ *
+ * @brief This function is responsible for disconnecting a client from one
+ * of the 4 available HDLC ports. It is not required that the Rx Flow
+ * has been disabled before calling this function. If the RX Flow has not been
+ * disabled, the disconnect will disable it before proceeding with the
+ * disconnect. No other HssAccPacketised
+ * interface should be called while this interface is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1).
+ * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port
+ * to disconnect and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3
+ *
+ * @return
+ * - IX_SUCCESS The function executed successfully
+ * - IX_FAIL The function did not execute successfully
+ * - IX_HSSACC_PKT_DISCONNECTING The function has initiated the disconnecting
+ * procedure but it has not completed yet.
+ */
+PUBLIC IX_STATUS
+ixHssAccPktPortDisconnect (IxHssAccHssPort hssPortId,
+ IxHssAccHdlcPort hdlcPortId);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn BOOL ixHssAccPktPortIsDisconnectComplete (IxHssAccHssPort hssPortId,
+ IxHssAccHdlcPort hdlcPortId)
+ *
+ * @brief This function is called to check if a given HSS/HDLC port
+ * combination is in a connected state or not. This function may be called
+ * at any time to determine a ports state. No other HssAccPacketised
+ * interface should be called while this interface is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1).
+ * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port
+ * to disconnect and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3
+ *
+ * @return
+ * - TRUE The state of this HSS/HDLC port combination is disconnected,
+ * so if a disconnect was called, it is now completed.
+ * - FALSE The state of this HSS/HDLC port combination is connected,
+ * so if a disconnect was called, it is not yet completed.
+ */
+PUBLIC BOOL
+ixHssAccPktPortIsDisconnectComplete (IxHssAccHssPort hssPortId,
+ IxHssAccHdlcPort hdlcPortId);
+
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccPktPortRxFreeReplenish (IxHssAccHssPort hssPortId,
+ IxHssAccHdlcPort hdlcPortId,
+ IX_OSAL_MBUF *buffer)
+ *
+ * @brief Function which the client calls at regular intervals to provide
+ * mbufs to the access component for RX. A connection should exist for
+ * the specified hssPortId/hdlcPortId combination before attempting to call this
+ * interface. Also, the connection should not be in a disconnecting state.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1).
+ * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port
+ * and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3
+ * @param *buffer @ref IX_OSAL_MBUF [in] - A pointer to a free mbuf to filled with payload.
+ *
+ * @return
+ * - IX_SUCCESS The function executed successfully
+ * - IX_FAIL The function did not execute successfully
+ * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ * parameter error
+ * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due
+ * to a resource error
+ * - IX_HSSACC_Q_WRITE_OVERFLOW The function did not succeed due to a Q
+ * overflow
+ */
+PUBLIC IX_STATUS
+ixHssAccPktPortRxFreeReplenish (IxHssAccHssPort hssPortId,
+ IxHssAccHdlcPort hdlcPortId,
+ IX_OSAL_MBUF *buffer);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccPktPortTx (IxHssAccHssPort hssPortId,
+ IxHssAccHdlcPort hdlcPortId,
+ IX_OSAL_MBUF *buffer)
+ *
+ * @brief Function which the client calls when it wants to transmit
+ * packetised data. An enabled connection should exist on the specified
+ * hssPortId/hdlcPortId combination before attempting to call this interface.
+ * No other HssAccPacketised
+ * interface should be called while this interface is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1).
+ * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port
+ * and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3
+ * @param *buffer @ref IX_OSAL_MBUF [in] - A pointer to a chain of mbufs which the
+ * client has filled with the payload
+ *
+ * @return
+ * - IX_SUCCESS The function executed successfully
+ * - IX_FAIL The function did not execute successfully
+ * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ * parameter error
+ * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due
+ * to a resource error. See note.
+ * - IX_HSSACC_Q_WRITE_OVERFLOW The function did not succeed due to a Q
+ * overflow
+ *
+ * @note IX_HSSACC_RESOURCE_ERR is returned when a free descriptor cannot be
+ * obtained to send the chain of mbufs to the NPE. This is a normal scenario.
+ * HssAcc has a pool of descriptors and this error means that they are currently
+ * all in use.
+ * The recommended approach to this is to retry until a descriptor becomes free
+ * and the packet is successfully transmitted.
+ * Alternatively, the user could wait until the next IxHssAccPktTxDoneCallback
+ * callback is triggered, and then retry, as it is this event that causes a
+ * transmit descriptor to be freed.
+ */
+PUBLIC IX_STATUS
+ixHssAccPktPortTx (IxHssAccHssPort hssPortId,
+ IxHssAccHdlcPort hdlcPortId,
+ IX_OSAL_MBUF *buffer);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccChanConnect (IxHssAccHssPort hssPortId,
+ unsigned bytesPerTSTrigger,
+ UINT8 *rxCircular,
+ unsigned numRxBytesPerTS,
+ UINT32 *txPtrList,
+ unsigned numTxPtrLists,
+ unsigned numTxBytesPerBlk,
+ IxHssAccChanRxCallback rxCallback)
+ *
+ * @brief This function allows the client to connect to the Tx/Rx NPE
+ * Channelised Service. There can only be one client per HSS port. The
+ * client is responsible for ensuring that the HSS port is configured
+ * appropriately before its connect request. No other HssAccChannelised
+ * interface should be called while this interface is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1).
+ * @param bytesPerTSTrigger unsigned [in] - The NPE will trigger the access
+ * component after bytesPerTSTrigger have been received for all trunk
+ * timeslots. This figure is a multiple of 8 e.g. 8 for 1ms trigger, 16 for
+ * 2ms trigger.
+ * @param *rxCircular UINT8 [in] - A pointer to memory allocated by the
+ * client to be filled by data received. The buffer at this address is part
+ * of a pool of buffers to be accessed in a circular fashion. This address
+ * will be written to by the NPE. Therefore, it needs to be a physical address.
+ * @param numRxBytesPerTS unsigned [in] - The number of bytes allocated per
+ * timeslot within the receive memory. This figure will depend on the
+ * latency of the system. It needs to be deep enough for data to be read by
+ * the client before the NPE re-writes over that memory e.g. if the client
+ * samples at a rate of 40bytes per timeslot, numRxBytesPerTS may need to
+ * be 40bytes * 3. This would give the client 3 * 5ms of time before
+ * received data is over-written.
+ * @param *txPtrList UINT32 [in] - The address of an area of contiguous
+ * memory allocated by the client to be populated with pointers to data for
+ * transmission. Each pointer list contains a pointer per active channel.
+ * The txPtrs will point to data to be transmitted by the NPE. Therefore,
+ * they must point to physical addresses.
+ * @param numTxPtrLists unsigned [in] - The number of pointer lists in
+ * txPtrList. This figure is dependent on jitter.
+ * @param numTxBytesPerBlk unsigned [in] - The size of the Tx data, in
+ * bytes, that each pointer within the PtrList points to.
+ * @param rxCallback @ref IxHssAccChanRxCallback [in] - A client function
+ * pointer to be called back to handle the actual tx/rx of channelised
+ * data. If this is not NULL, an ISR will call this function. If this
+ * pointer is NULL, it implies that the client will use a polling mechanism
+ * to detect when the tx and rx of channelised data is to occur. The client
+ * will use hssChanAccStatus for this.
+ *
+ * @return
+ * - IX_SUCCESS The function executed successfully
+ * - IX_FAIL The function did not execute successfully
+ * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ * parameter error
+ */
+
+PUBLIC IX_STATUS
+ixHssAccChanConnect (IxHssAccHssPort hssPortId,
+ unsigned bytesPerTSTrigger,
+ UINT8 *rxCircular,
+ unsigned numRxBytesPerTS,
+ UINT32 *txPtrList,
+ unsigned numTxPtrLists,
+ unsigned numTxBytesPerBlk,
+ IxHssAccChanRxCallback rxCallback);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccChanPortEnable (IxHssAccHssPort hssPortId)
+ *
+ * @brief This function is responsible for enabling a channelised service
+ * for the specified HSS port. It enables the NPE RX flow. The client must
+ * have already connected to a channelised service before enabling the
+ * channelised service. No other HssAccChannelised
+ * interface should be called while this interface is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1).
+ *
+ * @return
+ * - IX_SUCCESS The function executed successfully
+ * - IX_FAIL The function did not execute successfully
+ * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ * parameter error
+ */
+PUBLIC IX_STATUS
+ixHssAccChanPortEnable (IxHssAccHssPort hssPortId);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccChanPortDisable (IxHssAccHssPort hssPortId)
+ *
+ * @brief This function is responsible for disabling a channelised service
+ * for the specified HSS port. It disables the NPE RX flow. The client must
+ * have already connected to and enabled a channelised service for the
+ * specified HSS port. This disable interface can be called before a
+ * disconnect, but is not required to. No other HssAccChannelised
+ * interface should be called while this interface is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1).
+ *
+ * @return
+ * - IX_SUCCESS The function executed successfully
+ * - IX_FAIL The function did not execute successfully
+ * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ * parameter error
+ */
+PUBLIC IX_STATUS
+ixHssAccChanPortDisable (IxHssAccHssPort hssPortId);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccChanDisconnect (IxHssAccHssPort hssPortId)
+ *
+ * @brief This function allows the client to Disconnect from a channelised
+ * service. If the NPE RX Flow has not been disabled, the disconnect will
+ * disable it before proceeding with other disconnect functionality.
+ * No other HssAccChannelised interface should be called while this
+ * interface is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1).
+ *
+ * @return
+ * - IX_SUCCESS The function executed successfully
+ * - IX_FAIL The function did not execute successfully
+ * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ * parameter error
+ */
+PUBLIC IX_STATUS
+ixHssAccChanDisconnect (IxHssAccHssPort hssPortId);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccChanStatusQuery (IxHssAccHssPort hssPortId,
+ BOOL *dataRecvd,
+ unsigned *rxOffset,
+ unsigned *txOffset,
+ unsigned *numHssErrs)
+ *
+ * @brief This function is called by the client to query whether or not
+ * channelised data has been received. If there is, hssChanAcc will return
+ * the details in the output parameters. An enabled connection should
+ * exist on the specified hssPortId before attempting to call this interface.
+ * No other HssAccChannelised interface should be called while this
+ * interface is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1).
+ * @param *dataRecvd BOOL [out] - This BOOL indicates to the client whether
+ * or not the access component has read any data for the client. If
+ * FALSE, the other output parameters will not have been written to.
+ * @param *rxOffset unsigned [out] - An offset to indicate to the client
+ * where within the receive buffers the NPE has just written the received
+ * data to.
+ * @param *txOffset unsigned [out] - An offset to indicate to the client
+ * from where within the txPtrList the NPE is currently transmitting from
+ * @param *numHssErrs unsigned [out] - The total number of HSS port errors
+ * since initial port configuration
+ *
+ *
+ * @return
+ * - IX_SUCCESS The function executed successfully
+ * - IX_FAIL The function did not execute successfully
+ * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ * parameter error
+ */
+PUBLIC IX_STATUS
+ixHssAccChanStatusQuery (IxHssAccHssPort hssPortId,
+ BOOL *dataRecvd,
+ unsigned *rxOffset,
+ unsigned *txOffset,
+ unsigned *numHssErrs);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn void ixHssAccShow (void)
+ *
+ * @brief This function will display the current state of the IxHssAcc
+ * component. The output is sent to stdout.
+ *
+ * @return void
+ */
+PUBLIC void
+ixHssAccShow (void);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn void ixHssAccStatsInit (void)
+ *
+ * @brief This function will reset the IxHssAcc statistics.
+ *
+ * @return void
+ */
+PUBLIC void
+ixHssAccStatsInit (void);
+
+#endif /* IXHSSACC_H */
+
+/**
+ * @} defgroup IxHssAcc
+ */
diff --git a/cpu/ixp/npe/include/IxI2cDrv.h b/cpu/ixp/npe/include/IxI2cDrv.h
new file mode 100644
index 0000000..2472f31
--- /dev/null
+++ b/cpu/ixp/npe/include/IxI2cDrv.h
@@ -0,0 +1,867 @@
+/**
+ * @file IxI2cDrv.h
+ *
+ * @brief Header file for the IXP400 I2C Driver (IxI2cDrv)
+ *
+ * @version $Revision: 0.1 $
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxI2cDrv IXP400 I2C Driver(IxI2cDrv) API
+ *
+ * @brief IXP400 I2C Driver Public API
+ *
+ * @{
+ */
+#ifndef IXI2CDRV_H
+#define IXI2CDRV_H
+
+#ifdef __ixp46X
+#include "IxOsal.h"
+
+/*
+ * Section for #define
+ */
+
+/**
+ * @ingroup IxI2cDrv
+ * @brief The interval of micro/mili seconds the IXP will wait before it polls for
+ * status from the ixI2cIntrXferStatus; Every 20us is 1 byte @
+ * 400Kbps and 4 bytes @ 100Kbps. This is dependent on delay type selected
+ * through the API ixI2cDrvDelayTypeSelect.
+ */
+#define IX_I2C_US_POLL_FOR_XFER_STATUS 20
+
+/**
+ * @ingroup IxI2cDrv
+ * @brief The number of tries that will be attempted to call a callback
+ * function if the callback does not or is unable to resolve the
+ * issue it is called to resolve
+ */
+#define IX_I2C_NUM_OF_TRIES_TO_CALL_CALLBACK_FUNC 10
+
+
+/**
+ * @ingroup IxI2cDrv
+ * @brief Number of tries slave will poll the IDBR Rx full bit before it
+ * gives up
+ */
+#define IX_I2C_NUM_TO_POLL_IDBR_RX_FULL 0x100
+
+/**
+ * @ingroup IxI2cDrv
+ * @brief Number of tries slave will poll the IDBR Tx empty bit before it
+ * gives up
+ */
+#define IX_I2C_NUM_TO_POLL_IDBR_TX_EMPTY 0x100
+
+/*
+ * Section for enum
+ */
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @enum IxI2cMasterStatus
+ *
+ * @brief The master status - transfer complete, bus error or arbitration loss
+ */
+typedef enum
+{
+ IX_I2C_MASTER_XFER_COMPLETE = IX_SUCCESS,
+ IX_I2C_MASTER_XFER_BUS_ERROR,
+ IX_I2C_MASTER_XFER_ARB_LOSS
+} IxI2cMasterStatus;
+
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @enum IX_I2C_STATUS
+ *
+ * @brief The status that can be returned in a I2C driver initialization
+ */
+typedef enum
+{
+ IX_I2C_SUCCESS = IX_SUCCESS, /**< Success status */
+ IX_I2C_FAIL, /**< Fail status */
+ IX_I2C_NOT_SUPPORTED, /**< hardware does not have dedicated I2C hardware */
+ IX_I2C_NULL_POINTER, /**< parameter passed in is NULL */
+ IX_I2C_INVALID_SPEED_MODE_ENUM_VALUE, /**< speed mode selected is invalid */
+ IX_I2C_INVALID_FLOW_MODE_ENUM_VALUE, /**< flow mode selected is invalid */
+ IX_I2C_SLAVE_ADDR_CB_MISSING, /**< slave callback is NULL */
+ IX_I2C_GEN_CALL_CB_MISSING, /**< general callback is NULL */
+ IX_I2C_INVALID_SLAVE_ADDR, /**< invalid slave address specified */
+ IX_I2C_INT_BIND_FAIL, /**< interrupt bind fail */
+ IX_I2C_INT_UNBIND_FAIL, /**< interrupt unbind fail */
+ IX_I2C_NOT_INIT, /**< I2C is not initialized yet */
+ IX_I2C_MASTER_BUS_BUSY, /**< master detected a I2C bus busy */
+ IX_I2C_MASTER_ARB_LOSS, /**< master experienced arbitration loss */
+ IX_I2C_MASTER_XFER_ERROR, /**< master experienced a transfer error */
+ IX_I2C_MASTER_BUS_ERROR, /**< master detected a I2C bus error */
+ IX_I2C_MASTER_NO_BUFFER, /**< no buffer provided for master transfer */
+ IX_I2C_MASTER_INVALID_XFER_MODE, /**< xfer mode selected is invalid */
+ IX_I2C_SLAVE_ADDR_NOT_DETECTED, /**< polled slave addr not detected */
+ IX_I2C_GEN_CALL_ADDR_DETECTED, /**< polling detected general call */
+ IX_I2C_SLAVE_READ_DETECTED, /**< polling detected slave read request */
+ IX_I2C_SLAVE_WRITE_DETECTED, /**< polling detected slave write request */
+ IX_I2C_SLAVE_NO_BUFFER, /**< no buffer provided for slave transfers */
+ IX_I2C_DATA_SIZE_ZERO, /**< data size transfer is zero - invalid */
+ IX_I2C_SLAVE_WRITE_BUFFER_EMPTY, /**< slave buffer is used till empty */
+ IX_I2C_SLAVE_WRITE_ERROR, /**< slave write experienced an error */
+ IX_I2C_SLAVE_OR_GEN_READ_BUFFER_FULL, /**< slave buffer is filled up */
+ IX_I2C_SLAVE_OR_GEN_READ_ERROR /**< slave read experienced an error */
+} IX_I2C_STATUS;
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @enum IxI2cSpeedMode
+ *
+ * @brief Type of speed modes supported by the I2C hardware.
+ */
+typedef enum
+{
+ IX_I2C_NORMAL_MODE = 0x0,
+ IX_I2C_FAST_MODE
+} IxI2cSpeedMode;
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @enum IxI2cXferMode
+ *
+ * @brief Used for indicating it is a repeated start or normal transfer
+ */
+typedef enum
+{
+ IX_I2C_NORMAL = 0x0,
+ IX_I2C_REPEATED_START
+} IxI2cXferMode;
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @enum IxI2cFlowMode
+ *
+ * @brief Used for indicating it is a poll or interrupt mode
+ */
+typedef enum
+{
+ IX_I2C_POLL_MODE = 0x0,
+ IX_I2C_INTERRUPT_MODE
+} IxI2cFlowMode;
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @enum IxI2cDelayMode
+ *
+ * @brief Used for selecting looping delay or OS scheduler delay
+ */
+typedef enum
+{
+ IX_I2C_LOOP_DELAY = 1, /**< delay in microseconds */
+ IX_I2C_SCHED_DELAY /**< delay in miliseconds */
+} IxI2cDelayMode;
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @brief The pointer to the function that will be called when the master
+ * has completed its receive. The parameter that is passed will
+ * provide the status of the read (success, arb loss, or bus
+ * error), the transfer mode (normal or repeated start, the
+ * buffer pointer and number of bytes transferred.
+ */
+typedef void (*IxI2cMasterReadCallbackP)(IxI2cMasterStatus, IxI2cXferMode, char*, UINT32);
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @brief The pointer to the function that will be called when the master
+ * has completed its transmit. The parameter that is passed will
+ * provide the status of the write (success, arb loss, or buss
+ * error), the transfer mode (normal or repeated start), the
+ * buffer pointer and number of bytes transferred.
+ */
+typedef void (*IxI2cMasterWriteCallbackP)(IxI2cMasterStatus, IxI2cXferMode, char*, UINT32);
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @brief The pointer to the function that will be called when a slave
+ * address detected in interrupt mode for a read. The parameters
+ * that is passed will provide the read status, buffer pointer,
+ * buffer size, and the bytes received. When a start of a read
+ * is initiated there will be no buffer allocated and this callback
+ * will be called to request for a buffer. While receiving, if the
+ * buffer gets filled, this callback will be called to request for
+ * a new buffer while sending the filled buffer's pointer and size,
+ * and data size received. When the receive is complete, this
+ * callback will be called to process the data and free the memory
+ * by passing the buffer's pointer and size, and data size received.
+ */
+typedef void (*IxI2cSlaveReadCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32);
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @brief The pointer to the function that will be called when a slave
+ * address detected in interrupt mode for a write. The parameters
+ * that is passed will provide the write status, buffer pointer,
+ * buffer size, and the bytes received. When a start of a write is
+ * initiated there will be no buffer allocated and this callback
+ * will be called to request for a buffer and to fill it with data.
+ * While transmitting, if the data in the buffer empties, this
+ * callback will be called to request for more data to be filled in
+ * the same or new buffer. When the transmit is complete, this
+ * callback will be called to free the memory or other actions to
+ * be taken.
+ */
+typedef void (*IxI2cSlaveWriteCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32);
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @brief The pointer to the function that will be called when a general
+ * call detected in interrupt mode for a read. The parameters that
+ * is passed will provide the read status, buffer pointer, buffer
+ * size, and the bytes received. When a start of a read is
+ * initiated there will be no buffer allocated and this callback
+ * will be called to request for a buffer. While receiving, if the
+ * buffer gets filled, this callback will be called to request for
+ * a new buffer while sending the filled buffer's pointer and size,
+ * and data size received. When the receive is complete, this
+ * callback will be called to process the data and free the memory
+ * by passing the buffer's pointer and size, and data size received.
+ */
+typedef void (*IxI2cGenCallCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32);
+
+/*
+ * Section for struct
+ */
+
+/**
+ * @brief contains all the variables required to initialize the I2C unit
+ *
+ * Structure to be filled and used for calling initialization
+ */
+typedef struct
+{
+ IxI2cSpeedMode I2cSpeedSelect; /**<Select either normal (100kbps)
+ or fast mode (400kbps)*/
+ IxI2cFlowMode I2cFlowSelect; /**<Select interrupt or poll mode*/
+ IxI2cMasterReadCallbackP MasterReadCBP;
+ /**<The master read callback pointer */
+ IxI2cMasterWriteCallbackP MasterWriteCBP;
+ /**<The master write callback pointer */
+ IxI2cSlaveReadCallbackP SlaveReadCBP;
+ /**<The slave read callback pointer */
+ IxI2cSlaveWriteCallbackP SlaveWriteCBP;
+ /**<The slave write callback pointer */
+ IxI2cGenCallCallbackP GenCallCBP;
+ /**<The general call callback pointer */
+ BOOL I2cGenCallResponseEnable; /**<Enable/disable the unit to
+ respond to generall calls.*/
+ BOOL I2cSlaveAddrResponseEnable;/**<Enable/disable the unit to
+ respond to the slave address set in
+ ISAR*/
+ BOOL SCLEnable; /**<Enable/disable the unit from
+ driving the SCL line during master
+ mode operation*/
+ UINT8 I2cHWAddr; /**<The address the unit will
+ response to as a slave device*/
+} IxI2cInitVars;
+
+/**
+ * @brief contains results of counters and their overflow
+ *
+ * Structure contains all values of counters and associated overflows.
+ */
+typedef struct
+{
+ UINT32 ixI2cMasterXmitCounter; /**<Total bytes transmitted as
+ master.*/
+ UINT32 ixI2cMasterFailedXmitCounter; /**<Total bytes failed for
+ transmission as master.*/
+ UINT32 ixI2cMasterRcvCounter; /**<Total bytes received as
+ master.*/
+ UINT32 ixI2cMasterFailedRcvCounter; /**<Total bytes failed for
+ receival as master.*/
+ UINT32 ixI2cSlaveXmitCounter; /**<Total bytes transmitted as
+ slave.*/
+ UINT32 ixI2cSlaveFailedXmitCounter; /**<Total bytes failed for
+ transmission as slave.*/
+ UINT32 ixI2cSlaveRcvCounter; /**<Total bytes received as
+ slave.*/
+ UINT32 ixI2cSlaveFailedRcvCounter; /**<Total bytes failed for
+ receival as slave.*/
+ UINT32 ixI2cGenAddrCallSucceedCounter; /**<Total bytes successfully
+ transmitted for general address.*/
+ UINT32 ixI2cGenAddrCallFailedCounter; /**<Total bytes failed transmission
+ for general address.*/
+ UINT32 ixI2cArbLossCounter; /**<Total instances of arbitration
+ loss has occured.*/
+} IxI2cStatsCounters;
+
+
+/*
+ * Section for prototypes interface functions
+ */
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @fn ixI2cDrvInit(
+ IxI2cInitVars *InitVarsSelected)
+ *
+ * @brief Initializes the I2C Driver.
+ *
+ * @param "IxI2cInitVars [in] *InitVarsSelected" - struct containing required
+ * variables for initialization
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will check if the hardware supports this I2C driver and the validity
+ * of the parameters passed in. It will continue to process the parameters
+ * passed in by setting the speed of the I2C unit (100kbps or 400kbps), setting
+ * the flow to either interrupt or poll mode, setting the address of the I2C unit,
+ * enabling/disabling the respond to General Calls, enabling/disabling the respond
+ * to Slave Address and SCL line driving. If it is interrupt mode, then it will
+ * register the callback routines for master, slavetransfer and general call receive.
+ *
+ * @return
+ * - IX_I2C_SUCCESS - Successfully initialize and enable the I2C
+ * hardware.
+ * - IX_I2C_NOT_SUPPORTED - The hardware does not support or have a
+ * dedicated I2C unit to support this driver
+ * - IX_I2C_NULL_POINTER - The parameter passed in is a NULL pointed
+ * - IX_I2C_INVALID_SPEED_MODE_ENUM_VALUE - The speed mode selected in the
+ * InitVarsSelected is invalid
+ * - IX_I2C_INVALID_FLOW_MODE_ENUM_VALUE - The flow mode selected in the
+ * InitVarsSelected is invalid
+ * - IX_I2C_INVALID_SLAVE_ADDR - The address 0x0 is reserved for
+ * general call.
+ * - IX_I2C_SLAVE_ADDR_CB_MISSING - interrupt mode is selected but
+ * slave address callback pointer is NULL
+ * - IX_I2C_GEN_CALL_CB_MISSING - interrupt mode is selected but
+ * general call callback pointer is NULL
+ * - IX_I2C_INT_BIND_FAIL - The ISR for the I2C failed to bind
+ * - IX_I2C_INT_UNBIND_FAIL - The ISR for the I2C failed to unbind
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvInit(IxI2cInitVars *InitVarsSelected);
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @fn ixI2cDrvUninit(
+ void)
+ *
+ * @brief Disables the I2C hardware
+ *
+ * @param - None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will disable the I2C hardware, unbind interrupt, and unmap memory.
+ *
+ * @return
+ * - IX_I2C_SUCCESS - successfully un-initialized I2C
+ * - IX_I2C_INT_UNBIND_FAIL - failed to unbind the I2C interrupt
+ * - IX_I2C_NOT_INIT - I2C not init yet.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvUninit(void);
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @fn ixI2cDrvSlaveAddrSet(
+ UINT8 SlaveAddrSet)
+ *
+ * @brief Sets the I2C Slave Address
+ *
+ * @param "UINT8 [in] SlaveAddrSet" - Slave Address to be inserted into ISAR
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will insert the SlaveAddrSet into the ISAR.
+ *
+ * @return
+ * - IX_I2C_SUCCESS - successfuly set the slave addr
+ * - IX_I2C_INVALID_SLAVE_ADDR - invalid slave address (zero) specified
+ * - IX_I2C_NOT_INIT - I2C not init yet.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvSlaveAddrSet(UINT8 SlaveAddrSet);
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @fn ixI2cDrvBusScan(
+ void)
+ *
+ * @brief scans the I2C bus for slave devices
+ *
+ * @param - None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will prompt all slave addresses for a reply except its own
+ *
+ * @return
+ * - IX_I2C_SUCCESS - found at least one slave device
+ * - IX_I2C_FAIL - Fail to find even one slave device
+ * - IX_I2C_BUS_BUSY - The I2C bus is busy (held by another I2C master)
+ * - IX_I2C_ARB_LOSS - The I2C bus was loss to another I2C master
+ * - IX_I2C_NOT_INIT - I2C not init yet.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvBusScan(void);
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @fn ixI2cDrvWriteTransfer(
+ UINT8 SlaveAddr,
+ char *bufP,
+ UINT32 dataSize,
+ IxI2cXferMode XferModeSelect)
+ *
+ * @param "UINT8 [in] SlaveAddr" - The slave address to request data from.
+ * @param "char [in] *bufP" - The pointer to the data to be transmitted.
+ * @param "UINT32 [in] dataSize" - The number of bytes requested.
+ * @param "IxI2cXferMode [in] XferModeSelect" - the transfer mode selected,
+ * either repeated start (ends w/o stop) or normal (start and stop)
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will try to obtain master control of the I2C bus and transmit the
+ * number of bytes, specified by dataSize, to the user specified slave
+ * address from the buffer pointer. It will use either interrupt or poll mode
+ * depending on the method selected.
+ *
+ * If in interrupt mode and IxI2cMasterWriteCallbackP is not NULL, the driver
+ * will initiate the transfer and return immediately. The function pointed to
+ * by IxI2cMasterWriteCallbackP will be called in the interrupt service
+ * handlers when the operation is complete.
+ *
+ * If in interrupt mode and IxI2cMasterWriteCallbackP is NULL, then the driver
+ * will wait for the operation to complete, and then return.
+ *
+ * And if the repeated start transfer mode is selected, then it will not send a
+ * stop signal at the end of all the transfers.
+ * *NOTE*: If repeated start transfer mode is selected, it has to end with a
+ * normal mode transfer mode else the bus will continue to be held
+ * by the IXP.
+ *
+ * @return
+ * - IX_I2C_SUCCESS - Successfuuly wrote data to slave.
+ * - IX_I2C_MASTER_BUS_BUSY - The I2C bus is busy (held by another I2C master)
+ * - IX_I2C_MASTER_ARB_LOSS - The I2C bus was loss to another I2C master
+ * - IX_I2C_MASTER_XFER_ERROR - There was a transfer error
+ * - IX_I2C_MASTER_BUS_ERROR - There was a bus error during transfer
+ * - IX_I2C_MASTER_NO_BUFFER - buffer pointer is NULL
+ * - IX_I2C_MASTER_INVALID_XFER_MODE - Xfer mode selected is invalid
+ * - IX_I2C_DATA_SIZE_ZERO - dataSize passed in is zero, which is invalid
+ * - IX_I2C_NOT_INIT - I2C not init yet.
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvWriteTransfer(
+ UINT8 SlaveAddr,
+ char *bufP,
+ UINT32 dataSize,
+ IxI2cXferMode XferModeSelect);
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @fn ixI2cDrvReadTransfer(
+ UINT8 SlaveAddr,
+ char *bufP,
+ UINT32 dataSize,
+ IxI2cXferMode XferModeSelect)
+ *
+ * @brief Initiates a transfer to receive bytes of data from a slave
+ * device through the I2C bus.
+ *
+ * @param "UINT8 [in] SlaveAddr" - The slave address to request data from.
+ * @param "char [out] *bufP" - The pointer to the buffer to store the
+ * requested data.
+ * @param "UINT32 [in] dataSize" - The number of bytes requested.
+ * @param "IxI2cXferMode [in] XferModeSelect" - the transfer mode selected,
+ * either repeated start (ends w/o stop) or normal (start and stop)
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will try to obtain master control of the I2C bus and receive the
+ * number of bytes, specified by dataSize, from the user specified address
+ * into the receive buffer. It will use either interrupt or poll mode depending
+ * on the mode selected.
+ *
+ * If in interrupt mode and IxI2cMasterReadCallbackP is not NULL, the driver
+ * will initiate the transfer and return immediately. The function pointed to
+ * by IxI2cMasterReadCallbackP will be called in the interrupt service
+ * handlers when the operation is complete.
+ *
+ * If in interrupt mode and IxI2cMasterReadCallbackP is NULL, then the driver will
+ * wait for the operation to complete, and then return.
+ *
+ * And if the repeated start transfer mode is selected, then it will not send a
+ * stop signal at the end of all the transfers.
+ * *NOTE*: If repeated start transfer mode is selected, it has to end with a
+ * normal mode transfer mode else the bus will continue to be held
+ * by the IXP.
+ *
+ * @return
+ * - IX_I2C_SUCCESS - Successfuuly read slave data
+ * - IX_I2C_MASTER_BUS_BUSY - The I2C bus is busy (held by another I2C master)
+ * - IX_I2C_MASTER_ARB_LOSS - The I2C bus was loss to another I2C master
+ * - IX_I2C_MASTER_XFER_ERROR - There was a bus error during transfer
+ * - IX_I2C_MASTER_BUS_ERROR - There was a bus error during transfer
+ * - IX_I2C_MASTER_NO_BUFFER - buffer pointer is NULL
+ * - IX_I2C_MASTER_INVALID_XFER_MODE - Xfer mode selected is invalid
+ * - IX_I2C_INVALID_SLAVE_ADDR - invalid slave address (zero) specified
+ * - IX_I2C_DATA_SIZE_ZERO - dataSize passed in is zero, which is invalid
+ * - IX_I2C_NOT_INIT - I2C not init yet.
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvReadTransfer(
+ UINT8 SlaveAddr,
+ char *bufP,
+ UINT32 dataSize,
+ IxI2cXferMode XferModeSelect);
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @fn ixI2cDrvSlaveAddrAndGenCallDetectedCheck(
+ void)
+ *
+ * @brief Checks the I2C Status Register to determine if a slave address is
+ * detected
+ *
+ * @param - None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API is used in polled mode to determine if the I2C unit is requested
+ * for a slave or general call transfer. If it is requested for a slave
+ * transfer then it will determine if it is a general call (read only), read,
+ * or write transfer requested.
+ *
+ * @return
+ * - IX_I2C_SLAVE_ADDR_NOT_DETECTED - The I2C unit is not requested for slave
+ * transfer
+ * - IX_I2C_GEN_CALL_ADDR_DETECTED - The I2C unit is not requested for slave
+ * transfer but for general call
+ * - IX_I2C_SLAVE_READ_DETECTED - The I2C unit is requested for a read
+ * - IX_I2C_SLAVE_WRITE_DETECTED - The I2C unit is requested for a write
+ * - IX_I2C_NOT_INIT - I2C not init yet.
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvSlaveAddrAndGenCallDetectedCheck(void);
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @fn ixI2cDrvSlaveOrGenDataReceive(
+ char *bufP,
+ UINT32 bufSize,
+ UINT32 *dataSizeRcvd)
+ *
+ * @brief Performs the slave receive or general call receive data transfer
+ *
+ * @param "char [in] *bufP" - the pointer to the buffer to store data
+ * "UINT32 [in] bufSize" - the buffer size allocated
+ * "UINT32 [in] *dataSizeRcvd" - the length of data received in bytes
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API is only used in polled mode to perform the slave read or general call
+ * receive data. It will continuously store the data received into bufP until
+ * complete or until bufP is full in which it will return
+ * IX_I2C_SLAVE_OR_GEN_READ_BUFFER_FULL. If in interrupt mode, the callback will be
+ * used.
+ *
+ * @return
+ * - IX_I2C_SUCCESS - The I2C driver transferred the data successfully.
+ * - IX_I2C_SLAVE_OR_GEN_READ_BUFFER_FULL - The I2C driver has ran out of
+ * space to store the received data.
+ * - IX_I2C_SLAVE_OR_GEN_READ_ERROR - The I2C driver didn't manage to
+ * detect the IDBR Rx Full bit
+ * - IX_I2C_DATA_SIZE_ZERO - bufSize passed in is zero, which is invalid
+ * - IX_I2C_SLAVE_NO_BUFFER - buffer pointer is NULL
+ * - IX_I2C_NULL_POINTER - dataSizeRcvd is NULL
+ * - IX_I2C_NOT_INIT - I2C not init yet.
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvSlaveOrGenDataReceive(
+ char *bufP,
+ UINT32 bufSize,
+ UINT32 *dataSizeRcvd);
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @fn ixI2cDrvSlaveDataTransmit(
+ char *bufP,
+ UINT32 dataSize,
+ UINT32 *dataSizeXmtd)
+ *
+ * @brief Performs the slave write data transfer
+ *
+ * @param "char [in] *bufP" - the pointer to the buffer for data to be
+ * transmitted
+ * "UINT32 [in] bufSize" - the buffer size allocated
+ * "UINT32 [in] *dataSizeRcvd" - the length of data trasnmitted in
+ * bytes
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API is only used in polled mode to perform the slave transmit data. It
+ * will continuously transmit the data from bufP until complete or until bufP
+ * is empty in which it will return IX_I2C_SLAVE_WRITE_BUFFER_EMPTY. If in
+ * interrupt mode, the callback will be used.
+ *
+ * @return
+ * - IX_I2C_SUCCESS - The I2C driver transferred the data successfully.
+ * - IX_I2C_SLAVE_WRITE_BUFFER_EMPTY - The I2C driver needs more data to
+ * transmit.
+ * - IX_I2C_SLAVE_WRITE_ERROR -The I2C driver didn't manage to detect the
+ * IDBR Tx empty bit or the slave stop bit.
+ * - IX_I2C_DATA_SIZE_ZERO - dataSize passed in is zero, which is invalid
+ * - IX_I2C_SLAVE_NO_BUFFER - buffer pointer is NULL
+ * - IX_I2C_NULL_POINTER - dataSizeXmtd is NULL
+ * - IX_I2C_NOT_INIT - I2C not init yet.
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvSlaveDataTransmit(
+ char *bufP,
+ UINT32 dataSize,
+ UINT32 *dataSizeXmtd);
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @fn ixI2cDrvSlaveOrGenCallBufReplenish(
+ char *bufP,
+ UINT32 bufSize)
+ *
+ * @brief Replenishes the buffer which stores buffer info for both slave and
+ * general call
+ *
+ * @param "char [in] *bufP" - pointer to the buffer allocated
+ * "UINT32 [in] bufSize" - size of the buffer
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API is only used in interrupt mode for replenishing the same buffer
+ * that is used by both slave and generall call by updating the buffer info
+ * with new info and clearing previous offsets set by previous transfers.
+ *
+ * @return
+ * - None
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC void
+ixI2cDrvSlaveOrGenCallBufReplenish(
+ char *bufP,
+ UINT32 bufSize);
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @fn ixI2cDrvStatsGet(IxI2cStatsCounters *I2cStats)
+ *
+ * @brief Returns the I2C Statistics through the pointer passed in
+ *
+ * @param - "IxI2cStatsCounters [out] *I2cStats" - I2C statistics counter will
+ * be read and written to the location pointed by this pointer.
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will return the statistics counters of the I2C driver.
+ *
+ * @return
+ * - IX_I2C_NULL_POINTER - pointer passed in is NULL
+ * - IX_I2C_SUCCESS - successfully obtained I2C statistics
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvStatsGet(IxI2cStatsCounters *I2cStats);
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @fn ixI2cDrvStatsReset(void)
+ *
+ * @brief Reset I2C statistics counters.
+ *
+ * @param - None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will reset the statistics counters of the I2C driver.
+ *
+ * @return
+ * - None
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC void
+ixI2cDrvStatsReset(void);
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @fn ixI2cDrvShow(void)
+ *
+ * @brief Displays the I2C status register and the statistics counter.
+ *
+ * @param - None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will display the I2C Status register and is useful if any error
+ * occurs. It displays the detection of bus error, slave address, general call,
+ * address, IDBR receive full, IDBR transmit empty, arbitration loss, slave
+ * STOP signal, I2C bus busy, unit busy, ack/nack, and read/write mode. It will
+ * also call the ixI2cDrvGetStats and then display the statistics counter.
+ *
+ * @return
+ * - IX_I2C_SUCCESS - successfully displayed statistics and status register
+ * - IX_I2C_NOT_INIT - I2C not init yet.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvShow(void);
+
+/**
+ * @ingroup IxI2cDrv
+ *
+ * @fn ixI2cDrvDelayTypeSelect (IxI2cDelayMode delayMechanismSelect)
+ *
+ * @brief Sets the delay type of either looping delay or OS scheduler delay
+ * according to the argument provided.
+ *
+ * @param - "IxI2cDelayMode [in] delayTypeSelect" - the I2C delay type selected
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will set the delay type used by the I2C Driver to either looping
+ * delay or OS scheduler delay.
+ *
+ * @return
+ * - None
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC void
+ixI2cDrvDelayTypeSelect (IxI2cDelayMode delayTypeSelect);
+
+#endif /* __ixp46X */
+#endif /* IXI2CDRV_H */
diff --git a/cpu/ixp/npe/include/IxNpeA.h b/cpu/ixp/npe/include/IxNpeA.h
new file mode 100644
index 0000000..7427cc4
--- /dev/null
+++ b/cpu/ixp/npe/include/IxNpeA.h
@@ -0,0 +1,782 @@
+#ifndef __doxygen_HIDE /* This file is not part of the API */
+
+/**
+ * @file IxNpeA.h
+ *
+ * @date 22-Mar-2002
+ *
+ * @brief Header file for the IXP400 ATM NPE API
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxNpeA IXP400 NPE-A (IxNpeA) API
+ *
+ * @brief The Public API for the IXP400 NPE-A
+ *
+ * @{
+ */
+
+#ifndef IX_NPE_A_H
+#define IX_NPE_A_H
+
+#include "IxQMgr.h"
+#include "IxOsal.h"
+#include "IxQueueAssignments.h"
+
+/* General Message Ids */
+
+/* ATM Message Ids */
+
+/**
+ * @def IX_NPE_A_MSSG_ATM_UTOPIA_CONFIG_WRITE
+ *
+ * @brief ATM Message ID command to write the data to the offset in the
+ * Utopia Configuration Table
+ */
+#define IX_NPE_A_MSSG_ATM_UTOPIA_CONFIG_WRITE 0x20
+
+/**
+ * @def IX_NPE_A_MSSG_ATM_UTOPIA_CONFIG_LOAD
+ *
+ * @brief ATM Message ID command triggers the NPE to copy the Utopia
+ * Configuration Table to the Utopia coprocessor
+ */
+#define IX_NPE_A_MSSG_ATM_UTOPIA_CONFIG_LOAD 0x21
+
+/**
+ * @def IX_NPE_A_MSSG_ATM_UTOPIA_STATUS_UPLOAD
+ *
+ * @brief ATM Message ID command triggers the NPE to read-back the Utopia
+ * status registers and update the Utopia Status Table.
+ */
+#define IX_NPE_A_MSSG_ATM_UTOPIA_STATUS_UPLOAD 0x22
+
+/**
+ * @def IX_NPE_A_MSSG_ATM_UTOPIA_STATUS_READ
+ *
+ * @brief ATM Message ID command to read the Utopia Status Table at the
+ * specified offset.
+ */
+#define IX_NPE_A_MSSG_ATM_UTOPIA_STATUS_READ 0x23
+
+/**
+ * @def IX_NPE_A_MSSG_ATM_TX_ENABLE
+ *
+ * @brief ATM Message ID command triggers the NPE to re-enable processing
+ * of any entries on the TxVcQ for this port.
+ *
+ * This command will be ignored for a port already enabled
+ */
+#define IX_NPE_A_MSSG_ATM_TX_ENABLE 0x25
+
+ /**
+ * @def IX_NPE_A_MSSG_ATM_TX_DISABLE
+ *
+ * @brief ATM Message ID command triggers the NPE to disable processing on
+ * this port
+ *
+ * This command will be ignored for a port already disabled
+ */
+#define IX_NPE_A_MSSG_ATM_TX_DISABLE 0x26
+
+/**
+ * @def IX_NPE_A_MSSG_ATM_RX_ENABLE
+ *
+ * @brief ATM Message ID command triggers the NPE to process any received
+ * cells for this VC according to the VC Lookup Table.
+ *
+ * Re-issuing this command with different contents for a VC that is not
+ * disabled will cause unpredictable behavior.
+ */
+#define IX_NPE_A_MSSG_ATM_RX_ENABLE 0x27
+
+/**
+ * @def IX_NPE_A_MSSG_ATM_RX_DISABLE
+ *
+ * @brief ATM Message ID command triggers the NPE to disable processing for
+ * this VC.
+ *
+ * This command will be ignored for a VC already disabled
+ */
+#define IX_NPE_A_MSSG_ATM_RX_DISABLE 0x28
+
+/**
+ * @def IX_NPE_A_MSSG_ATM_STATUS_READ
+ *
+ * @brief ATM Message ID command to read the ATM status. The data is returned via
+ * a response message
+ */
+#define IX_NPE_A_MSSG_ATM_STATUS_READ 0x29
+
+/*--------------------------------------------------------------------------
+ * HSS Message IDs
+ *--------------------------------------------------------------------------*/
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PORT_CONFIG_WRITE
+ *
+ * @brief HSS Message ID command writes the ConfigWord value to the location
+ * in the HSS_CONFIG_TABLE specified by offset for HSS port hPort.
+ */
+#define IX_NPE_A_MSSG_HSS_PORT_CONFIG_WRITE 0x40
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PORT_CONFIG_LOAD
+ *
+ * @brief HSS Message ID command triggers the NPE to copy the contents of the
+ * HSS Configuration Table to the appropriate configuration registers in the
+ * HSS coprocessor for the port specified by hPort.
+ */
+#define IX_NPE_A_MSSG_HSS_PORT_CONFIG_LOAD 0x41
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PORT_ERROR_READ
+ *
+ * @brief HSS Message ID command triggers the NPE to return an HssErrorReadResponse
+ * message for HSS port hPort.
+ */
+#define IX_NPE_A_MSSG_HSS_PORT_ERROR_READ 0x42
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_CHAN_FLOW_ENABLE
+ *
+ * @brief HSS Message ID command triggers the NPE to reset internal status and
+ * enable the HssChannelized operation on the HSS port specified by hPort.
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_FLOW_ENABLE 0x43
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_CHAN_FLOW_DISABLE
+ *
+ * @brief HSS Message ID command triggers the NPE to disable the HssChannelized
+ * operation on the HSS port specified by hPort.
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_FLOW_DISABLE 0x44
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_CHAN_IDLE_PATTERN_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnC_IDLE_PATTERN value for HSS
+ * port hPort. (n=hPort)
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_IDLE_PATTERN_WRITE 0x45
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_CHAN_NUM_CHANS_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnC_NUM_CHANNELS value for HSS
+ * port hPort. (n=hPort)
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_NUM_CHANS_WRITE 0x46
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_CHAN_RX_BUF_ADDR_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnC_RX_BUF_ADDR value for HSS
+ * port hPort. (n=hPort)
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_RX_BUF_ADDR_WRITE 0x47
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_CHAN_RX_BUF_CFG_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnC_RX_BUF_SIZEB and
+ * HSSnC_RX_TRIG_PERIOD values for HSS port hPort. (n=hPort)
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_RX_BUF_CFG_WRITE 0x48
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_CHAN_TX_BLK_CFG_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnC_TX_BLK1_SIZEB,
+ * HSSnC_TX_BLK1_SIZEW, HSSnC_TX_BLK2_SIZEB, and HSSnC_TX_BLK2_SIZEW values
+ * for HSS port hPort. (n=hPort)
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_TX_BLK_CFG_WRITE 0x49
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_CHAN_TX_BUF_ADDR_WRITE
+ * @brief HSS Message ID command writes the HSSnC_TX_BUF_ADDR value for HSS
+ * port hPort. (n=hPort)
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_TX_BUF_ADDR_WRITE 0x4A
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_CHAN_TX_BUF_SIZE_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnC_TX_BUF_SIZEN value for HSS
+ * port hPort. (n=hPort)
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_TX_BUF_SIZE_WRITE 0x4B
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PKT_PIPE_FLOW_ENABLE
+ *
+ * @brief HSS Message ID command triggers the NPE to reset internal status and
+ * enable the HssPacketized operation for the flow specified by pPipe on
+ * the HSS port specified by hPort.
+ */
+#define IX_NPE_A_MSSG_HSS_PKT_PIPE_FLOW_ENABLE 0x50
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PKT_PIPE_FLOW_DISABLE
+ * @brief HSS Message ID command triggers the NPE to disable the HssPacketized
+ * operation for the flow specified by pPipe on the HSS port specified by hPort.
+ */
+#define IX_NPE_A_MSSG_HSS_PKT_PIPE_FLOW_DISABLE 0x51
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PKT_NUM_PIPES_WRITE
+ * @brief HSS Message ID command writes the HSSnP_NUM_PIPES value for HSS
+ * port hPort.(n=hPort)
+ */
+#define IX_NPE_A_MSSG_HSS_PKT_NUM_PIPES_WRITE 0x52
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PKT_PIPE_FIFO_SIZEW_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnP_PIPEp_FIFOSIZEW value for
+ * packet-pipe pPipe on HSS port hPort. (n=hPort, p=pPipe)
+ */
+#define IX_NPE_A_MSSG_HSS_PKT_PIPE_FIFO_SIZEW_WRITE 0x53
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PKT_PIPE_HDLC_CFG_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnP_PIPEp_HDLC_RXCFG and
+ * HSSnP_PIPEp_HDLC_TXCFG values for packet-pipe pPipe on HSS port hPort.
+ * (n=hPort, p=pPipe)
+ */
+#define IX_NPE_A_MSSG_HSS_PKT_PIPE_HDLC_CFG_WRITE 0x54
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PKT_PIPE_IDLE_PATTERN_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnP_PIPEp_IDLE_PATTERN value
+ * for packet-pipe pPipe on HSS port hPort. (n=hPort, p=pPipe)
+ */
+#define IX_NPE_A_MSSG_HSS_PKT_PIPE_IDLE_PATTERN_WRITE 0x55
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PKT_PIPE_RX_SIZE_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnP_PIPEp_RXSIZEB value for
+ * packet-pipe pPipe on HSS port hPort. (n=hPort, p=pPipe)
+ */
+#define IX_NPE_A_MSSG_HSS_PKT_PIPE_RX_SIZE_WRITE 0x56
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PKT_PIPE_MODE_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnP_PIPEp_MODE value for
+ * packet-pipe pPipe on HSS port hPort. (n=hPort, p=pPipe)
+ */
+#define IX_NPE_A_MSSG_HSS_PKT_PIPE_MODE_WRITE 0x57
+
+
+
+/* Queue Entry Masks */
+
+/*--------------------------------------------------------------------------
+ * ATM Descriptor Structure offsets
+ *--------------------------------------------------------------------------*/
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_STATUS_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Status field
+ *
+ * It is used for descriptor error reporting.
+ */
+#define IX_NPE_A_RXDESCRIPTOR_STATUS_OFFSET 0
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_VCID_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor VC ID field
+ *
+ * It is used to hold an identifier number for this VC
+ */
+#define IX_NPE_A_RXDESCRIPTOR_VCID_OFFSET 1
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_CURRMBUFSIZE_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Current Mbuf
+ * Size field
+ *
+ * Number of bytes the current mbuf data buffer can hold
+ */
+#define IX_NPE_A_RXDESCRIPTOR_CURRMBUFSIZE_OFFSET 2
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_ATMHEADER_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor ATM Header
+ */
+#define IX_NPE_A_RXDESCRIPTOR_ATMHEADER_OFFSET 4
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_CURRMBUFLEN_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Current MBuf length
+ *
+ *
+ * RX - Initialized to zero. The NPE updates this field as each cell is received and
+ * zeroes it with every new mbuf for chaining. Will not be bigger than currBbufSize.
+ */
+#define IX_NPE_A_RXDESCRIPTOR_CURRMBUFLEN_OFFSET 12
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_TIMELIMIT__OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Time Limit field
+ *
+ * Contains the Payload Reassembly Time Limit (used for aal0_xx only)
+ */
+#define IX_NPE_A_RXDESCRIPTOR_TIMELIMIT_OFFSET 14
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_PCURRMBUFF_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Current MBuf Pointer
+ *
+ * The current mbuf pointer of a chain of mbufs.
+ */
+#define IX_NPE_A_RXDESCRIPTOR_PCURRMBUFF_OFFSET 20
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_PCURRMBUFDATA_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Current MBuf Pointer
+ *
+ * Pointer to the next byte to be read or next free location to be written.
+ */
+#define IX_NPE_A_RXDESCRIPTOR_PCURRMBUFDATA_OFFSET 24
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_PNEXTMBUF_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Next MBuf Pointer
+ *
+ * Pointer to the next MBuf in a chain of MBufs.
+ */
+#define IX_NPE_A_RXDESCRIPTOR_PNEXTMBUF_OFFSET 28
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_TOTALLENGTH_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Total Length
+ *
+ * Total number of bytes written to the chain of MBufs by the NPE
+ */
+#define IX_NPE_A_RXDESCRIPTOR_TOTALLENGTH_OFFSET 32
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_AAL5CRCRESIDUE_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor AAL5 CRC Residue
+ *
+ * Current CRC value for a PDU
+ */
+#define IX_NPE_A_RXDESCRIPTOR_AAL5CRCRESIDUE_OFFSET 36
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_SIZE
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Size
+ *
+ * The size of the Receive descriptor
+ */
+#define IX_NPE_A_RXDESCRIPTOR_SIZE 40
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_PORT_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor Port
+ *
+ * Port identifier.
+ */
+#define IX_NPE_A_TXDESCRIPTOR_PORT_OFFSET 0
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_RSVD_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor RSVD
+ */
+#define IX_NPE_A_TXDESCRIPTOR_RSVD_OFFSET 1
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_CURRMBUFLEN_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor Current MBuf Length
+ *
+ * TX - Initialized by the XScale to the number of bytes in the current MBuf data buffer.
+ * The NPE decrements this field for every transmitted cell. Thus, when the NPE writes a
+ * descriptor the TxDone queue, this field will equal zero.
+ */
+#define IX_NPE_A_TXDESCRIPTOR_CURRMBUFLEN_OFFSET 2
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_ATMHEADER_OFFSET
+ * @brief ATM Descriptor structure offset for Transmit Descriptor ATM Header
+ */
+#define IX_NPE_A_TXDESCRIPTOR_ATMHEADER_OFFSET 4
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_PCURRMBUFF_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor Pointer to the current MBuf chain
+ */
+#define IX_NPE_A_TXDESCRIPTOR_PCURRMBUFF_OFFSET 8
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_PCURRMBUFDATA_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor Pointer to the current MBuf Data
+ *
+ * Pointer to the next byte to be read or next free location to be written.
+ */
+#define IX_NPE_A_TXDESCRIPTOR_PCURRMBUFDATA_OFFSET 12
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_PNEXTMBUF_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor Pointer to the Next MBuf chain
+ */
+#define IX_NPE_A_TXDESCRIPTOR_PNEXTMBUF_OFFSET 16
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_TOTALLENGTH_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor Total Length
+ *
+ * Total number of bytes written to the chain of MBufs by the NPE
+ */
+#define IX_NPE_A_TXDESCRIPTOR_TOTALLENGTH_OFFSET 20
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_AAL5CRCRESIDUE_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor AAL5 CRC Residue
+ *
+ * Current CRC value for a PDU
+ */
+#define IX_NPE_A_TXDESCRIPTOR_AAL5CRCRESIDUE_OFFSET 24
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_SIZE
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor Size
+ */
+#define IX_NPE_A_TXDESCRIPTOR_SIZE 28
+
+/**
+ * @def IX_NPE_A_CHAIN_DESC_COUNT_MAX
+ *
+ * @brief Maximum number of chained MBufs that can be chained together
+ */
+#define IX_NPE_A_CHAIN_DESC_COUNT_MAX 256
+
+/*
+ * Definition of the ATM cell header
+ *
+ * This would most conviently be defined as the bit field shown below.
+ * Endian portability prevents this, therefore a set of macros
+ * are defined to access the fields within the cell header assumed to
+ * be passed as a UINT32.
+ *
+ * Changes to field sizes or orders must be reflected in the offset
+ * definitions above.
+ *
+ * typedef struct
+ * {
+ * unsigned int gfc:4;
+ * unsigned int vpi:8;
+ * unsigned int vci:16;
+ * unsigned int pti:3;
+ * unsigned int clp:1;
+ * } IxNpeA_AtmCellHeader;
+ *
+ */
+
+/** Mask to acess GFC */
+#define GFC_MASK 0xf0000000
+
+/** return GFC from ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_GFC_GET( header ) \
+(((header) & GFC_MASK) >> 28)
+
+/** set GFC into ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_GFC_SET( header,gfc ) \
+do { \
+ (header) &= ~GFC_MASK; \
+ (header) |= (((gfc) << 28) & GFC_MASK); \
+} while(0)
+
+/** Mask to acess VPI */
+#define VPI_MASK 0x0ff00000
+
+/** return VPI from ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_VPI_GET( header ) \
+(((header) & VPI_MASK) >> 20)
+
+/** set VPI into ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_VPI_SET( header, vpi ) \
+do { \
+ (header) &= ~VPI_MASK; \
+ (header) |= (((vpi) << 20) & VPI_MASK); \
+} while(0)
+
+/** Mask to acess VCI */
+#define VCI_MASK 0x000ffff0
+
+/** return VCI from ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_VCI_GET( header ) \
+(((header) & VCI_MASK) >> 4)
+
+/** set VCI into ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_VCI_SET( header, vci ) \
+do { \
+ (header) &= ~VCI_MASK; \
+ (header) |= (((vci) << 4) & VCI_MASK); \
+} while(0)
+
+/** Mask to acess PTI */
+#define PTI_MASK 0x0000000e
+
+/** return PTI from ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_PTI_GET( header ) \
+(((header) & PTI_MASK) >> 1)
+
+/** set PTI into ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_PTI_SET( header, pti ) \
+do { \
+ (header) &= ~PTI_MASK; \
+ (header) |= (((pti) << 1) & PTI_MASK); \
+} while(0)
+
+/** Mask to acess CLP */
+#define CLP_MASK 0x00000001
+
+/** return CLP from ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_CLP_GET( header ) \
+((header) & CLP_MASK)
+
+/** set CLP into ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_CLP_SET( header, clp ) \
+do { \
+ (header) &= ~CLP_MASK; \
+ (header) |= ((clp) & CLP_MASK); \
+} while(0)
+
+
+/*
+* Definition of the Rx bitfield
+*
+* This would most conviently be defined as the bit field shown below.
+* Endian portability prevents this, therefore a set of macros
+* are defined to access the fields within the rxBitfield assumed to
+* be passed as a UINT32.
+*
+* Changes to field sizes or orders must be reflected in the offset
+* definitions above.
+*
+* Rx bitfield
+* struct
+* { IX_NPEA_RXBITFIELD(
+* unsigned int status:1,
+* unsigned int port:7,
+* unsigned int vcId:8,
+* unsigned int currMbufSize:16);
+* } rxBitField;
+*
+*/
+
+/** Mask to acess the rxBitField status */
+#define STATUS_MASK 0x80000000
+
+/** return the rxBitField status */
+#define IX_NPE_A_RXBITFIELD_STATUS_GET( rxbitfield ) \
+(((rxbitfield) & STATUS_MASK) >> 31)
+
+/** set the rxBitField status */
+#define IX_NPE_A_RXBITFIELD_STATUS_SET( rxbitfield, status ) \
+do { \
+ (rxbitfield) &= ~STATUS_MASK; \
+ (rxbitfield) |= (((status) << 31) & STATUS_MASK); \
+} while(0)
+
+/** Mask to acess the rxBitField port */
+#define PORT_MASK 0x7f000000
+
+/** return the rxBitField port */
+#define IX_NPE_A_RXBITFIELD_PORT_GET( rxbitfield ) \
+(((rxbitfield) & PORT_MASK) >> 24)
+
+/** set the rxBitField port */
+#define IX_NPE_A_RXBITFIELD_PORT_SET( rxbitfield, port ) \
+do { \
+ (rxbitfield) &= ~PORT_MASK; \
+ (rxbitfield) |= (((port) << 24) & PORT_MASK); \
+} while(0)
+
+/** Mask to acess the rxBitField vcId */
+#define VCID_MASK 0x00ff0000
+
+/** return the rxBitField vcId */
+#define IX_NPE_A_RXBITFIELD_VCID_GET( rxbitfield ) \
+(((rxbitfield) & VCID_MASK) >> 16)
+
+/** set the rxBitField vcId */
+#define IX_NPE_A_RXBITFIELD_VCID_SET( rxbitfield, vcid ) \
+do { \
+ (rxbitfield) &= ~VCID_MASK; \
+ (rxbitfield) |= (((vcid) << 16) & VCID_MASK); \
+} while(0)
+
+/** Mask to acess the rxBitField mbuf size */
+#define CURRMBUFSIZE_MASK 0x0000ffff
+
+/** return the rxBitField mbuf size */
+#define IX_NPE_A_RXBITFIELD_CURRMBUFSIZE_GET( rxbitfield ) \
+((rxbitfield) & CURRMBUFSIZE_MASK)
+
+/** set the rxBitField mbuf size */
+#define IX_NPE_A_RXBITFIELD_CURRMBUFSIZE_SET( rxbitfield, currmbufsize ) \
+do { \
+ (rxbitfield) &= ~CURRMBUFSIZE_MASK; \
+ (rxbitfield) |= ((currmbufsize) & CURRMBUFSIZE_MASK); \
+} while(0)
+
+
+
+/**
+ * @brief Tx Descriptor definition
+ */
+typedef struct
+{
+ UINT8 port; /**< Tx Port number */
+ UINT8 aalType; /**< AAL Type */
+ UINT16 currMbufLen; /**< mbuf length */
+ UINT32 atmCellHeader; /**< ATM cell header */
+ IX_OSAL_MBUF *pCurrMbuf; /**< pointer to mbuf */
+ unsigned char *pCurrMbufData; /**< Pointer to mbuf->dat */
+ IX_OSAL_MBUF *pNextMbuf; /**< Pointer to next mbuf */
+ UINT32 totalLen; /**< Total Length */
+ UINT32 aal5CrcResidue; /**< AAL5 CRC Residue */
+} IxNpeA_TxAtmVc;
+
+/* Changes to field sizes or orders must be reflected in the offset
+ * definitions above. */
+
+
+
+
+/**
+ * @brief Rx Descriptor definition
+ */
+typedef struct
+{
+ UINT32 rxBitField; /**< Recieved bit field */
+ UINT32 atmCellHeader; /**< ATM Cell Header */
+ UINT32 rsvdWord0; /**< Reserved field */
+ UINT16 currMbufLen; /**< Mbuf Length */
+ UINT8 timeLimit; /**< Payload Reassembly timeLimit (used for aal0_xx only) */
+ UINT8 rsvdByte0; /**< Reserved field */
+ UINT32 rsvdWord1; /**< Reserved field */
+ IX_OSAL_MBUF *pCurrMbuf; /**< Pointer to current mbuf */
+ unsigned char *pCurrMbufData; /**< Pointer to current mbuf->data */
+ IX_OSAL_MBUF *pNextMbuf; /**< Pointer to next mbuf */
+ UINT32 totalLen; /**< Total Length */
+ UINT32 aal5CrcResidue; /**< AAL5 CRC Residue */
+} IxNpeA_RxAtmVc;
+
+
+/**
+ * @brief NPE-A AAL Type
+ */
+typedef enum
+{
+ IX_NPE_A_AAL_TYPE_INVALID = 0, /**< Invalid AAL type */
+ IX_NPE_A_AAL_TYPE_0_48 = 0x1, /**< AAL0 - 48 byte */
+ IX_NPE_A_AAL_TYPE_0_52 = 0x2, /**< AAL0 - 52 byte */
+ IX_NPE_A_AAL_TYPE_5 = 0x5, /**< AAL5 */
+ IX_NPE_A_AAL_TYPE_OAM = 0xF /**< OAM */
+} IxNpeA_AalType;
+
+/**
+ * @brief NPE-A Payload format 52-bytes & 48-bytes
+ */
+typedef enum
+{
+ IX_NPE_A_52_BYTE_PAYLOAD = 0, /**< 52 byte payload */
+ IX_NPE_A_48_BYTE_PAYLOAD /**< 48 byte payload */
+} IxNpeA_PayloadFormat;
+
+/**
+ * @brief HSS Packetized NpePacket Descriptor Structure
+ */
+typedef struct
+{
+ UINT8 status; /**< Status of the packet passed to the client */
+ UINT8 errorCount; /**< Number of errors */
+ UINT8 chainCount; /**< Mbuf chain count e.g. 0 - No mbuf chain */
+ UINT8 rsvdByte0; /**< Reserved byte to make the descriptor word align */
+
+ UINT16 packetLength; /**< Packet Length */
+ UINT16 rsvdShort0; /**< Reserved short to make the descriptor a word align */
+
+ IX_OSAL_MBUF *pRootMbuf; /**< Pointer to Root mbuf */
+ IX_OSAL_MBUF *pNextMbuf; /**< Pointer to next mbuf */
+ UINT8 *pMbufData; /**< Pointer to the current mbuf->data */
+ UINT32 mbufLength; /**< Current mbuf length */
+
+} IxNpeA_NpePacketDescriptor;
+
+
+#endif
+/**
+ *@}
+ */
+
+#endif /* __doxygen_HIDE */
diff --git a/cpu/ixp/npe/include/IxNpeDl.h b/cpu/ixp/npe/include/IxNpeDl.h
new file mode 100644
index 0000000..86f69f4
--- /dev/null
+++ b/cpu/ixp/npe/include/IxNpeDl.h
@@ -0,0 +1,980 @@
+/**
+ * @file IxNpeDl.h
+ *
+ * @date 14 December 2001
+
+ * @brief This file contains the public API of the IXP400 NPE Downloader
+ * component.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeDl IXP400 NPE-Downloader (IxNpeDl) API
+ *
+ * @brief The Public API for the IXP400 NPE Downloader
+ *
+ * @{
+ */
+
+#ifndef IXNPEDL_H
+#define IXNPEDL_H
+
+/*
+ * Put the user defined include files required
+ */
+#include "IxOsalTypes.h"
+#include "IxNpeMicrocode.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+/**
+ * @def IX_NPEDL_PARAM_ERR
+ *
+ * @brief NpeDl function return value for a parameter error
+ */
+#define IX_NPEDL_PARAM_ERR 2
+
+/**
+ * @def IX_NPEDL_RESOURCE_ERR
+ *
+ * @brief NpeDl function return value for a resource error
+ */
+#define IX_NPEDL_RESOURCE_ERR 3
+
+/**
+ * @def IX_NPEDL_CRITICAL_NPE_ERR
+ *
+ * @brief NpeDl function return value for a Critical NPE error occuring during
+ download. Assume NPE is left in unstable condition if this value is
+ returned or NPE is hang / halt.
+ */
+#define IX_NPEDL_CRITICAL_NPE_ERR 4
+
+/**
+ * @def IX_NPEDL_CRITICAL_MICROCODE_ERR
+ *
+ * @brief NpeDl function return value for a Critical Microcode error
+ * discovered during download. Assume NPE is left in unstable condition
+ * if this value is returned.
+ */
+#define IX_NPEDL_CRITICAL_MICROCODE_ERR 5
+
+/**
+ * @def IX_NPEDL_DEVICE_ERR
+ *
+ * @brief NpeDl function return value when image being downloaded
+ * is not meant for the device in use
+ */
+#define IX_NPEDL_DEVICE_ERR 6
+
+/**
+ * @defgroup NPEImageID IXP400 NPE Image ID Definition
+ *
+ * @ingroup IxNpeDl
+ *
+ * @brief Definition of NPE Image ID to be passed to ixNpeDlNpeInitAndStart()
+ * as input of type UINT32 which has the following fields format:
+ *
+ * Field [Bit Location] <BR>
+ * -------------------- <BR>
+ * Device ID [31 - 28] <BR>
+ * NPE ID [27 - 24] <BR>
+ * NPE Functionality ID [23 - 16] <BR>
+ * Major Release Number [15 - 8] <BR>
+ * Minor Release Number [7 - 0] <BR>
+ *
+ *
+ * @{
+ */
+
+/**
+ * @def IX_NPEDL_NPEIMAGE_FIELD_MASK
+ *
+ * @brief Mask for NPE Image ID's Field
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define IX_NPEDL_NPEIMAGE_FIELD_MASK 0xff
+
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEID_MASK
+ *
+ * @brief Mask for NPE Image NPE ID's Field
+ *
+ */
+#define IX_NPEDL_NPEIMAGE_NPEID_MASK 0xf
+
+/**
+ * @def IX_NPEDL_NPEIMAGE_DEVICEID_MASK
+ *
+ * @brief Mask for NPE Image Device ID's Field
+ *
+ */
+#define IX_NPEDL_NPEIMAGE_DEVICEID_MASK 0xf
+
+/**
+ * @def IX_NPEDL_NPEIMAGE_BIT_LOC_NPEID
+ *
+ * @brief Location of NPE ID field in term of bit.
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define IX_NPEDL_NPEIMAGE_BIT_LOC_NPEID 24
+
+/**
+ * @def IX_NPEDL_NPEIMAGE_BIT_LOC_FUNCTIONALITYID
+ *
+ * @brief Location of Functionality ID field in term of bit.
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define IX_NPEDL_NPEIMAGE_BIT_LOC_FUNCTIONALITYID 16
+
+/**
+ * @def IX_NPEDL_NPEIMAGE_BIT_LOC_MAJOR
+ *
+ * @brief Location of Major Release Number field in term of bit.
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define IX_NPEDL_NPEIMAGE_BIT_LOC_MAJOR 8
+
+/**
+ * @def IX_NPEDL_NPEIMAGE_BIT_LOC_MINOR
+ *
+ * @brief Location of Minor Release Number field in term of bit.
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define IX_NPEDL_NPEIMAGE_BIT_LOC_MINOR 0
+
+/**
+ * @} addtogroup NPEImageID
+ */
+
+/**
+ * @def ixNpeDlMicrocodeImageOverride(x)
+ *
+ * @brief Map old terminology that uses term "image" to new term
+ * "image library"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define ixNpeDlMicrocodeImageOverride(x) ixNpeDlMicrocodeImageLibraryOverride(x)
+
+/**
+ * @def IxNpeDlVersionId
+ *
+ * @brief Map old terminology that uses term "version" to new term
+ * "image"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define IxNpeDlVersionId IxNpeDlImageId
+
+/**
+ * @def ixNpeDlVersionDownload
+ *
+ * @brief Map old terminology that uses term "version" to new term
+ * "image"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define ixNpeDlVersionDownload(x,y) ixNpeDlImageDownload(x,y)
+
+/**
+ * @def ixNpeDlAvailableVersionsCountGet
+ *
+ * @brief Map old terminology that uses term "version" to new term
+ * "image"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define ixNpeDlAvailableVersionsCountGet(x) ixNpeDlAvailableImagesCountGet(x)
+
+/**
+ * @def ixNpeDlAvailableVersionsListGet
+ *
+ * @brief Map old terminology that uses term "version" to new term
+ * "image"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define ixNpeDlAvailableVersionsListGet(x,y) ixNpeDlAvailableImagesListGet(x,y)
+
+ /**
+ * @def ixNpeDlLoadedVersionGet
+ *
+ * @brief Map old terminology that uses term "version" to new term
+ * "image"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define ixNpeDlLoadedVersionGet(x,y) ixNpeDlLoadedImageGet(x,y)
+
+ /**
+ * @def clientImage
+ *
+ * @brief Map old terminology that uses term "image" to new term
+ * "image library"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define clientImage clientImageLibrary
+
+ /**
+ * @def versionIdPtr
+ *
+ * @brief Map old terminology that uses term "version" to new term
+ * "image"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define versionIdPtr imageIdPtr
+
+ /**
+ * @def numVersionsPtr
+ *
+ * @brief Map old terminology that uses term "version" to new term
+ * "image"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define numVersionsPtr numImagesPtr
+
+/**
+ * @def versionIdListPtr
+ *
+ * @brief Map old terminology that uses term "version" to new term
+ * "image"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define versionIdListPtr imageIdListPtr
+
+/**
+ * @def IxNpeDlBuildId
+ *
+ * @brief Map old terminology that uses term "buildId" to new term
+ * "functionalityId"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define IxNpeDlBuildId IxNpeDlFunctionalityId
+
+/**
+ * @def buildId
+ *
+ * @brief Map old terminology that uses term "buildId" to new term
+ * "functionalityId"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define buildId functionalityId
+
+/**
+ * @def IX_NPEDL_MicrocodeImage
+ *
+ * @brief Map old terminology that uses term "image" to new term
+ * "image library"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define IX_NPEDL_MicrocodeImage IX_NPEDL_MicrocodeImageLibrary
+
+/*
+ * Typedefs
+ */
+
+/**
+ * @typedef IxNpeDlFunctionalityId
+ * @brief Used to make up Functionality ID field of Image Id
+ *
+ * @warning <b>THIS typedef HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+typedef UINT8 IxNpeDlFunctionalityId;
+
+/**
+ * @typedef IxNpeDlMajor
+ * @brief Used to make up Major Release field of Image Id
+ *
+ * @warning <b>THIS typedef HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+typedef UINT8 IxNpeDlMajor;
+
+/**
+ * @typedef IxNpeDlMinor
+ * @brief Used to make up Minor Revision field of Image Id
+ *
+ * @warning <b>THIS typedef HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+typedef UINT8 IxNpeDlMinor;
+
+/*
+ * Enums
+ */
+
+/**
+ * @brief NpeId numbers to identify NPE A, B or C
+ * @note In this context, for IXP425 Silicon (B0):<br>
+ * - NPE-A has HDLC, HSS, AAL and UTOPIA Coprocessors.<br>
+ * - NPE-B has Ethernet Coprocessor.<br>
+ * - NPE-C has Ethernet, AES, DES and HASH Coprocessors.<br>
+ * - IXP400 Product Line have different combinations of coprocessors.
+ */
+typedef enum
+{
+ IX_NPEDL_NPEID_NPEA = 0, /**< Identifies NPE A */
+ IX_NPEDL_NPEID_NPEB, /**< Identifies NPE B */
+ IX_NPEDL_NPEID_NPEC, /**< Identifies NPE C */
+ IX_NPEDL_NPEID_MAX /**< Total Number of NPEs */
+} IxNpeDlNpeId;
+
+/*
+ * Structs
+ */
+
+/**
+ * @brief Image Id to identify each image contained in an image library
+ *
+ * @warning <b>THIS struct HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+typedef struct
+{
+ IxNpeDlNpeId npeId; /**< NPE ID */
+ IxNpeDlFunctionalityId functionalityId; /**< Build ID indicates functionality of image */
+ IxNpeDlMajor major; /**< Major Release Number */
+ IxNpeDlMinor minor; /**< Minor Revision Number */
+} IxNpeDlImageId;
+
+/*
+ * Prototypes for interface functions
+ */
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlNpeInitAndStart (UINT32 imageId)
+ *
+ * @brief Stop, reset, download microcode (firmware) and finally start NPE.
+ *
+ * @param imageId UINT32 [in] - Id of the microcode image to download.
+ *
+ * This function locates the image specified by the <i>imageId</i> parameter
+ * from the default microcode image library which is included internally by
+ * this component.
+ * It then stops and resets the NPE, loads the firmware image onto the NPE,
+ * and then restarts the NPE.
+ *
+ * @note A list of valid image IDs is included in this header file.
+ * See #defines with prefix IX_NPEDL_NPEIMAGE_...
+ *
+ * @note This function, along with @ref ixNpeDlCustomImageNpeInitAndStart
+ * and @ref ixNpeDlLoadedImageFunctionalityGet, supercedes the following
+ * functions which are deprecated and will be removed completely in a
+ * future release:
+ * - @ref ixNpeDlImageDownload
+ * - @ref ixNpeDlAvailableImagesCountGet
+ * - @ref ixNpeDlAvailableImagesListGet
+ * - @ref ixNpeDlLatestImageGet
+ * - @ref ixNpeDlLoadedImageGet
+ * - @ref ixNpeDlMicrocodeImageLibraryOverride
+ * - @ref ixNpeDlNpeExecutionStop
+ * - @ref ixNpeDlNpeStopAndReset
+ * - @ref ixNpeDlNpeExecutionStart
+ *
+ * @pre
+ * - The Client is responsible for ensuring mutual access to the NPE.
+ * @post
+ * - The NPE Instruction Pipeline will be cleared if State Information
+ * has been downloaded.
+ * - If the download fails with a critical error, the NPE may
+ * be left in an ususable state.
+ * @return
+ * - IX_SUCCESS if the download was successful;
+ * - IX_NPEDL_PARAM_ERR if a parameter error occured
+ * - IX_NPEDL_CRITICAL_NPE_ERR if a critical NPE error occured during
+ * download
+ * - IX_NPEDL_CRITICAL_MICROCODE_ERR if a critical microcode error
+ * occured during download
+ * - IX_NPEDL_DEVICE_ERR if the image being loaded is not meant for
+ * the device currently running.
+ * - IX_FAIL if NPE is not available or image is failed to be located.
+ * A warning is issued if the NPE is not present.
+ */
+PUBLIC IX_STATUS
+ixNpeDlNpeInitAndStart (UINT32 npeImageId);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlCustomImageNpeInitAndStart (UINT32 *imageLibrary,
+ UINT32 imageId)
+ *
+ * @brief Stop, reset, download microcode (firmware) and finally start NPE
+ *
+ * @param imageId UINT32 [in] - Id of the microcode image to download.
+ *
+ * This function locates the image specified by the <i>imageId</i> parameter
+ * from the specified microcode image library which is pointed to by the
+ * <i>imageLibrary</i> parameter.
+ * It then stops and resets the NPE, loads the firmware image onto the NPE,
+ * and then restarts the NPE.
+ *
+ * This is a facility for users who wish to use an image from an external
+ * library of NPE firmware images. To use a standard image from the
+ * built-in library, see @ref ixNpeDlNpeInitAndStart instead.
+ *
+ * @note A list of valid image IDs is included in this header file.
+ * See #defines with prefix IX_NPEDL_NPEIMAGE_...
+ *
+ * @note This function, along with @ref ixNpeDlNpeInitAndStart
+ * and @ref ixNpeDlLoadedImageFunctionalityGet, supercedes the following
+ * functions which are deprecated and will be removed completely in a
+ * future release:
+ * - @ref ixNpeDlImageDownload
+ * - @ref ixNpeDlAvailableImagesCountGet
+ * - @ref ixNpeDlAvailableImagesListGet
+ * - @ref ixNpeDlLatestImageGet
+ * - @ref ixNpeDlLoadedImageGet
+ * - @ref ixNpeDlMicrocodeImageLibraryOverride
+ * - @ref ixNpeDlNpeExecutionStop
+ * - @ref ixNpeDlNpeStopAndReset
+ * - @ref ixNpeDlNpeExecutionStart
+ *
+ * @pre
+ * - The Client is responsible for ensuring mutual access to the NPE.
+ * - The image library supplied must be in the correct format for use
+ * by the NPE Downloader (IxNpeDl) component. Details of the library
+ * format are contained in the Functional Specification document for
+ * IxNpeDl.
+ * @post
+ * - The NPE Instruction Pipeline will be cleared if State Information
+ * has been downloaded.
+ * - If the download fails with a critical error, the NPE may
+ * be left in an ususable state.
+ * @return
+ * - IX_SUCCESS if the download was successful;
+ * - IX_NPEDL_PARAM_ERR if a parameter error occured
+ * - IX_NPEDL_CRITICAL_NPE_ERR if a critical NPE error occured during
+ * download
+ * - IX_NPEDL_CRITICAL_MICROCODE_ERR if a critical microcode error
+ * occured during download
+ * - IX_NPEDL_DEVICE_ERR if the image being loaded is not meant for
+ * the device currently running.
+ * - IX_FAIL if NPE is not available or image is failed to be located.
+ * A warning is issued if the NPE is not present.
+ */
+PUBLIC IX_STATUS
+ixNpeDlCustomImageNpeInitAndStart (UINT32 *imageLibrary,
+ UINT32 npeImageId);
+
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlLoadedImageFunctionalityGet (IxNpeDlNpeId npeId,
+ UINT8 *functionalityId)
+ *
+ * @brief Gets the functionality of the image last loaded on a particular NPE
+ *
+ * @param npeId @ref IxNpeDlNpeId [in] - Id of the target NPE.
+ * @param functionalityId UINT8* [out] - the functionality ID of the image
+ * last loaded on the NPE.
+ *
+ * This function retrieves the functionality ID of the image most recently
+ * downloaded successfully to the specified NPE. If the NPE does not contain
+ * a valid image, this function returns a FAIL status.
+ *
+ * @warning This function is not intended for general use, as a knowledge of
+ * how to interpret the functionality ID is required. As such, this function
+ * should only be used by other Access Layer components of the IXP400 Software
+ * Release.
+ *
+ * @pre
+ *
+ * @post
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_NPEDL_PARAM_ERR if a parameter error occured
+ * - IX_FAIL if the NPE does not have a valid image loaded
+ */
+PUBLIC IX_STATUS
+ixNpeDlLoadedImageFunctionalityGet (IxNpeDlNpeId npeId,
+ UINT8 *functionalityId);
+
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn IX_STATUS ixNpeDlMicrocodeImageLibraryOverride (UINT32 *clientImageLibrary)
+ *
+ * @brief This instructs NPE Downloader to use client-supplied microcode image library.
+ *
+ * @param clientImageLibrary UINT32* [in] - Pointer to the client-supplied
+ * NPE microcode image library
+ *
+ * This function sets NPE Downloader to use a client-supplied microcode image library
+ * instead of the standard image library which is included by the NPE Downloader.
+ * <b>This function is provided mainly for increased testability and should not
+ * be used in normal circumstances.</b> When not used, NPE Downloader will use
+ * a "built-in" image library, local to this component, which should always contain the
+ * latest microcode for the NPEs.
+ *
+ * @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlCustomImageNpeInitAndStart.
+ *
+ * @pre
+ * - <i>clientImageLibrary</i> should point to a microcode image library valid for use
+ * by the NPE Downloader component.
+ *
+ * @post
+ * - the client-supplied image library will be used for all subsequent operations
+ * performed by the NPE Downloader
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_NPEDL_PARAM_ERR if a parameter error occured
+ * - IX_FAIL if the client-supplied image library did not contain a valid signature
+ */
+PUBLIC IX_STATUS
+ixNpeDlMicrocodeImageLibraryOverride (UINT32 *clientImageLibrary);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlImageDownload (IxNpeDlImageId *imageIdPtr,
+ BOOL verify)
+ *
+ * @brief Stop, reset, download microcode and finally start NPE.
+ *
+ * @param imageIdPtr @ref IxNpeDlImageId* [in] - Pointer to Id of the microcode
+ * image to download.
+ * @param verify BOOL [in] - ON/OFF option to verify the download. If ON
+ * (verify == TRUE), the Downloader will read back
+ * each word written to the NPE registers to
+ * ensure the download operation was successful.
+ *
+ * Using the <i>imageIdPtr</i>, this function locates a particular image of
+ * microcode in the microcode image library in memory, and downloads the microcode
+ * to a particular NPE.
+ *
+ * @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
+ *
+ * @pre
+ * - The Client is responsible for ensuring mutual access to the NPE.
+ * - The Client should use ixNpeDlLatestImageGet() to obtain the latest
+ * version of the image before attempting download.
+ * @post
+ * - The NPE Instruction Pipeline will be cleared if State Information
+ * has been downloaded.
+ * - If the download fails with a critical error, the NPE may
+ * be left in an ususable state.
+ * @return
+ * - IX_SUCCESS if the download was successful;
+ * - IX_NPEDL_PARAM_ERR if a parameter error occured
+ * - IX_NPEDL_CRITICAL_NPE_ERR if a critical NPE error occured during
+ * download
+ * - IX_PARAM_CRITICAL_MICROCODE_ERR if a critical microcode error
+ * occured during download
+ * - IX_FAIL if NPE is not available or image is failed to be located.
+ * A warning is issued if the NPE is not present.
+ */
+PUBLIC IX_STATUS
+ixNpeDlImageDownload (IxNpeDlImageId *imageIdPtr,
+ BOOL verify);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlAvailableImagesCountGet (UINT32 *numImagesPtr)
+ *
+ * @brief Get the number of Images available in a microcode image library
+ *
+ * @param numImagesPtr UINT32* [out] - A pointer to the number of images in
+ * the image library.
+ *
+ * Gets the number of images available in the microcode image library.
+ * Then returns this in a variable pointed to by <i>numImagesPtr</i>.
+ *
+ * @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
+ *
+ * @pre
+ * - The Client should declare the variable to which numImagesPtr points
+ *
+ * @post
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_NPEDL_PARAM_ERR if a parameter error occured
+ * - IX_FAIL otherwise
+ */
+PUBLIC IX_STATUS
+ixNpeDlAvailableImagesCountGet (UINT32 *numImagesPtr);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlAvailableImagesListGet (IxNpeDlImageId *imageIdListPtr,
+ UINT32 *listSizePtr)
+ *
+ * @brief Get a list of the images available in a microcode image library
+ *
+ * @param imageIdListPtr @ref IxNpeDlImageId* [out] - Array to contain list of
+ * image Ids (memory
+ * allocated by Client).
+ * @param listSizePtr UINT32* [inout] - As an input, this param should point
+ * to the max number of Ids the
+ * <i>imageIdListPtr</i> array can
+ * hold. NpeDl will replace the input
+ * value of this parameter with the
+ * number of image Ids actually filled
+ * into the array before returning.
+ *
+ * Finds list of images available in the microcode image library.
+ * Fills these into the array pointed to by <i>imageIdListPtr</i>
+ *
+ * @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
+ *
+ * @pre
+ * - The Client should declare the variable to which numImagesPtr points
+ * - The Client should create an array (<i>imageIdListPtr</i>) large
+ * enough to contain all the image Ids in the image library
+ *
+ * @post
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_NPEDL_PARAM_ERR if a parameter error occured
+ * - IX_FAIL otherwise
+ */
+PUBLIC IX_STATUS
+ixNpeDlAvailableImagesListGet (IxNpeDlImageId *imageIdListPtr,
+ UINT32 *listSizePtr);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlLoadedImageGet (IxNpeDlNpeId npeId,
+ IxNpeDlImageId *imageIdPtr)
+ *
+ * @brief Gets the Id of the image currently loaded on a particular NPE
+ *
+ * @param npeId @ref IxNpeDlNpeId [in] - Id of the target NPE.
+ * @param imageIdPtr @ref IxNpeDlImageId* [out] - Pointer to the where the
+ * image id should be stored.
+ *
+ * If an image of microcode was previously downloaded successfully to the NPE
+ * by NPE Downloader, this function returns in <i>imageIdPtr</i> the image
+ * Id of that image loaded on the NPE.
+ *
+ * @pre
+ * - The Client has allocated memory to the <i>imageIdPtr</i> pointer.
+ *
+ * @post
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_NPEDL_PARAM_ERR if a parameter error occured
+ * - IX_FAIL if the NPE doesn't currently have a image loaded
+ */
+PUBLIC IX_STATUS
+ixNpeDlLoadedImageGet (IxNpeDlNpeId npeId,
+ IxNpeDlImageId *imageIdPtr);
+
+/**
+ * @fn PUBLIC IX_STATUS ixNpeDlLatestImageGet (IxNpeDlNpeId npeId, IxNpeDlFunctionalityId
+ functionalityId, IxNpeDlImageId *imageIdPtr)
+ *
+ * @brief This instructs NPE Downloader to get Id of the latest version for an
+ * image that is specified by the client.
+ *
+ * @param npeId @ref IxNpeDlNpeId [in] - Id of the target NPE.
+ * @param functionalityId @ref IxNpeDlFunctionalityId [in] - functionality of the image
+ * @param imageIdPtr @ref IxNpeDlImageId* [out] - Pointer to the where the
+ * image id should be stored.
+ *
+ * This function sets NPE Downloader to return the id of the latest version for
+ * image. The user will select the image by providing a particular NPE
+ * (specifying <i>npeId</i>) with particular functionality (specifying
+ * <i>FunctionalityId</i>). The most recent version available as determined by the
+ * highest Major and Minor revision numbers is returned in <i>imageIdPtr</i>.
+ *
+ * @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_NPEDL_PARAM_ERR if a parameter error occured
+ * - IX_FAIL otherwise
+ */
+PUBLIC IX_STATUS
+ixNpeDlLatestImageGet (IxNpeDlNpeId npeId,
+ IxNpeDlFunctionalityId functionalityId,
+ IxNpeDlImageId *imageIdPtr);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlNpeStopAndReset (IxNpeDlNpeId npeId)
+ *
+ * @brief Stops and Resets an NPE
+ *
+ * @param npeId @ref IxNpeDlNpeId [in] - Id of the target NPE.
+ *
+ * This function performs a soft NPE reset by writing reset values to
+ * particular NPE registers. Note that this does not reset NPE co-processors.
+ * This implicitly stops NPE code execution before resetting the NPE.
+ *
+ * @note It is no longer necessary to call this function before downloading
+ * a new image to the NPE. It is left on the API only to allow greater control
+ * of NPE execution if required. Where appropriate, use @ref ixNpeDlNpeInitAndStart
+ * or @ref ixNpeDlCustomImageNpeInitAndStart instead.
+ *
+ * @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
+ *
+ * @pre
+ * - The Client is responsible for ensuring mutual access to the NPE.
+ *
+ * @post
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_NPEDL_PARAM_ERR if a parameter error occured
+ * - IX_FAIL otherwise
+ * - IX_NPEDL_CRITICAL_NPE_ERR failed to reset NPE due to timeout error.
+ * Timeout error could happen if NPE hang
+ */
+PUBLIC IX_STATUS
+ixNpeDlNpeStopAndReset (IxNpeDlNpeId npeId);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlNpeExecutionStart (IxNpeDlNpeId npeId)
+ *
+ * @brief Starts code execution on a NPE
+ *
+ * @param npeId @ref IxNpeDlNpeId [in] - Id of the target NPE
+ *
+ * Starts execution of code on a particular NPE. A client would typically use
+ * this after a download to NPE is performed, to start/restart code execution
+ * on the NPE.
+ *
+ * @note It is no longer necessary to call this function after downloading
+ * a new image to the NPE. It is left on the API only to allow greater control
+ * of NPE execution if required. Where appropriate, use @ref ixNpeDlNpeInitAndStart
+ * or @ref ixNpeDlCustomImageNpeInitAndStart instead.
+ *
+ * @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
+ *
+ * @pre
+ * - The Client is responsible for ensuring mutual access to the NPE.
+ * - Note that this function does not set the NPE Next Program Counter
+ * (NextPC), so it should be set beforehand if required by downloading
+ * appropriate State Information (using ixNpeDlVersionDownload()).
+ *
+ * @post
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_NPEDL_PARAM_ERR if a parameter error occured
+ * - IX_FAIL otherwise
+ */
+PUBLIC IX_STATUS
+ixNpeDlNpeExecutionStart (IxNpeDlNpeId npeId);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlNpeExecutionStop (IxNpeDlNpeId npeId)
+ *
+ * @brief Stops code execution on a NPE
+ *
+ * @param npeId @ref IxNpeDlNpeId [in] - Id of the target NPE
+ *
+ * Stops execution of code on a particular NPE. This would typically be used
+ * by a client before a download to NPE is performed, to stop code execution on
+ * an NPE, unless ixNpeDlNpeStopAndReset() is used instead. Unlike
+ * ixNpeDlNpeStopAndReset(), this function only halts the NPE and leaves
+ * all registers and settings intact. This is useful, for example, between
+ * stages of a multi-stage download, to stop the NPE prior to downloading the
+ * next image while leaving the current state of the NPE intact..
+ *
+ * @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ * It will be removed in a future release.
+ * See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
+ *
+ * @pre
+ * - The Client is responsible for ensuring mutual access to the NPE.
+ *
+ * @post
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_NPEDL_PARAM_ERR if a parameter error occured
+ * - IX_FAIL otherwise
+ */
+PUBLIC IX_STATUS
+ixNpeDlNpeExecutionStop (IxNpeDlNpeId npeId);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlUnload (void)
+ *
+ * @brief This function will uninitialise the IxNpeDl component.
+ *
+ * This function will uninitialise the IxNpeDl component. It should only be
+ * called once, and only if the IxNpeDl component has already been initialised by
+ * calling any of the following functions:
+ * - @ref ixNpeDlNpeInitAndStart
+ * - @ref ixNpeDlCustomImageNpeInitAndStart
+ * - @ref ixNpeDlImageDownload (deprecated)
+ * - @ref ixNpeDlNpeStopAndReset (deprecated)
+ * - @ref ixNpeDlNpeExecutionStop (deprecated)
+ * - @ref ixNpeDlNpeExecutionStart (deprecated)
+ *
+ * If possible, this function should be called before a soft reboot or unloading
+ * a kernel module to perform any clean up operations required for IxNpeDl.
+ *
+ * The following actions will be performed by this function:
+ * - Unmapping of any kernel memory mapped by IxNpeDl
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_FAIL otherwise
+ */
+
+PUBLIC IX_STATUS
+ixNpeDlUnload (void);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC void ixNpeDlStatsShow (void)
+ *
+ * @brief This function will display run-time statistics from the IxNpeDl
+ * component
+ *
+ * @return none
+ */
+PUBLIC void
+ixNpeDlStatsShow (void);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC void ixNpeDlStatsReset (void)
+ *
+ * @brief This function will reset the statistics of the IxNpeDl component
+ *
+ * @return none
+ */
+PUBLIC void
+ixNpeDlStatsReset (void);
+
+#endif /* IXNPEDL_H */
+
+/**
+ * @} defgroup IxNpeDl
+ */
+
+
diff --git a/cpu/ixp/npe/include/IxNpeDlImageMgr_p.h b/cpu/ixp/npe/include/IxNpeDlImageMgr_p.h
new file mode 100644
index 0000000..622f879
--- /dev/null
+++ b/cpu/ixp/npe/include/IxNpeDlImageMgr_p.h
@@ -0,0 +1,363 @@
+/**
+ * @file IxNpeDlImageMgr_p.h
+ *
+ * @author Intel Corporation
+ * @date 14 December 2001
+
+ * @brief This file contains the private API for the ImageMgr module
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeDlImageMgr_p IxNpeDlImageMgr_p
+ *
+ * @brief The private API for the IxNpeDl ImageMgr module
+ *
+ * @{
+ */
+
+#ifndef IXNPEDLIMAGEMGR_P_H
+#define IXNPEDLIMAGEMGR_P_H
+
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxNpeDl.h"
+#include "IxOsalTypes.h"
+
+
+/*
+ * #defines and macros
+ */
+
+/**
+ * @def IX_NPEDL_IMAGEMGR_SIGNATURE
+ *
+ * @brief Signature found as 1st word in a microcode image library
+ */
+#define IX_NPEDL_IMAGEMGR_SIGNATURE 0xDEADBEEF
+
+/**
+ * @def IX_NPEDL_IMAGEMGR_END_OF_HEADER
+ *
+ * @brief Marks end of header in a microcode image library
+ */
+#define IX_NPEDL_IMAGEMGR_END_OF_HEADER 0xFFFFFFFF
+
+/**
+ * @def IX_NPEDL_IMAGEID_NPEID_OFFSET
+ *
+ * @brief Offset from LSB of NPE ID field in Image ID
+ */
+#define IX_NPEDL_IMAGEID_NPEID_OFFSET 24
+
+/**
+ * @def IX_NPEDL_IMAGEID_DEVICEID_OFFSET
+ *
+ * @brief Offset from LSB of Device ID field in Image ID
+ */
+#define IX_NPEDL_IMAGEID_DEVICEID_OFFSET 28
+
+/**
+ * @def IX_NPEDL_IMAGEID_FUNCTIONID_OFFSET
+ *
+ * @brief Offset from LSB of Functionality ID field in Image ID
+ */
+#define IX_NPEDL_IMAGEID_FUNCTIONID_OFFSET 16
+
+/**
+ * @def IX_NPEDL_IMAGEID_MAJOR_OFFSET
+ *
+ * @brief Offset from LSB of Major revision field in Image ID
+ */
+#define IX_NPEDL_IMAGEID_MAJOR_OFFSET 8
+
+/**
+ * @def IX_NPEDL_IMAGEID_MINOR_OFFSET
+ *
+ * @brief Offset from LSB of Minor revision field in Image ID
+ */
+#define IX_NPEDL_IMAGEID_MINOR_OFFSET 0
+
+
+/**
+ * @def IX_NPEDL_NPEID_FROM_IMAGEID_GET
+ *
+ * @brief Macro to extract NPE ID field from Image ID
+ */
+#define IX_NPEDL_NPEID_FROM_IMAGEID_GET(imageId) \
+ (((imageId) >> IX_NPEDL_IMAGEID_NPEID_OFFSET) & \
+ IX_NPEDL_NPEIMAGE_NPEID_MASK)
+
+/**
+ * @def IX_NPEDL_DEVICEID_FROM_IMAGEID_GET
+ *
+ * @brief Macro to extract NPE ID field from Image ID
+ */
+#define IX_NPEDL_DEVICEID_FROM_IMAGEID_GET(imageId) \
+ (((imageId) >> IX_NPEDL_IMAGEID_DEVICEID_OFFSET) & \
+ IX_NPEDL_NPEIMAGE_DEVICEID_MASK)
+
+/**
+ * @def IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET
+ *
+ * @brief Macro to extract Functionality ID field from Image ID
+ */
+#define IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId) \
+ (((imageId) >> IX_NPEDL_IMAGEID_FUNCTIONID_OFFSET) & \
+ IX_NPEDL_NPEIMAGE_FIELD_MASK)
+
+/**
+ * @def IX_NPEDL_MAJOR_FROM_IMAGEID_GET
+ *
+ * @brief Macro to extract Major revision field from Image ID
+ */
+#define IX_NPEDL_MAJOR_FROM_IMAGEID_GET(imageId) \
+ (((imageId) >> IX_NPEDL_IMAGEID_MAJOR_OFFSET) & \
+ IX_NPEDL_NPEIMAGE_FIELD_MASK)
+
+/**
+ * @def IX_NPEDL_MINOR_FROM_IMAGEID_GET
+ *
+ * @brief Macro to extract Minor revision field from Image ID
+ */
+#define IX_NPEDL_MINOR_FROM_IMAGEID_GET(imageId) \
+ (((imageId) >> IX_NPEDL_IMAGEID_MINOR_OFFSET) & \
+ IX_NPEDL_NPEIMAGE_FIELD_MASK)
+
+
+/*
+ * Prototypes for interface functions
+ */
+
+/**
+ * @fn IX_STATUS ixNpeDlImageMgrMicrocodeImageLibraryOverride (UINT32 *clientImageLibrary)
+ *
+ * @brief This instructs NPE Downloader to use client-supplied microcode image library.
+ *
+ * This function sets NPE Downloader to use a client-supplied microcode image library
+ * instead of the standard image library which is included by the NPE Downloader.
+ *
+ * @note THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.
+ * It will be removed in a future release.
+ * See API header file IxNpeDl.h for more information.
+ *
+ * @pre
+ * - <i>clientImageLibrary</i> should point to a microcode image library valid for use
+ * by the NPE Downloader component.
+ *
+ * @post
+ * - the client-supplied image uibrary will be used for all subsequent operations
+ * performed by the NPE Downloader
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_FAIL if the client-supplied image library did not contain a valid signature
+ */
+IX_STATUS
+ixNpeDlImageMgrMicrocodeImageLibraryOverride (UINT32 *clientImageLibrary);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlImageMgrImageListExtract (IxNpeDlImageId *imageListPtr,
+ UINT32 *numImages)
+ *
+ * @brief Extracts a list of images available in the NPE microcode image library.
+ *
+ * @param IxNpeDlImageId* [out] imageListPtr - pointer to array to contain
+ * a list of images. If NULL,
+ * only the number of images
+ * is returned (in
+ * <i>numImages</i>)
+ * @param UINT32* [inout] numImages - As input, it points to a variable
+ * containing the number of images which
+ * can be stored in the
+ * <i>imageListPtr</i> array. Its value
+ * is ignored as input if
+ * <i>imageListPtr</i> is NULL. As an
+ * output, it will contain number of
+ * images in the image library.
+ *
+ * This function reads the header of the microcode image library and extracts a list of the
+ * images available in the image library. It can also be used to find the number of
+ * images in the image library.
+ *
+ * @note THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.
+ * It will be removed in a future release.
+ * See API header file IxNpeDl.h for more information.
+ *
+ * @pre
+ * - if <i>imageListPtr</i> != NULL, <i>numImages</i> should reflect the
+ * number of image Id elements the <i>imageListPtr</i> can contain.
+ *
+ * @post
+ * - <i>numImages</i> will reflect the number of image Id's found in the
+ * microcode image library.
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_FAIL otherwise
+ */
+IX_STATUS
+ixNpeDlImageMgrImageListExtract (IxNpeDlImageId *imageListPtr,
+ UINT32 *numImages);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlImageMgrImageLocate (IxNpeDlImageId *imageId,
+ UINT32 **imagePtr,
+ UINT32 *imageSize)
+ *
+ * @brief Finds a image block in the NPE microcode image library.
+ *
+ * @param IxNpeDlImageId* [in] imageId - the id of the image to locate
+ * @param UINT32** [out] imagePtr - pointer to the image in memory
+ * @param UINT32* [out] imageSize - size (in 32-bit words) of image
+ *
+ * This function examines the header of the microcode image library for the location
+ * and size of the specified image.
+ *
+ * @note THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.
+ * It will be removed in a future release.
+ * See API header file IxNpeDl.h for more information.
+ *
+ * @pre
+ *
+ * @post
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_FAIL otherwise
+ */
+IX_STATUS
+ixNpeDlImageMgrImageLocate (IxNpeDlImageId *imageId,
+ UINT32 **imagePtr,
+ UINT32 *imageSize);
+
+/**
+ * @fn IX_STATUS ixNpeDlImageMgrLatestImageExtract (IxNpeDlImageId *imageId)
+ *
+ * @brief Finds the most recent version of an image in the NPE image library.
+ *
+ * @param IxNpeDlImageId* [inout] imageId - the id of the image
+ *
+ * This function determines the most recent version of a specified image by its
+ * higest major release and minor revision numbers
+ *
+ * @note THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.
+ * It will be removed in a future release.
+ * See API header file IxNpeDl.h for more information.
+ *
+ * @pre
+ *
+ * @post
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_FAIL otherwise
+ */
+IX_STATUS
+ixNpeDlImageMgrLatestImageExtract (IxNpeDlImageId *imageId);
+
+/**
+ * @fn void ixNpeDlImageMgrStatsShow (void)
+ *
+ * @brief This function will display the statistics of the IxNpeDl ImageMgr
+ * module
+ *
+ * @return none
+ */
+void
+ixNpeDlImageMgrStatsShow (void);
+
+
+/**
+ * @fn void ixNpeDlImageMgrStatsReset (void)
+ *
+ * @brief This function will reset the statistics of the IxNpeDl ImageMgr
+ * module
+ *
+ * @return none
+ */
+void
+ixNpeDlImageMgrStatsReset (void);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlImageMgrImageGet (UINT32 *imageLibrary,
+ UINT32 imageId,
+ UINT32 **imagePtr,
+ UINT32 *imageSize)
+ *
+ * @brief Finds a image block in the NPE microcode image library.
+ *
+ * @param UINT32* [in] imageLibrary - the image library to use
+ * @param UINT32 [in] imageId - the id of the image to locate
+ * @param UINT32** [out] imagePtr - pointer to the image in memory
+ * @param UINT32* [out] imageSize - size (in 32-bit words) of image
+ *
+ * This function examines the header of the specified microcode image library
+ * for the location and size of the specified image. It returns a pointer to
+ * the image in the <i>imagePtr</i> parameter.
+ * If no image library is specified (imageLibrary == NULL), then the default
+ * built-in image library will be used.
+ *
+ * @pre
+ *
+ * @post
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_FAIL otherwise
+ */
+IX_STATUS
+ixNpeDlImageMgrImageFind (UINT32 *imageLibrary,
+ UINT32 imageId,
+ UINT32 **imagePtr,
+ UINT32 *imageSize);
+
+
+#endif /* IXNPEDLIMAGEMGR_P_H */
+
+/**
+ * @} defgroup IxNpeDlImageMgr_p
+ */
diff --git a/cpu/ixp/npe/include/IxNpeDlMacros_p.h b/cpu/ixp/npe/include/IxNpeDlMacros_p.h
new file mode 100644
index 0000000..e32906a
--- /dev/null
+++ b/cpu/ixp/npe/include/IxNpeDlMacros_p.h
@@ -0,0 +1,414 @@
+/**
+ * @file IxNpeDlMacros_p.h
+ *
+ * @author Intel Corporation
+ * @date 21 January 2002
+ *
+ * @brief This file contains the macros for the IxNpeDl component.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeDlMacros_p IxNpeDlMacros_p
+ *
+ * @brief Macros for the IxNpeDl component.
+ *
+ * @{
+ */
+
+#ifndef IXNPEDLMACROS_P_H
+#define IXNPEDLMACROS_P_H
+
+
+/*
+ * Put the user defined include files required.
+ */
+#if (CPU != XSCALE)
+/* To support IxNpeDl unit tests... */
+#include <stdio.h>
+#include "test/IxNpeDlTestReg.h"
+
+#else
+#include "IxOsal.h"
+
+#endif
+
+
+/*
+ * Typedefs
+ */
+
+/**
+ * @typedef IxNpeDlTraceTypes
+ * @brief Enumeration defining IxNpeDl trace levels
+ */
+typedef enum
+{
+ IX_NPEDL_TRACE_OFF, /**< no trace */
+ IX_NPEDL_DEBUG, /**< debug */
+ IX_NPEDL_FN_ENTRY_EXIT /**< function entry/exit */
+} IxNpeDlTraceTypes;
+
+
+/*
+ * #defines and macros.
+ */
+
+/* Implementation of the following macros for use with IxNpeDl unit test code */
+#if (CPU != XSCALE)
+
+
+/**
+ * @def IX_NPEDL_TRACE_LEVEL
+ *
+ * @brief IxNpeDl debug trace level
+ */
+#define IX_NPEDL_TRACE_LEVEL IX_NPEDL_FN_ENTRY_EXIT
+
+/**
+ * @def IX_NPEDL_ERROR_REPORT
+ *
+ * @brief Mechanism for reporting IxNpeDl software errors
+ *
+ * @param char* [in] STR - Error string to report
+ *
+ * This macro simply prints the error string passed.
+ * Intended for use with IxNpeDl unit test code.
+ *
+ * @return none
+ */
+#define IX_NPEDL_ERROR_REPORT(STR) printf ("IxNpeDl ERROR: %s\n", (STR));
+
+/**
+ * @def IX_NPEDL_WARNING_REPORT
+ *
+ * @brief Mechanism for reporting IxNpeDl software errors
+ *
+ * @param char* [in] STR - Error string to report
+ *
+ * This macro simply prints the error string passed.
+ * Intended for use with IxNpeDl unit test code.
+ *
+ * @return none
+ */
+#define IX_NPEDL_WARNING_REPORT(STR) printf ("IxNpeDl WARNING: %s\n", (STR));
+
+/**
+ * @def IX_NPEDL_TRACE0
+ *
+ * @brief Mechanism for tracing debug for the IxNpeDl component, for no arguments
+ *
+ * @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
+ * @param char* [in] STR - Trace string
+ *
+ * This macro simply prints the trace string passed, if the level is supported.
+ * Intended for use with IxNpeDl unit test code.
+ *
+ * @return none
+ */
+#define IX_NPEDL_TRACE0(LEVEL, STR) \
+{ \
+ if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
+ { \
+ printf ("IxNpeDl TRACE: "); \
+ printf ((STR)); \
+ printf ("\n"); \
+ } \
+}
+
+ /**
+ * @def IX_NPEDL_TRACE1
+ *
+ * @brief Mechanism for tracing debug for the IxNpeDl component, with 1 argument
+ *
+ * @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
+ * @param char* [in] STR - Trace string
+ * @param argType [in] ARG1 - Argument to trace
+ *
+ * This macro simply prints the trace string passed, if the level is supported.
+ * Intended for use with IxNpeDl unit test code.
+ *
+ * @return none
+ */
+#define IX_NPEDL_TRACE1(LEVEL, STR, ARG1) \
+{ \
+ if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
+ { \
+ printf ("IxNpeDl TRACE: "); \
+ printf (STR, ARG1); \
+ printf ("\n"); \
+ } \
+}
+
+/**
+ * @def IX_NPEDL_TRACE2
+ *
+ * @brief Mechanism for tracing debug for the IxNpeDl component, with 2 arguments
+ *
+ * @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
+ * @param char* [in] STR - Trace string
+ * @param argType [in] ARG1 - Argument to trace
+ * @param argType [in] ARG2 - Argument to trace
+ *
+ * This macro simply prints the trace string passed, if the level is supported.
+ * Intended for use with IxNpeDl unit test code.
+ *
+ * @return none
+ */
+#define IX_NPEDL_TRACE2(LEVEL, STR, ARG1, ARG2) \
+{ \
+ if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
+ { \
+ printf ("IxNpeDl TRACE: "); \
+ printf (STR, ARG1, ARG2); \
+ printf ("\n"); \
+ } \
+}
+
+
+/**
+ * @def IX_NPEDL_REG_WRITE
+ *
+ * @brief Mechanism for writing to a memory-mapped register
+ *
+ * @param UINT32 [in] base - Base memory address for this NPE's registers
+ * @param UINT32 [in] offset - Offset from base memory address
+ * @param UINT32 [in] value - Value to write to register
+ *
+ * This macro calls a function from Unit Test code to write a register. This
+ * allows extra flexibility for unit testing of the IxNpeDl component.
+ *
+ * @return none
+ */
+#define IX_NPEDL_REG_WRITE(base, offset, value) \
+{ \
+ ixNpeDlTestRegWrite (base, offset, value); \
+}
+
+
+/**
+ * @def IX_NPEDL_REG_READ
+ *
+ * @brief Mechanism for reading from a memory-mapped register
+ *
+ * @param UINT32 [in] base - Base memory address for this NPE's registers
+ * @param UINT32 [in] offset - Offset from base memory address
+ * @param UINT32 *[out] value - Value read from register
+ *
+ * This macro calls a function from Unit Test code to read a register. This
+ * allows extra flexibility for unit testing of the IxNpeDl component.
+ *
+ * @return none
+ */
+#define IX_NPEDL_REG_READ(base, offset, value) \
+{ \
+ ixNpeDlTestRegRead (base, offset, value); \
+}
+
+
+/* Implementation of the following macros when integrated with IxOsal */
+#else /* #if (CPU != XSCALE) */
+
+
+/**
+ * @def IX_NPEDL_TRACE_LEVEL
+ *
+ * @brief IxNpeDl debug trace level
+ */
+#define IX_NPEDL_TRACE_LEVEL IX_NPEDL_DEBUG
+
+
+/**
+ * @def IX_NPEDL_ERROR_REPORT
+ *
+ * @brief Mechanism for reporting IxNpeDl software errors
+ *
+ * @param char* [in] STR - Error string to report
+ *
+ * This macro is used to report IxNpeDl software errors.
+ *
+ * @return none
+ */
+#define IX_NPEDL_ERROR_REPORT(STR) \
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, STR, 0, 0, 0, 0, 0, 0);
+
+/**
+ * @def IX_NPEDL_WARNING_REPORT
+ *
+ * @brief Mechanism for reporting IxNpeDl software warnings
+ *
+ * @param char* [in] STR - Warning string to report
+ *
+ * This macro is used to report IxNpeDl software warnings.
+ *
+ * @return none
+ */
+#define IX_NPEDL_WARNING_REPORT(STR) \
+ ixOsalLog (IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, STR, 0, 0, 0, 0, 0, 0);
+
+
+/**
+ * @def IX_NPEDL_TRACE0
+ *
+ * @brief Mechanism for tracing debug for the IxNpeDl component, for no arguments
+ *
+ * @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
+ * @param char* [in] STR - Trace string
+ *
+ * This macro simply prints the trace string passed, if the level is supported.
+ *
+ * @return none
+ */
+#define IX_NPEDL_TRACE0(LEVEL, STR) \
+{ \
+ if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
+ { \
+ if (LEVEL == IX_NPEDL_FN_ENTRY_EXIT) \
+ { \
+ ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, IX_OSAL_LOG_DEV_STDOUT, STR, 0, 0, 0, 0, 0, 0); \
+ } \
+ else if (LEVEL == IX_NPEDL_DEBUG) \
+ { \
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, STR, 0, 0, 0, 0, 0, 0); \
+ } \
+ } \
+}
+
+/**
+ * @def IX_NPEDL_TRACE1
+ *
+ * @brief Mechanism for tracing debug for the IxNpeDl component, with 1 argument
+ *
+ * @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
+ * @param char* [in] STR - Trace string
+ * @param argType [in] ARG1 - Argument to trace
+ *
+ * This macro simply prints the trace string passed, if the level is supported.
+ *
+ * @return none
+ */
+#define IX_NPEDL_TRACE1(LEVEL, STR, ARG1) \
+{ \
+ if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
+ { \
+ if (LEVEL == IX_NPEDL_FN_ENTRY_EXIT) \
+ { \
+ ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, IX_OSAL_LOG_DEV_STDOUT, STR, ARG1, 0, 0, 0, 0, 0); \
+ } \
+ else if (LEVEL == IX_NPEDL_DEBUG) \
+ { \
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, STR, ARG1, 0, 0, 0, 0, 0); \
+ } \
+ } \
+}
+
+/**
+ * @def IX_NPEDL_TRACE2
+ *
+ * @brief Mechanism for tracing debug for the IxNpeDl component, with 2 arguments
+ *
+ * @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
+ * @param char* [in] STR - Trace string
+ * @param argType [in] ARG1 - Argument to trace
+ * @param argType [in] ARG2 - Argument to trace
+ *
+ * This macro simply prints the trace string passed, if the level is supported.
+ *
+ * @return none
+ */
+#define IX_NPEDL_TRACE2(LEVEL, STR, ARG1, ARG2) \
+{ \
+ if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
+ { \
+ if (LEVEL == IX_NPEDL_FN_ENTRY_EXIT) \
+ { \
+ ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, IX_OSAL_LOG_DEV_STDOUT, STR, ARG1, ARG2, 0, 0, 0, 0); \
+ } \
+ else if (LEVEL == IX_NPEDL_DEBUG) \
+ { \
+ ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, STR, ARG1, ARG2, 0, 0, 0, 0); \
+ } \
+ } \
+}
+
+/**
+ * @def IX_NPEDL_REG_WRITE
+ *
+ * @brief Mechanism for writing to a memory-mapped register
+ *
+ * @param UINT32 [in] base - Base memory address for this NPE's registers
+ * @param UINT32 [in] offset - Offset from base memory address
+ * @param UINT32 [in] value - Value to write to register
+ *
+ * This macro forms the address of the register from base address + offset, and
+ * dereferences that address to write the contents of the register.
+ *
+ * @return none
+ */
+#define IX_NPEDL_REG_WRITE(base, offset, value) \
+ IX_OSAL_WRITE_LONG(((base) + (offset)), (value))
+
+
+
+/**
+ * @def IX_NPEDL_REG_READ
+ *
+ * @brief Mechanism for reading from a memory-mapped register
+ *
+ * @param UINT32 [in] base - Base memory address for this NPE's registers
+ * @param UINT32 [in] offset - Offset from base memory address
+ * @param UINT32 *[out] value - Value read from register
+ *
+ * This macro forms the address of the register from base address + offset, and
+ * dereferences that address to read the register contents.
+ *
+ * @return none
+ */
+#define IX_NPEDL_REG_READ(base, offset, value) \
+ *(value) = IX_OSAL_READ_LONG(((base) + (offset)))
+
+#endif /* #if (CPU != XSCALE) */
+
+#endif /* IXNPEDLMACROS_P_H */
+
+/**
+ * @} defgroup IxNpeDlMacros_p
+ */
diff --git a/cpu/ixp/npe/include/IxNpeDlNpeMgrEcRegisters_p.h b/cpu/ixp/npe/include/IxNpeDlNpeMgrEcRegisters_p.h
new file mode 100644
index 0000000..f682126
--- /dev/null
+++ b/cpu/ixp/npe/include/IxNpeDlNpeMgrEcRegisters_p.h
@@ -0,0 +1,893 @@
+/**
+ * @file IxNpeDlNpeMgrEcRegisters_p.h
+ *
+ * @author Intel Corporation
+ * @date 14 December 2001
+
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+
+#ifndef IXNPEDLNPEMGRECREGISTERS_P_H
+#define IXNPEDLNPEMGRECREGISTERS_P_H
+
+#include "IxOsal.h"
+
+/*
+ * Base Memory Addresses for accessing NPE registers
+ */
+
+#define IX_NPEDL_NPE_BASE (IX_OSAL_IXP400_PERIPHERAL_PHYS_BASE)
+
+#define IX_NPEDL_NPEA_OFFSET (0x6000) /**< NPE-A register base offset */
+#define IX_NPEDL_NPEB_OFFSET (0x7000) /**< NPE-B register base offset */
+#define IX_NPEDL_NPEC_OFFSET (0x8000) /**< NPE-C register base offset */
+
+/**
+ * @def IX_NPEDL_NPEBASEADDRESS_NPEA
+ * @brief Base Memory Address of NPE-A Configuration Bus registers
+ */
+#define IX_NPEDL_NPEBASEADDRESS_NPEA (IX_NPEDL_NPE_BASE + IX_NPEDL_NPEA_OFFSET)
+
+/**
+ * @def IX_NPEDL_NPEBASEADDRESS_NPEB
+ * @brief Base Memory Address of NPE-B Configuration Bus registers
+ */
+#define IX_NPEDL_NPEBASEADDRESS_NPEB (IX_NPEDL_NPE_BASE + IX_NPEDL_NPEB_OFFSET)
+
+/**
+ * @def IX_NPEDL_NPEBASEADDRESS_NPEC
+ * @brief Base Memory Address of NPE-C Configuration Bus registers
+ */
+#define IX_NPEDL_NPEBASEADDRESS_NPEC (IX_NPEDL_NPE_BASE + IX_NPEDL_NPEC_OFFSET)
+
+
+/*
+ * Instruction Memory Size (in words) for each NPE
+ */
+
+/**
+ * @def IX_NPEDL_INS_MEMSIZE_WORDS_NPEA
+ * @brief Size (in words) of NPE-A Instruction Memory
+ */
+#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEA 4096
+
+/**
+ * @def IX_NPEDL_INS_MEMSIZE_WORDS_NPEB
+ * @brief Size (in words) of NPE-B Instruction Memory
+ */
+#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEB 2048
+
+/**
+ * @def IX_NPEDL_INS_MEMSIZE_WORDS_NPEC
+ * @brief Size (in words) of NPE-B Instruction Memory
+ */
+#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEC 2048
+
+
+/*
+ * Data Memory Size (in words) for each NPE
+ */
+
+/**
+ * @def IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA
+ * @brief Size (in words) of NPE-A Data Memory
+ */
+#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA 2048
+
+/**
+ * @def IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB
+ * @brief Size (in words) of NPE-B Data Memory
+ */
+#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB 2048
+
+/**
+ * @def IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC
+ * @brief Size (in words) of NPE-C Data Memory
+ */
+#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC 2048
+
+
+/*
+ * Configuration Bus Register offsets (in bytes) from NPE Base Address
+ */
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_EXAD
+ * @brief Offset (in bytes) of EXAD (Execution Address) register from NPE Base
+ * Address
+ */
+#define IX_NPEDL_REG_OFFSET_EXAD 0x00000000
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_EXDATA
+ * @brief Offset (in bytes) of EXDATA (Execution Data) register from NPE Base
+ * Address
+ */
+#define IX_NPEDL_REG_OFFSET_EXDATA 0x00000004
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_EXCTL
+ * @brief Offset (in bytes) of EXCTL (Execution Control) register from NPE Base
+ * Address
+ */
+#define IX_NPEDL_REG_OFFSET_EXCTL 0x00000008
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_EXCT
+ * @brief Offset (in bytes) of EXCT (Execution Count) register from NPE Base
+ * Address
+ */
+#define IX_NPEDL_REG_OFFSET_EXCT 0x0000000C
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_AP0
+ * @brief Offset (in bytes) of AP0 (Action Point 0) register from NPE Base
+ * Address
+ */
+#define IX_NPEDL_REG_OFFSET_AP0 0x00000010
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_AP1
+ * @brief Offset (in bytes) of AP1 (Action Point 1) register from NPE Base
+ * Address
+ */
+#define IX_NPEDL_REG_OFFSET_AP1 0x00000014
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_AP2
+ * @brief Offset (in bytes) of AP2 (Action Point 2) register from NPE Base
+ * Address
+ */
+#define IX_NPEDL_REG_OFFSET_AP2 0x00000018
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_AP3
+ * @brief Offset (in bytes) of AP3 (Action Point 3) register from NPE Base
+ * Address
+ */
+#define IX_NPEDL_REG_OFFSET_AP3 0x0000001C
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_WFIFO
+ * @brief Offset (in bytes) of WFIFO (Watchpoint FIFO) register from NPE Base
+ * Address
+ */
+#define IX_NPEDL_REG_OFFSET_WFIFO 0x00000020
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_WC
+ * @brief Offset (in bytes) of WC (Watch Count) register from NPE Base
+ * Address
+ */
+#define IX_NPEDL_REG_OFFSET_WC 0x00000024
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_PROFCT
+ * @brief Offset (in bytes) of PROFCT (Profile Count) register from NPE Base
+ * Address
+ */
+#define IX_NPEDL_REG_OFFSET_PROFCT 0x00000028
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_STAT
+ * @brief Offset (in bytes) of STAT (Messaging Status) register from NPE Base
+ * Address
+ */
+#define IX_NPEDL_REG_OFFSET_STAT 0x0000002C
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_CTL
+ * @brief Offset (in bytes) of CTL (Messaging Control) register from NPE Base
+ * Address
+ */
+#define IX_NPEDL_REG_OFFSET_CTL 0x00000030
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_MBST
+ * @brief Offset (in bytes) of MBST (Mailbox Status) register from NPE Base
+ * Address
+ */
+#define IX_NPEDL_REG_OFFSET_MBST 0x00000034
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_FIFO
+ * @brief Offset (in bytes) of FIFO (messaging in/out FIFO) register from NPE
+ * Base Address
+ */
+#define IX_NPEDL_REG_OFFSET_FIFO 0x00000038
+
+
+/*
+ * Non-zero reset values for the Configuration Bus registers
+ */
+
+/**
+ * @def IX_NPEDL_REG_RESET_FIFO
+ * @brief Reset value for Mailbox (MBST) register
+ * NOTE that if used, it should be complemented with an NPE intruction
+ * to clear the Mailbox at the NPE side as well
+ */
+#define IX_NPEDL_REG_RESET_MBST 0x0000F0F0
+
+
+/*
+ * Bit-masks used to read/write particular bits in Configuration Bus registers
+ */
+
+/**
+ * @def IX_NPEDL_MASK_WFIFO_VALID
+ * @brief Masks the VALID bit in the WFIFO register
+ */
+#define IX_NPEDL_MASK_WFIFO_VALID 0x80000000
+
+/**
+ * @def IX_NPEDL_MASK_STAT_OFNE
+ * @brief Masks the OFNE bit in the STAT register
+ */
+#define IX_NPEDL_MASK_STAT_OFNE 0x00010000
+
+/**
+ * @def IX_NPEDL_MASK_STAT_IFNE
+ * @brief Masks the IFNE bit in the STAT register
+ */
+#define IX_NPEDL_MASK_STAT_IFNE 0x00080000
+
+
+/*
+ * EXCTL (Execution Control) Register commands
+*/
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_NPE_STEP
+ * @brief EXCTL Command to Step execution of an NPE Instruction
+ */
+
+#define IX_NPEDL_EXCTL_CMD_NPE_STEP 0x01
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_NPE_START
+ * @brief EXCTL Command to Start NPE execution
+ */
+#define IX_NPEDL_EXCTL_CMD_NPE_START 0x02
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_NPE_STOP
+ * @brief EXCTL Command to Stop NPE execution
+ */
+#define IX_NPEDL_EXCTL_CMD_NPE_STOP 0x03
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE
+ * @brief EXCTL Command to Clear NPE instruction pipeline
+ */
+#define IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE 0x04
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_RD_INS_MEM
+ * @brief EXCTL Command to read NPE instruction memory at address in EXAD
+ * register and return value in EXDATA register
+ */
+#define IX_NPEDL_EXCTL_CMD_RD_INS_MEM 0x10
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_WR_INS_MEM
+ * @brief EXCTL Command to write NPE instruction memory at address in EXAD
+ * register with data in EXDATA register
+ */
+#define IX_NPEDL_EXCTL_CMD_WR_INS_MEM 0x11
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_RD_DATA_MEM
+ * @brief EXCTL Command to read NPE data memory at address in EXAD
+ * register and return value in EXDATA register
+ */
+#define IX_NPEDL_EXCTL_CMD_RD_DATA_MEM 0x12
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_WR_DATA_MEM
+ * @brief EXCTL Command to write NPE data memory at address in EXAD
+ * register with data in EXDATA register
+ */
+#define IX_NPEDL_EXCTL_CMD_WR_DATA_MEM 0x13
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_RD_ECS_REG
+ * @brief EXCTL Command to read Execution Access register at address in EXAD
+ * register and return value in EXDATA register
+ */
+#define IX_NPEDL_EXCTL_CMD_RD_ECS_REG 0x14
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_WR_ECS_REG
+ * @brief EXCTL Command to write Execution Access register at address in EXAD
+ * register with data in EXDATA register
+ */
+#define IX_NPEDL_EXCTL_CMD_WR_ECS_REG 0x15
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT
+ * @brief EXCTL Command to clear Profile Count register
+ */
+#define IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT 0x0C
+
+
+/*
+ * EXCTL (Execution Control) Register status bit masks
+ */
+
+/**
+ * @def IX_NPEDL_EXCTL_STATUS_RUN
+ * @brief Masks the RUN status bit in the EXCTL register
+ */
+#define IX_NPEDL_EXCTL_STATUS_RUN 0x80000000
+
+/**
+ * @def IX_NPEDL_EXCTL_STATUS_STOP
+ * @brief Masks the STOP status bit in the EXCTL register
+ */
+#define IX_NPEDL_EXCTL_STATUS_STOP 0x40000000
+
+/**
+ * @def IX_NPEDL_EXCTL_STATUS_CLEAR
+ * @brief Masks the CLEAR status bit in the EXCTL register
+ */
+#define IX_NPEDL_EXCTL_STATUS_CLEAR 0x20000000
+
+/**
+ * @def IX_NPEDL_EXCTL_STATUS_ECS_K
+ * @brief Masks the K (pipeline Klean) status bit in the EXCTL register
+ */
+#define IX_NPEDL_EXCTL_STATUS_ECS_K 0x00800000
+
+
+/*
+ * Executing Context Stack (ECS) level registers
+ */
+
+/**
+ * @def IX_NPEDL_ECS_BG_CTXT_REG_0
+ * @brief Execution Access register address for register 0 at Backgound
+ * Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_BG_CTXT_REG_0 0x00
+
+/**
+ * @def IX_NPEDL_ECS_BG_CTXT_REG_1
+ * @brief Execution Access register address for register 1 at Backgound
+ * Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_BG_CTXT_REG_1 0x01
+
+/**
+ * @def IX_NPEDL_ECS_BG_CTXT_REG_2
+ * @brief Execution Access register address for register 2 at Backgound
+ * Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_BG_CTXT_REG_2 0x02
+
+/**
+ * @def IX_NPEDL_ECS_PRI_1_CTXT_REG_0
+ * @brief Execution Access register address for register 0 at Priority 1
+ * Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_0 0x04
+
+/**
+ * @def IX_NPEDL_ECS_PRI_1_CTXT_REG_1
+ * @brief Execution Access register address for register 1 at Priority 1
+ * Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_1 0x05
+
+/**
+ * @def IX_NPEDL_ECS_PRI_1_CTXT_REG_2
+ * @brief Execution Access register address for register 2 at Priority 1
+ * Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_2 0x06
+
+/**
+ * @def IX_NPEDL_ECS_PRI_2_CTXT_REG_0
+ * @brief Execution Access register address for register 0 at Priority 2
+ * Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_0 0x08
+
+/**
+ * @def IX_NPEDL_ECS_PRI_2_CTXT_REG_1
+ * @brief Execution Access register address for register 1 at Priority 2
+ * Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_1 0x09
+
+/**
+ * @def IX_NPEDL_ECS_PRI_2_CTXT_REG_2
+ * @brief Execution Access register address for register 2 at Priority 2
+ * Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_2 0x0A
+
+/**
+ * @def IX_NPEDL_ECS_DBG_CTXT_REG_0
+ * @brief Execution Access register address for register 0 at Debug
+ * Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_DBG_CTXT_REG_0 0x0C
+
+/**
+ * @def IX_NPEDL_ECS_DBG_CTXT_REG_1
+ * @brief Execution Access register address for register 1 at Debug
+ * Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_DBG_CTXT_REG_1 0x0D
+
+/**
+ * @def IX_NPEDL_ECS_DBG_CTXT_REG_2
+ * @brief Execution Access register address for register 2 at Debug
+ * Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_DBG_CTXT_REG_2 0x0E
+
+/**
+ * @def IX_NPEDL_ECS_INSTRUCT_REG
+ * @brief Execution Access register address for NPE Instruction Register
+ */
+#define IX_NPEDL_ECS_INSTRUCT_REG 0x11
+
+
+/*
+ * Execution Access register reset values
+ */
+
+/**
+ * @def IX_NPEDL_ECS_BG_CTXT_REG_0_RESET
+ * @brief Reset value for Execution Access Background ECS level register 0
+ */
+#define IX_NPEDL_ECS_BG_CTXT_REG_0_RESET 0xA0000000
+
+/**
+ * @def IX_NPEDL_ECS_BG_CTXT_REG_1_RESET
+ * @brief Reset value for Execution Access Background ECS level register 1
+ */
+#define IX_NPEDL_ECS_BG_CTXT_REG_1_RESET 0x01000000
+
+/**
+ * @def IX_NPEDL_ECS_BG_CTXT_REG_2_RESET
+ * @brief Reset value for Execution Access Background ECS level register 2
+ */
+#define IX_NPEDL_ECS_BG_CTXT_REG_2_RESET 0x00008000
+
+/**
+ * @def IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET
+ * @brief Reset value for Execution Access Priority 1 ECS level register 0
+ */
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET 0x20000080
+
+/**
+ * @def IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET
+ * @brief Reset value for Execution Access Priority 1 ECS level register 1
+ */
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET 0x01000000
+
+/**
+ * @def IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET
+ * @brief Reset value for Execution Access Priority 1 ECS level register 2
+ */
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET 0x00008000
+
+/**
+ * @def IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET
+ * @brief Reset value for Execution Access Priority 2 ECS level register 0
+ */
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET 0x20000080
+
+/**
+ * @def IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET
+ * @brief Reset value for Execution Access Priority 2 ECS level register 1
+ */
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET 0x01000000
+
+/**
+ * @def IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET
+ * @brief Reset value for Execution Access Priority 2 ECS level register 2
+ */
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET 0x00008000
+
+/**
+ * @def IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET
+ * @brief Reset value for Execution Access Debug ECS level register 0
+ */
+#define IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET 0x20000000
+
+/**
+ * @def IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET
+ * @brief Reset value for Execution Access Debug ECS level register 1
+ */
+#define IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET 0x00000000
+
+/**
+ * @def IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET
+ * @brief Reset value for Execution Access Debug ECS level register 2
+ */
+#define IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET 0x001E0000
+
+/**
+ * @def IX_NPEDL_ECS_INSTRUCT_REG_RESET
+ * @brief Reset value for Execution Access NPE Instruction Register
+ */
+#define IX_NPEDL_ECS_INSTRUCT_REG_RESET 0x1003C00F
+
+
+/*
+ * masks used to read/write particular bits in Execution Access registers
+ */
+
+/**
+ * @def IX_NPEDL_MASK_ECS_REG_0_ACTIVE
+ * @brief Mask the A (Active) bit in Execution Access Register 0 of all ECS
+ * levels
+ */
+#define IX_NPEDL_MASK_ECS_REG_0_ACTIVE 0x80000000
+
+/**
+ * @def IX_NPEDL_MASK_ECS_REG_0_NEXTPC
+ * @brief Mask the NextPC bits in Execution Access Register 0 of all ECS
+ * levels (except Debug ECS level)
+ */
+#define IX_NPEDL_MASK_ECS_REG_0_NEXTPC 0x1FFF0000
+
+/**
+ * @def IX_NPEDL_MASK_ECS_REG_0_LDUR
+ * @brief Mask the LDUR bits in Execution Access Register 0 of all ECS levels
+ */
+#define IX_NPEDL_MASK_ECS_REG_0_LDUR 0x00000700
+
+/**
+ * @def IX_NPEDL_MASK_ECS_REG_1_CCTXT
+ * @brief Mask the NextPC bits in Execution Access Register 1 of all ECS levels
+ */
+#define IX_NPEDL_MASK_ECS_REG_1_CCTXT 0x000F0000
+
+/**
+ * @def IX_NPEDL_MASK_ECS_REG_1_SELCTXT
+ * @brief Mask the NextPC bits in Execution Access Register 1 of all ECS levels
+ */
+#define IX_NPEDL_MASK_ECS_REG_1_SELCTXT 0x0000000F
+
+/**
+ * @def IX_NPEDL_MASK_ECS_DBG_REG_2_IF
+ * @brief Mask the IF bit in Execution Access Register 2 of Debug ECS level
+ */
+#define IX_NPEDL_MASK_ECS_DBG_REG_2_IF 0x00100000
+
+/**
+ * @def IX_NPEDL_MASK_ECS_DBG_REG_2_IE
+ * @brief Mask the IE bit in Execution Access Register 2 of Debug ECS level
+ */
+#define IX_NPEDL_MASK_ECS_DBG_REG_2_IE 0x00080000
+
+
+/*
+ * Bit-Offsets from LSB of particular bit-fields in Execution Access registers
+ */
+
+/**
+ * @def IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC
+ * @brief LSB-offset of NextPC field in Execution Access Register 0 of all ECS
+ * levels (except Debug ECS level)
+ */
+#define IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC 16
+
+/**
+ * @def IX_NPEDL_OFFSET_ECS_REG_0_LDUR
+ * @brief LSB-offset of LDUR field in Execution Access Register 0 of all ECS
+ * levels
+ */
+#define IX_NPEDL_OFFSET_ECS_REG_0_LDUR 8
+
+/**
+ * @def IX_NPEDL_OFFSET_ECS_REG_1_CCTXT
+ * @brief LSB-offset of CCTXT field in Execution Access Register 1 of all ECS
+ * levels
+ */
+#define IX_NPEDL_OFFSET_ECS_REG_1_CCTXT 16
+
+/**
+ * @def IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT
+ * @brief LSB-offset of SELCTXT field in Execution Access Register 1 of all ECS
+ * levels
+ */
+#define IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT 0
+
+
+/*
+ * NPE core & co-processor instruction templates to load into NPE Instruction
+ * Register, for read/write of NPE register file registers
+ */
+
+/**
+ * @def IX_NPEDL_INSTR_RD_REG_BYTE
+ * @brief NPE Instruction, used to read an 8-bit NPE internal logical register
+ * and return the value in the EXDATA register (aligned to MSB).
+ * NPE Assembler instruction: "mov8 d0, d0 &&& DBG_WrExec"
+ */
+#define IX_NPEDL_INSTR_RD_REG_BYTE 0x0FC00000
+
+/**
+ * @def IX_NPEDL_INSTR_RD_REG_SHORT
+ * @brief NPE Instruction, used to read a 16-bit NPE internal logical register
+ * and return the value in the EXDATA register (aligned to MSB).
+ * NPE Assembler instruction: "mov16 d0, d0 &&& DBG_WrExec"
+ */
+#define IX_NPEDL_INSTR_RD_REG_SHORT 0x0FC08010
+
+/**
+ * @def IX_NPEDL_INSTR_RD_REG_WORD
+ * @brief NPE Instruction, used to read a 16-bit NPE internal logical register
+ * and return the value in the EXDATA register.
+ * NPE Assembler instruction: "mov32 d0, d0 &&& DBG_WrExec"
+ */
+#define IX_NPEDL_INSTR_RD_REG_WORD 0x0FC08210
+
+/**
+ * @def IX_NPEDL_INSTR_WR_REG_BYTE
+ * @brief NPE Immediate-Mode Instruction, used to write an 8-bit NPE internal
+ * logical register.
+ * NPE Assembler instruction: "mov8 d0, #0"
+ */
+#define IX_NPEDL_INSTR_WR_REG_BYTE 0x00004000
+
+/**
+ * @def IX_NPEDL_INSTR_WR_REG_SHORT
+ * @brief NPE Immediate-Mode Instruction, used to write a 16-bit NPE internal
+ * logical register.
+ * NPE Assembler instruction: "mov16 d0, #0"
+ */
+#define IX_NPEDL_INSTR_WR_REG_SHORT 0x0000C000
+
+/**
+ * @def IX_NPEDL_INSTR_RD_FIFO
+ * @brief NPE Immediate-Mode Instruction, used to write a 16-bit NPE internal
+ * logical register.
+ * NPE Assembler instruction: "cprd32 d0 &&& DBG_RdInFIFO"
+ */
+#define IX_NPEDL_INSTR_RD_FIFO 0x0F888220
+
+/**
+ * @def IX_NPEDL_INSTR_RESET_MBOX
+ * @brief NPE Instruction, used to reset Mailbox (MBST) register
+ * NPE Assembler instruction: "mov32 d0, d0 &&& DBG_ClearM"
+ */
+#define IX_NPEDL_INSTR_RESET_MBOX 0x0FAC8210
+
+
+/*
+ * Bit-offsets from LSB, of particular bit-fields in an NPE instruction
+ */
+
+/**
+ * @def IX_NPEDL_OFFSET_INSTR_SRC
+ * @brief LSB-offset to SRC (source operand) field of an NPE Instruction
+ */
+#define IX_NPEDL_OFFSET_INSTR_SRC 4
+
+/**
+ * @def IX_NPEDL_OFFSET_INSTR_DEST
+ * @brief LSB-offset to DEST (destination operand) field of an NPE Instruction
+ */
+#define IX_NPEDL_OFFSET_INSTR_DEST 9
+
+/**
+ * @def IX_NPEDL_OFFSET_INSTR_COPROC
+ * @brief LSB-offset to COPROC (coprocessor instruction) field of an NPE
+ * Instruction
+ */
+#define IX_NPEDL_OFFSET_INSTR_COPROC 18
+
+
+/*
+ * masks used to read/write particular bits of an NPE Instruction
+ */
+
+/**
+ * @def IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA
+ * @brief Mask the bits of 16-bit data value (least-sig 5 bits) to be used in
+ * SRC field of immediate-mode NPE instruction
+ */
+#define IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA 0x1F
+
+/**
+ * @def IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA
+ * @brief Mask the bits of 16-bit data value (most-sig 11 bits) to be used in
+ * COPROC field of immediate-mode NPE instruction
+ */
+#define IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA 0xFFE0
+
+/**
+ * @def IX_NPEDL_OFFSET_IMMED_INSTR_COPROC_DATA
+ * @brief LSB offset of the bit-field of 16-bit data value (most-sig 11 bits)
+ * to be used in COPROC field of immediate-mode NPE instruction
+ */
+#define IX_NPEDL_OFFSET_IMMED_INSTR_COPROC_DATA 5
+
+/**
+ * @def IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA
+ * @brief Number of left-shifts required to align most-sig 11 bits of 16-bit
+ * data value into COPROC field of immediate-mode NPE instruction
+ */
+#define IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA \
+ (IX_NPEDL_OFFSET_INSTR_COPROC - IX_NPEDL_OFFSET_IMMED_INSTR_COPROC_DATA)
+
+/**
+ * @def IX_NPEDL_WR_INSTR_LDUR
+ * @brief LDUR value used with immediate-mode NPE Instructions by the NpeDl
+ * for writing to NPE internal logical registers
+ */
+#define IX_NPEDL_WR_INSTR_LDUR 1
+
+/**
+ * @def IX_NPEDL_RD_INSTR_LDUR
+ * @brief LDUR value used with NON-immediate-mode NPE Instructions by the NpeDl
+ * for reading from NPE internal logical registers
+ */
+#define IX_NPEDL_RD_INSTR_LDUR 0
+
+
+/**
+ * @enum IxNpeDlCtxtRegNum
+ * @brief Numeric values to identify the NPE internal Context Store registers
+ */
+typedef enum
+{
+ IX_NPEDL_CTXT_REG_STEVT = 0, /**< identifies STEVT */
+ IX_NPEDL_CTXT_REG_STARTPC, /**< identifies STARTPC */
+ IX_NPEDL_CTXT_REG_REGMAP, /**< identifies REGMAP */
+ IX_NPEDL_CTXT_REG_CINDEX, /**< identifies CINDEX */
+ IX_NPEDL_CTXT_REG_MAX /**< Total number of Context Store registers */
+} IxNpeDlCtxtRegNum;
+
+
+/*
+ * NPE Context Store register logical addresses
+ */
+
+/**
+ * @def IX_NPEDL_CTXT_REG_ADDR_STEVT
+ * @brief Logical address of STEVT NPE internal Context Store register
+ */
+#define IX_NPEDL_CTXT_REG_ADDR_STEVT 0x0000001B
+
+/**
+ * @def IX_NPEDL_CTXT_REG_ADDR_STARTPC
+ * @brief Logical address of STARTPC NPE internal Context Store register
+ */
+#define IX_NPEDL_CTXT_REG_ADDR_STARTPC 0x0000001C
+
+/**
+ * @def IX_NPEDL_CTXT_REG_ADDR_REGMAP
+ * @brief Logical address of REGMAP NPE internal Context Store register
+ */
+#define IX_NPEDL_CTXT_REG_ADDR_REGMAP 0x0000001E
+
+/**
+ * @def IX_NPEDL_CTXT_REG_ADDR_CINDEX
+ * @brief Logical address of CINDEX NPE internal Context Store register
+ */
+#define IX_NPEDL_CTXT_REG_ADDR_CINDEX 0x0000001F
+
+
+/*
+ * NPE Context Store register reset values
+ */
+
+/**
+ * @def IX_NPEDL_CTXT_REG_RESET_STEVT
+ * @brief Reset value of STEVT NPE internal Context Store register
+ * (STEVT = off, 0x80)
+ */
+#define IX_NPEDL_CTXT_REG_RESET_STEVT 0x80
+
+/**
+ * @def IX_NPEDL_CTXT_REG_RESET_STARTPC
+ * @brief Reset value of STARTPC NPE internal Context Store register
+ * (STARTPC = 0x0000)
+ */
+#define IX_NPEDL_CTXT_REG_RESET_STARTPC 0x0000
+
+/**
+ * @def IX_NPEDL_CTXT_REG_RESET_REGMAP
+ * @brief Reset value of REGMAP NPE internal Context Store register
+ * (REGMAP = d0->p0, d8->p2, d16->p4)
+ */
+#define IX_NPEDL_CTXT_REG_RESET_REGMAP 0x0820
+
+/**
+ * @def IX_NPEDL_CTXT_REG_RESET_CINDEX
+ * @brief Reset value of CINDEX NPE internal Context Store register
+ * (CINDEX = 0)
+ */
+#define IX_NPEDL_CTXT_REG_RESET_CINDEX 0x00
+
+
+/*
+ * numeric range of context levels available on an NPE
+ */
+
+/**
+ * @def IX_NPEDL_CTXT_NUM_MIN
+ * @brief Lowest NPE Context number in range
+ */
+#define IX_NPEDL_CTXT_NUM_MIN 0
+
+/**
+ * @def IX_NPEDL_CTXT_NUM_MAX
+ * @brief Highest NPE Context number in range
+ */
+#define IX_NPEDL_CTXT_NUM_MAX 15
+
+
+/*
+ * Physical NPE internal registers
+ */
+
+/**
+ * @def IX_NPEDL_TOTAL_NUM_PHYS_REG
+ * @brief Number of Physical registers currently supported
+ * Initial NPE implementations will have a 32-word register file.
+ * Later implementations may have a 64-word register file.
+ */
+#define IX_NPEDL_TOTAL_NUM_PHYS_REG 32
+
+/**
+ * @def IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP
+ * @brief LSB-offset of Regmap number in Physical NPE register address, used
+ * for Physical To Logical register address mapping in the NPE
+ */
+#define IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP 1
+
+/**
+ * @def IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR
+ * @brief Mask to extract a logical NPE register address from a physical
+ * register address, used for Physical To Logical address mapping
+ */
+#define IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR 0x1
+
+#endif /* IXNPEDLNPEMGRECREGISTERS_P_H */
diff --git a/cpu/ixp/npe/include/IxNpeDlNpeMgrUtils_p.h b/cpu/ixp/npe/include/IxNpeDlNpeMgrUtils_p.h
new file mode 100644
index 0000000..a752f26
--- /dev/null
+++ b/cpu/ixp/npe/include/IxNpeDlNpeMgrUtils_p.h
@@ -0,0 +1,405 @@
+/**
+ * @file IxNpeDlNpeMgrUtils_p.h
+ *
+ * @author Intel Corporation
+ * @date 18 February 2002
+ * @brief This file contains the private API for the NpeMgr module.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+
+/**
+ * @defgroup IxNpeDlNpeMgrUtils_p IxNpeDlNpeMgrUtils_p
+ *
+ * @brief The private API for the IxNpeDl NpeMgr Utils module
+ *
+ * @{
+ */
+
+#ifndef IXNPEDLNPEMGRUTILS_P_H
+#define IXNPEDLNPEMGRUTILS_P_H
+
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxNpeDl.h"
+#include "IxOsalTypes.h"
+#include "IxNpeDlNpeMgrEcRegisters_p.h"
+
+
+/*
+ * Function Prototypes
+ */
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrInsMemWrite (UINT32 npeBaseAddress,
+ UINT32 insMemAddress,
+ UINT32 insMemData,
+ BOOL verify)
+ *
+ * @brief Writes a word to NPE Instruction memory
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ * @param UINT32 [in] insMemAddress - NPE instruction memory address to write
+ * @param UINT32 [in] insMemData - data to write to instruction memory
+ * @param BOOL [in] verify - if TRUE, verify the memory location is
+ * written successfully.
+ *
+ * This function is used to write a single word of data to a location in NPE
+ * instruction memory. If the <i>verify</i> option is ON, NpeDl will read back
+ * from the memory location to verify that it was written successfully
+ *
+ * @pre
+ *
+ * @post
+ *
+ * @return
+ * - IX_FAIL if verify is TRUE and the memory location was not written
+ * successfully
+ * - IX_SUCCESS otherwise
+ */
+IX_STATUS
+ixNpeDlNpeMgrInsMemWrite (UINT32 npeBaseAddress, UINT32 insMemAddress,
+ UINT32 insMemData, BOOL verify);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrDataMemWrite (UINT32 npeBaseAddress,
+ UINT32 dataMemAddress,
+ UINT32 dataMemData,
+ BOOL verify)
+ *
+ * @brief Writes a word to NPE Data memory
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ * @param UINT32 [in] dataMemAddress - NPE data memory address to write
+ * @param UINT32 [in] dataMemData - data to write to NPE data memory
+ * @param BOOL [in] verify - if TRUE, verify the memory location is
+ * written successfully.
+ *
+ * This function is used to write a single word of data to a location in NPE
+ * data memory. If the <i>verify</i> option is ON, NpeDl will read back from
+ * the memory location to verify that it was written successfully
+ *
+ * @pre
+ *
+ * @post
+ *
+ * @return
+ * - IX_FAIL if verify is TRUE and the memory location was not written
+ * successfully
+ * - IX_SUCCESS otherwise
+ */
+IX_STATUS
+ixNpeDlNpeMgrDataMemWrite (UINT32 npeBaseAddress, UINT32 dataMemAddress,
+ UINT32 dataMemData, BOOL verify);
+
+
+/**
+ * @fn void ixNpeDlNpeMgrExecAccRegWrite (UINT32 npeBaseAddress,
+ UINT32 regAddress,
+ UINT32 regData)
+ *
+ * @brief Writes a word to an NPE Execution Access register
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ * @param UINT32 [in] regAddress - NPE Execution Access register address
+ * @param UINT32 [in] regData - data to write to register
+ *
+ * This function is used to write a single word of data to an NPE Execution
+ * Access register.
+ *
+ * @pre
+ *
+ * @post
+ *
+ * @return none
+ */
+void
+ixNpeDlNpeMgrExecAccRegWrite (UINT32 npeBaseAddress, UINT32 regAddress,
+ UINT32 regData);
+
+
+/**
+ * @fn UINT32 ixNpeDlNpeMgrExecAccRegRead (UINT32 npeBaseAddress,
+ UINT32 regAddress)
+ *
+ * @brief Reads the contents of an NPE Execution Access register
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ * @param UINT32 [in] regAddress - NPE Execution Access register address
+ *
+ * This function is used to read the contents of an NPE Execution
+ * Access register.
+ *
+ * @pre
+ *
+ * @post
+ *
+ * @return The value read from the Execution Access register
+ */
+UINT32
+ixNpeDlNpeMgrExecAccRegRead (UINT32 npeBaseAddress, UINT32 regAddress);
+
+
+/**
+ * @fn void ixNpeDlNpeMgrCommandIssue (UINT32 npeBaseAddress,
+ UINT32 command)
+ *
+ * @brief Issues an NPE Execution Control command
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ * @param UINT32 [in] command - Command to issue
+ *
+ * This function is used to issue a stand-alone NPE Execution Control command
+ * (e.g. command to Stop NPE execution)
+ *
+ * @pre
+ *
+ * @post
+ *
+ * @return none
+ */
+void
+ixNpeDlNpeMgrCommandIssue (UINT32 npeBaseAddress, UINT32 command);
+
+
+/**
+ * @fn void ixNpeDlNpeMgrDebugInstructionPreExec (UINT32 npeBaseAddress)
+ *
+ * @brief Prepare to executes one or more NPE instructions in the Debug
+ * Execution Stack level.
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ *
+ * This function should be called once before a sequence of calls to
+ * ixNpeDlNpeMgrDebugInstructionExec().
+ *
+ * @pre
+ *
+ * @post
+ * - ixNpeDlNpeMgrDebugInstructionPostExec() should be called to restore
+ * registers values altered by this function
+ *
+ * @return none
+ */
+void
+ixNpeDlNpeMgrDebugInstructionPreExec (UINT32 npeBaseAddress);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrDebugInstructionExec (UINT32 npeBaseAddress,
+ UINT32 npeInstruction,
+ UINT32 ctxtNum,
+ UINT32 ldur)
+ *
+ * @brief Executes a single instruction on the NPE at the Debug Execution Stack
+ * level
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ * @param UINT32 [in] npeInstruction - Value to write to INSTR (Instruction)
+ * register
+ * @param UINT32 [in] ctxtNum - context the instruction will be executed
+ * in and which context store it may access
+ * @param UINT32 [in] ldur - Long Immediate Duration, set to non-zero
+ * to use long-immediate mode instruction
+ *
+ * This function is used to execute a single instruction in the NPE pipeline at
+ * the debug Execution Context Stack level. It won't disturb the state of other
+ * executing contexts. Its useful for performing NPE operations, such as
+ * writing to NPE Context Store registers and physical registers, that cannot
+ * be carried out directly using the Configuration Bus registers. This function
+ * will return TIMEOUT status if NPE not responding due to NPS is hang / halt.
+ *
+ * @pre
+ * - The NPE should be stopped and in a clean state
+ * - ixNpeDlNpeMgrDebugInstructionPreExec() should be called once before
+ * a sequential of 1 or more calls to this function
+ *
+ * @post
+ * - ixNpeDlNpeMgrDebugInstructionPostExec() should be called after
+ * a sequence of calls to this function
+ *
+ * @return
+ * - IX_NPEDL_CRITICAL_NPE_ERR if execution of instruction failed / timeout
+ * - IX_SUCCESS otherwise
+ */
+IX_STATUS
+ixNpeDlNpeMgrDebugInstructionExec (UINT32 npeBaseAddress,
+ UINT32 npeInstruction,
+ UINT32 ctxtNum, UINT32 ldur);
+
+
+/**
+ * @fn void ixNpeDlNpeMgrDebugInstructionPostExec (UINT32 npeBaseAddress)
+ *
+ * @brief Clean up after executing one or more NPE instructions in the
+ * Debug Stack Level
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ *
+ * This function should be called once following a sequence of calls to
+ * ixNpeDlNpeMgrDebugInstructionExec().
+ *
+ * @pre
+ * - ixNpeDlNpeMgrDebugInstructionPreExec() was called earlier
+ *
+ * @post
+ * - The Instruction Pipeline will cleared
+ *
+ * @return none
+ */
+void
+ixNpeDlNpeMgrDebugInstructionPostExec (UINT32 npeBaseAddress);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrPhysicalRegWrite (UINT32 npeBaseAddress,
+ UINT32 regAddr,
+ UINT32 regValue,
+ BOOL verify)
+ *
+ * @brief Write one of the 32* 32-bit physical registers in the NPE data
+ * register file
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ * @param UINT32 [in] regAddr - number of the physical register (0-31)*
+ * @param UINT32 [in] regValue - value to write to the physical register
+ * @param BOOL [in] verify - if TRUE, verify the register is written
+ * successfully.
+ *
+ * This function writes a physical register in the NPE data register file.
+ * If the <i>verify</i> option is ON, NpeDl will read back the register to
+ * verify that it was written successfully
+ * *Note that release 1.0 of this software supports 32 physical
+ * registers, but 64 may be supported in future versions.
+ *
+ * @pre
+ * - The NPE should be stopped and in a clean state
+ * - ixNpeDlNpeMgrDebugInstructionPreExec() should be called once before
+ * a sequential of 1 or more calls to this function
+ *
+ * @post
+ * - Contents of REGMAP Context Store register for Context 0 will be altered
+ * - ixNpeDlNpeMgrDebugInstructionPostExec() should be called after
+ * a sequence of calls to this function
+ *
+ * @return
+ * - IX_FAIL if verify is TRUE and the Context Register was not written
+ * successfully
+ * - IX_SUCCESS if Context Register was written successfully
+ * - IX_NPEDL_CRITICAL_NPE_ERR if Context Register was not written
+ * successfully due to timeout error where NPE is not responding
+ */
+IX_STATUS
+ixNpeDlNpeMgrPhysicalRegWrite (UINT32 npeBaseAddress, UINT32 regAddr,
+ UINT32 regValue, BOOL verify);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrCtxtRegWrite (UINT32 npeBaseAddress,
+ UINT32 ctxtNum,
+ IxNpeDlCtxtRegNum ctxtReg,
+ UINT32 ctxtRegVal,
+ BOOL verify)
+ *
+ * @brief Writes a value to a Context Store register on an NPE
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ * @param UINT32 [in] ctxtNum - context store to access
+ * @param IxNpeDlCtxtRegNum [in] ctxtReg - which Context Store reg to write
+ * @param UINT32 [in] ctxtRegVal - value to write to the Context Store
+ * register
+ * @param BOOL [in] verify - if TRUE, verify the register is
+ * written successfully.
+ *
+ * This function writes the contents of a Context Store register in the NPE
+ * register file. If the <i>verify</i> option is ON, NpeDl will read back the
+ * register to verify that it was written successfully
+ *
+ * @pre
+ * - The NPE should be stopped and in a clean state
+ * - ixNpeDlNpeMgrDebugInstructionPreExec() should be called once before
+ * a sequential of 1 or more calls to this function
+ *
+ * @post
+ * - ixNpeDlNpeMgrDebugInstructionPostExec() should be called after
+ * a sequence of calls to this function
+ *
+ * @return
+ * - IX_FAIL if verify is TRUE and the Context Register was not written
+ * successfully
+ * - IX_SUCCESS if Context Register was written successfully
+ * - IX_NPEDL_CRITICAL_NPE_ERR if Context Register was not written
+ * successfully due to timeout error where NPE is not responding
+ */
+IX_STATUS
+ixNpeDlNpeMgrCtxtRegWrite (UINT32 npeBaseAddress, UINT32 ctxtNum,
+ IxNpeDlCtxtRegNum ctxtReg, UINT32 ctxtRegVal,
+ BOOL verify);
+
+
+/**
+ * @fn void ixNpeDlNpeMgrUtilsStatsShow (void)
+ *
+ * @brief This function will display the statistics of the IxNpeDl NpeMgrUtils
+ * module
+ *
+ * @return none
+ */
+void
+ixNpeDlNpeMgrUtilsStatsShow (void);
+
+
+/**
+ * @fn void ixNpeDlNpeMgrUtilsStatsReset (void)
+ *
+ * @brief This function will reset the statistics of the IxNpeDl NpeMgrUtils
+ * module
+ *
+ * @return none
+ */
+void
+ixNpeDlNpeMgrUtilsStatsReset (void);
+
+
+#endif /* IXNPEDLNPEMGRUTILS_P_H */
diff --git a/cpu/ixp/npe/include/IxNpeDlNpeMgr_p.h b/cpu/ixp/npe/include/IxNpeDlNpeMgr_p.h
new file mode 100644
index 0000000..b7fb0f0
--- /dev/null
+++ b/cpu/ixp/npe/include/IxNpeDlNpeMgr_p.h
@@ -0,0 +1,260 @@
+/**
+ * @file IxNpeDlNpeMgr_p.h
+ *
+ * @author Intel Corporation
+ * @date 14 December 2001
+ * @brief This file contains the private API for the NpeMgr module.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+
+/**
+ * @defgroup IxNpeDlNpeMgr_p IxNpeDlNpeMgr_p
+ *
+ * @brief The private API for the IxNpeDl NpeMgr module
+ *
+ * @{
+ */
+
+#ifndef IXNPEDLNPEMGR_P_H
+#define IXNPEDLNPEMGR_P_H
+
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxNpeDl.h"
+#include "IxOsalTypes.h"
+
+
+/*
+ * Function Prototypes
+ */
+
+
+/**
+ * @fn void ixNpeDlNpeMgrInit (void)
+ *
+ * @brief Initialises the NpeMgr module
+ *
+ * @param none
+ *
+ * This function initialises the NpeMgr module.
+ * It should be called before any other function in this module is called.
+ * It only needs to be called once, but can be called multiple times safely.
+ * The code will ASSERT on failure.
+ *
+ * @pre
+ * - It must be called before any other function in this module
+ *
+ * @post
+ * - NPE Configuration Register memory space will be mapped using
+ * IxOsal. This memory will not be unmapped by this module.
+ *
+ * @return none
+ */
+void
+ixNpeDlNpeMgrInit (void);
+
+
+/**
+ * @fn IX_STATUS ixNpeMhNpeMgrUninit (void)
+ *
+ * @brief This function will uninitialise the IxNpeDlNpeMgr sub-component.
+ *
+ * This function will uninitialise the IxNpeDlNpeMgr sub-component.
+ * It should only be called once, and only if the IxNpeDlNpeMgr sub-component
+ * has already been initialised by calling @ref ixNpeDlNpeMgrInit().
+ * No other IxNpeDlNpeMgr sub-component API functions should be called
+ * until @ref ixNpeDlNpeMgrInit() is called again.
+ * If possible, this function should be called before a soft reboot or unloading
+ * a kernel module to perform any clean up operations required for IxNpeMh.
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_FAIL otherwise
+ */
+
+IX_STATUS ixNpeDlNpeMgrUninit (void);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrImageLoad (IxNpeDlNpeId npeId,
+ UINT32 *imageCodePtr,
+ BOOL verify)
+ *
+ * @brief Loads a image of microcode onto an NPE
+ *
+ * @param IxNpeDlNpeId [in] npeId - Id of target NPE
+ * @param UINT32* [in] imageCodePtr - pointer to image code in image to be
+ * downloaded
+ * @param BOOL [in] verify - if TRUE, verify each word written to
+ * NPE memory.
+ *
+ * This function loads a image containing blocks of microcode onto a
+ * particular NPE. If the <i>verify</i> option is ON, NpeDl will read back each
+ * word written and verify that it was written successfully
+ *
+ * @pre
+ * - The NPE should be stopped beforehand
+ *
+ * @post
+ * - The NPE Instruction Pipeline may be flushed clean
+ *
+ * @return
+ * - IX_SUCCESS if the download was successful
+ * - IX_FAIL if the download failed
+ * - IX_NPEDL_CRITICAL_NPE_ERR if the download failed due to timeout error
+ * where NPE is not responding
+ */
+IX_STATUS
+ixNpeDlNpeMgrImageLoad (IxNpeDlNpeId npeId, UINT32 *imageCodePtr,
+ BOOL verify);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrNpeReset (IxNpeDlNpeId npeId)
+ *
+ * @brief sets a NPE to RESET state
+ *
+ * @param IxNpeDlNpeId [in] npeId - id of target NPE
+ *
+ * This function performs a soft NPE reset by writing reset values to the
+ * Configuration Bus Execution Control registers, the Execution Context Stack
+ * registers, the Physical Register file, and the Context Store registers for
+ * each context number. It also clears inFIFO, outFIFO and Watchpoint FIFO.
+ * It does not reset NPE Co-processors.
+ *
+ * @pre
+ * - The NPE should be stopped beforehand
+ *
+ * @post
+ * - NPE NextProgram Counter (NextPC) will be set to a fixed initial value,
+ * such as 0. This should be explicitly set by downloading State
+ * Information before starting NPE Execution.
+ * - The NPE Instruction Pipeline will be in a clean state.
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_FAIL if the operation failed
+ * - IX_NPEDL_CRITICAL_NPE_ERR if the operation failed due to NPE hang
+ */
+IX_STATUS
+ixNpeDlNpeMgrNpeReset (IxNpeDlNpeId npeId);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrNpeStart (IxNpeDlNpeId npeId)
+ *
+ * @brief Starts NPE Execution
+ *
+ * @param IxNpeDlNpeId [in] npeId - Id of target NPE
+ *
+ * Ensures only background Execution Stack Level is Active, clears instruction
+ * pipeline, and starts Execution on a NPE by sending a Start NPE command to
+ * the NPE. Checks the execution status of the NPE to verify that it is
+ * running.
+ *
+ * @pre
+ * - The NPE should be stopped beforehand.
+ * - Note that this function does not set the NPE Next Program Counter
+ * (NextPC), so it should be set beforehand if required by downloading
+ * appropriate State Information.
+ *
+ * @post
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_FAIL otherwise
+ */
+IX_STATUS
+ixNpeDlNpeMgrNpeStart (IxNpeDlNpeId npeId);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrNpeStop (IxNpeDlNpeId npeId)
+ *
+ * @brief Halts NPE Execution
+ *
+ * @param IxNpeDlNpeId [in] npeId - id of target NPE
+ *
+ * Stops execution on an NPE by sending a Stop NPE command to the NPE.
+ * Checks the execution status of the NPE to verify that it has stopped.
+ *
+ * @pre
+ *
+ * @post
+ *
+ * @return
+ * - IX_SUCCESS if the operation was successful
+ * - IX_FAIL otherwise
+ */
+IX_STATUS
+ixNpeDlNpeMgrNpeStop (IxNpeDlNpeId npeId);
+
+
+/**
+ * @fn void ixNpeDlNpeMgrStatsShow (void)
+ *
+ * @brief This function will display statistics of the IxNpeDl NpeMgr module
+ *
+ * @return none
+ */
+void
+ixNpeDlNpeMgrStatsShow (void);
+
+
+/**
+ * @fn void ixNpeDlNpeMgrStatsReset (void)
+ *
+ * @brief This function will reset the statistics of the IxNpeDl NpeMgr module
+ *
+ * @return none
+ */
+void
+ixNpeDlNpeMgrStatsReset (void);
+
+
+#endif /* IXNPEDLIMAGEMGR_P_H */
+
+/**
+ * @} defgroup IxNpeDlNpeMgr_p
+ */
diff --git a/cpu/ixp/npe/include/IxNpeMh.h b/cpu/ixp/npe/include/IxNpeMh.h
new file mode 100644
index 0000000..20ee38b
--- /dev/null
+++ b/cpu/ixp/npe/include/IxNpeMh.h
@@ -0,0 +1,497 @@
+/**
+ * @file IxNpeMh.h
+ *
+ * @date 14 Dec 2001
+ *
+ * @brief This file contains the public API for the IXP400 NPE Message
+ * Handler component.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeMh IXP400 NPE Message Handler (IxNpeMh) API
+ *
+ * @brief The public API for the IXP400 NPE Message Handler component.
+ *
+ * @{
+ */
+
+#ifndef IXNPEMH_H
+#define IXNPEMH_H
+
+#include "IxOsalTypes.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+#define IX_NPEMH_MIN_MESSAGE_ID (0x00) /**< minimum valid message ID */
+#define IX_NPEMH_MAX_MESSAGE_ID (0xFF) /**< maximum valid message ID */
+
+#define IX_NPEMH_SEND_RETRIES_DEFAULT (3) /**< default msg send retries */
+
+
+/**
+ * @def IX_NPEMH_CRITICAL_NPE_ERR
+ *
+ * @brief NpeMH function return value for a Critical NPE error occuring during
+ sending/receiving message. Assume NPE hang / halt if this value is
+ returned.
+ */
+#define IX_NPEMH_CRITICAL_NPE_ERR 2
+
+/**
+ * @enum IxNpeMhNpeId
+ *
+ * @brief The ID of a particular NPE.
+ * @note In this context, for IXP425 Silicon (B0):<br>
+ * - NPE-A has HDLC, HSS, AAL and UTOPIA Coprocessors.<br>
+ * - NPE-B has Ethernet Coprocessor.<br>
+ * - NPE-C has Ethernet, AES, DES and HASH Coprocessors.<br>
+ * - IXP400 Product Line have different combinations of coprocessors.
+ */
+
+typedef enum
+{
+ IX_NPEMH_NPEID_NPEA = 0, /**< ID for NPE-A */
+ IX_NPEMH_NPEID_NPEB, /**< ID for NPE-B */
+ IX_NPEMH_NPEID_NPEC, /**< ID for NPE-C */
+ IX_NPEMH_NUM_NPES /**< Number of NPEs */
+} IxNpeMhNpeId;
+
+/**
+ * @enum IxNpeMhNpeInterrupts
+ *
+ * @brief Indicator specifying whether or not NPE interrupts should drive
+ * receiving of messages from the NPEs.
+ */
+
+typedef enum
+{
+ IX_NPEMH_NPEINTERRUPTS_NO = 0, /**< Don't use NPE interrupts */
+ IX_NPEMH_NPEINTERRUPTS_YES /**< Do use NPE interrupts */
+} IxNpeMhNpeInterrupts;
+
+/**
+ * @brief The 2-word message structure to send to and receive from the
+ * NPEs.
+ */
+
+typedef struct
+{
+ UINT32 data[2]; /**< the actual data of the message */
+} IxNpeMhMessage;
+
+/** message ID */
+typedef UINT32 IxNpeMhMessageId;
+
+/**
+ * @typedef IxNpeMhCallback
+ *
+ * @brief This prototype shows the format of a message callback function.
+ *
+ * This prototype shows the format of a message callback function. The
+ * message callback will be passed the message to be handled and will also
+ * be told from which NPE the message was received. The message callback
+ * will either be registered by ixNpeMhUnsolicitedCallbackRegister() or
+ * passed as a parameter to ixNpeMhMessageWithResponseSend(). It will be
+ * called from within an ISR triggered by the NPE's "outFIFO not empty"
+ * interrupt (see ixNpeMhInitialize()). The parameters passed are the ID
+ * of the NPE that the message was received from, and the message to be
+ * handled.<P><B>Re-entrancy:</B> This function is only a prototype, and
+ * will be implemented by the client. It does not need to be re-entrant.
+ */
+
+typedef void (*IxNpeMhCallback) (IxNpeMhNpeId, IxNpeMhMessage);
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhInitialize (
+ IxNpeMhNpeInterrupts npeInterrupts)
+ *
+ * @brief This function will initialise the IxNpeMh component.
+ *
+ * @param npeInterrupts @ref IxNpeMhNpeInterrupts [in] - This parameter
+ * dictates whether or not the IxNpeMh component will service NPE "outFIFO
+ * not empty" interrupts to trigger receiving and processing of messages
+ * from the NPEs. If not then the client must use ixNpeMhMessagesReceive()
+ * to control message receiving and processing.
+ *
+ * This function will initialise the IxNpeMh component. It should only be
+ * called once, prior to using the IxNpeMh component. The following
+ * actions will be performed by this function:<OL><LI>Initialization of
+ * internal data structures (e.g. solicited and unsolicited callback
+ * tables).</LI><LI>Configuration of the interface with the NPEs (e.g.
+ * enabling of NPE "outFIFO not empty" interrupts).</LI><LI>Registration of
+ * ISRs that will receive and handle messages when the NPEs' "outFIFO not
+ * empty" interrupts fire (if npeInterrupts equals
+ * IX_NPEMH_NPEINTERRUPTS_YES).</LI></OL>
+ *
+ * @return The function returns a status indicating success or failure.
+ */
+
+PUBLIC IX_STATUS ixNpeMhInitialize (
+ IxNpeMhNpeInterrupts npeInterrupts);
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhUnload (void)
+ *
+ * @brief This function will uninitialise the IxNpeMh component.
+ *
+ * This function will uninitialise the IxNpeMh component. It should only be
+ * called once, and only if the IxNpeMh component has already been initialised.
+ * No other IxNpeMh API functions should be called until @ref ixNpeMhInitialize
+ * is called again.
+ * If possible, this function should be called before a soft reboot or unloading
+ * a kernel module to perform any clean up operations required for IxNpeMh.
+ *
+ * The following actions will be performed by this function:
+ * <OL><LI>Unmapping of kernel memory mapped by the function
+ * @ref ixNpeMhInitialize.</LI></OL>
+ *
+ * @return The function returns a status indicating success or failure.
+ */
+
+PUBLIC IX_STATUS ixNpeMhUnload (void);
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhUnsolicitedCallbackRegister (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId messageId,
+ IxNpeMhCallback unsolicitedCallback)
+ *
+ * @brief This function will register an unsolicited callback for a
+ * particular NPE and message ID.
+ *
+ * @param npeId @ref IxNpeMhNpeId [in] - The ID of the NPE whose messages
+ * the unsolicited callback will handle.
+ * @param messageId @ref IxNpeMhMessageId [in] - The ID of the messages the
+ * unsolicited callback will handle.
+ * @param unsolicitedCallback @ref IxNpeMhCallback [in] - The unsolicited
+ * callback function. A value of NULL will deregister any previously
+ * registered callback for this NPE and message ID.
+ *
+ * This function will register an unsolicited message callback for a
+ * particular NPE and message ID.<P>If an unsolicited callback is already
+ * registered for the specified NPE and message ID then the callback will
+ * be overwritten. Only one client will be responsible for handling a
+ * particular message ID associated with a NPE. Registering a NULL
+ * unsolicited callback will deregister any previously registered
+ * callback.<P>The callback function will be called from an ISR that will
+ * be triggered by the NPE's "outFIFO not empty" interrupt (see
+ * ixNpeMhInitialize()) to handle any unsolicited messages of the specific
+ * message ID received from the NPE. Unsolicited messages will be handled
+ * in the order they are received.<P>If no unsolicited callback can be
+ * found for a received message then it is assumed that the message is
+ * solicited.<P>If more than one client may be interested in a particular
+ * unsolicited message then the suggested strategy is to register a
+ * callback for the message that can itself distribute the message to
+ * multiple clients as necessary.<P>See also
+ * ixNpeMhUnsolicitedCallbackForRangeRegister().<P><B>Re-entrancy:</B> This
+ * function will be callable from any thread at any time. IxOsal
+ * will be used for any necessary resource protection.
+ *
+ * @return The function returns a status indicating success or failure.
+ */
+
+PUBLIC IX_STATUS ixNpeMhUnsolicitedCallbackRegister (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId messageId,
+ IxNpeMhCallback unsolicitedCallback);
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhUnsolicitedCallbackForRangeRegister (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId minMessageId,
+ IxNpeMhMessageId maxMessageId,
+ IxNpeMhCallback unsolicitedCallback)
+ *
+ * @brief This function will register an unsolicited callback for a
+ * particular NPE and range of message IDs.
+ *
+ * @param npeId @ref IxNpeMhNpeId [in] - The ID of the NPE whose messages the
+ * unsolicited callback will handle.
+ * @param minMessageId @ref IxNpeMhMessageId [in] - The minimum message ID in
+ * the range of message IDs the unsolicited callback will handle.
+ * @param maxMessageId @ref IxNpeMhMessageId [in] - The maximum message ID in
+ * the range of message IDs the unsolicited callback will handle.
+ * @param unsolicitedCallback @ref IxNpeMhCallback [in] - The unsolicited
+ * callback function. A value of NULL will deregister any previously
+ * registered callback(s) for this NPE and range of message IDs.
+ *
+ * This function will register an unsolicited callback for a particular NPE
+ * and range of message IDs. It is a convenience function that is
+ * effectively the same as calling ixNpeMhUnsolicitedCallbackRegister() for
+ * each ID in the specified range. See
+ * ixNpeMhUnsolicitedCallbackRegister() for more
+ * information.<P><B>Re-entrancy:</B> This function will be callable from
+ * any thread at any time. IxOsal will be used for any necessary
+ * resource protection.
+ *
+ * @return The function returns a status indicating success or failure.
+ */
+
+PUBLIC IX_STATUS ixNpeMhUnsolicitedCallbackForRangeRegister (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId minMessageId,
+ IxNpeMhMessageId maxMessageId,
+ IxNpeMhCallback unsolicitedCallback);
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhMessageSend (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage message,
+ UINT32 maxSendRetries)
+ *
+ * @brief This function will send a message to a particular NPE.
+ *
+ * @param npeId @ref IxNpeMhNpeId [in] - The ID of the NPE to send the message
+ * to.
+ * @param message @ref IxNpeMhMessage [in] - The message to send.
+ * @param maxSendRetries UINT32 [in] - Max num. of retries to perform
+ * if the NPE's inFIFO is full.
+ *
+ * This function will send a message to a particular NPE. It will be the
+ * client's responsibility to ensure that the message is properly formed.
+ * The return status will signify to the client if the message was
+ * successfully sent or not.<P>If the message is sent to the NPE then this
+ * function will return a status of success. Note that this will only mean
+ * the message has been placed in the NPE's inFIFO. There will be no way
+ * of knowing that the NPE has actually read the message, but once in the
+ * incoming message queue it will be safe to assume that the NPE will
+ * process it.
+ * <P>The inFIFO may fill up sometimes if the Xscale is sending messages
+ * faster than the NPE can handle them. This forces us to retry attempts
+ * to send the message until the NPE services the inFIFO. The client should
+ * specify a ceiling value for the number of retries suitable to their
+ * needs. IX_NPEMH_SEND_RETRIES_DEFAULT can be used as a default value for
+ * the <i>maxSendRetries</i> parameter for this function. Each retry
+ * exceeding this default number will incur a blocking delay of 1 microsecond,
+ * to avoid consuming too much AHB bus bandwidth while performing retries.
+ * <P>Note this function <B>must</B> only be used for messages.
+ * that do not solicit responses. If the message being sent will solicit a
+ * response then the ixNpeMhMessageWithResponseSend() function <B>must</B>
+ * be used to ensure that the response is correctly
+ * handled. <P> This function will return timeout status if NPE hang / halt
+ * while sending message. The timeout error is not related to the
+ * <i>maxSendRetries</i> as mentioned above. The timeout error will only occur
+ * if the first word of the message has been sent to NPE (not exceeding
+ * <i>maxSendRetries</i> when sending 1st message word), but the second word of
+ * the message can't be written to NPE's inFIFO due to NPE hang / halt after
+ * maximum waiting time (IX_NPE_MH_MAX_NUM_OF_RETRIES).
+ * <P><B>Re-entrancy:</B> This function will be callable from any
+ * thread at any time. IxOsal will be used for any necessary
+ * resource protection.
+ *
+ * @return The function returns a status indicating success, failure or timeout.
+ */
+
+PUBLIC IX_STATUS ixNpeMhMessageSend (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage message,
+ UINT32 maxSendRetries);
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhMessageWithResponseSend (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage message,
+ IxNpeMhMessageId solicitedMessageId,
+ IxNpeMhCallback solicitedCallback,
+ UINT32 maxSendRetries)
+ *
+ * @brief This function is equivalent to the ixNpeMhMessageSend() function,
+ * but must be used when the message being sent will solicited a response.
+ *
+ * @param npeId @ref IxNpeMhNpeId [in] - The ID of the NPE to send the message
+ * to.
+ * @param message @ref IxNpeMhMessage [in] - The message to send.
+ * @param solicitedMessageId @ref IxNpeMhMessageId [in] - The ID of the
+ * solicited response message.
+ * @param solicitedCallback @ref IxNpeMhCallback [in] - The function to use to
+ * pass the response message back to the client. A value of NULL will
+ * cause the response message to be discarded.
+ * @param maxSendRetries UINT32 [in] - Max num. of retries to perform
+ * if the NPE's inFIFO is full.
+ *
+ * This function is equivalent to the ixNpeMhMessageSend() function, but
+ * must be used when the message being sent will solicited a
+ * response.<P>The client must specify the ID of the solicited response
+ * message to allow the response to be recognised when it is received. The
+ * client must also specify a callback function to handle the received
+ * response. The IxNpeMh component will not offer the facility to send a
+ * message to a NPE and receive a response within the same context.<P>Note
+ * if the client is not interested in the response, specifying a NULL
+ * callback will cause the response message to be discarded.<P>The
+ * solicited callback will be stored and called some time later from an ISR
+ * that will be triggered by the NPE's "outFIFO not empty" interrupt (see
+ * ixNpeMhInitialize()) to handle the response message corresponding to the
+ * message sent. Response messages will be handled in the order they are
+ * received.<P>
+ * <P>The inFIFO may fill up sometimes if the Xscale is sending messages
+ * faster than the NPE can handle them. This forces us to retry attempts
+ * to send the message until the NPE services the inFIFO. The client should
+ * specify a ceiling value for the number of retries suitable to their
+ * needs. IX_NPEMH_SEND_RETRIES_DEFAULT can be used as a default value for
+ * the <i>maxSendRetries</i> parameter for this function. Each retry
+ * exceeding this default number will incur a blocking delay of 1 microsecond,
+ * to avoid consuming too much AHB bus bandwidth while performing retries.
+ * <P> This function will return timeout status if NPE hang / halt
+ * while sending message. The timeout error is not related to the
+ * <i>maxSendRetries</i> as mentioned above. The timeout error will only occur
+ * if the first word of the message has been sent to NPE (not exceeding
+ * <i>maxSendRetries</i> when sending 1st message word), but the second word of
+ * the message can't be written to NPE's inFIFO due to NPE hang / halt after
+ * maximum waiting time (IX_NPE_MH_MAX_NUM_OF_RETRIES).
+ * <P><B>Re-entrancy:</B> This function will be callable from any
+ * thread at any time. IxOsal will be used for any necessary
+ * resource protection.
+ *
+ * @return The function returns a status indicating success or failure.
+ */
+
+PUBLIC IX_STATUS ixNpeMhMessageWithResponseSend (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage message,
+ IxNpeMhMessageId solicitedMessageId,
+ IxNpeMhCallback solicitedCallback,
+ UINT32 maxSendRetries);
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhMessagesReceive (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function will receive messages from a particular NPE and
+ * pass each message to the client via a solicited callback (for solicited
+ * messages) or an unsolicited callback (for unsolicited messages).
+ *
+ * @param npeId @ref IxNpeMhNpeId [in] - The ID of the NPE to receive and
+ * process messages from.
+ *
+ * This function will receive messages from a particular NPE and pass each
+ * message to the client via a solicited callback (for solicited messages)
+ * or an unsolicited callback (for unsolicited messages).<P>If the IxNpeMh
+ * component is initialised to service NPE "outFIFO not empty" interrupts
+ * (see ixNpeMhInitialize()) then there is no need to call this function.
+ * This function is only provided as an alternative mechanism to control
+ * the receiving and processing of messages from the NPEs.<P> This function
+ * will return timeout status if NPE hang / halt while receiving message. The
+ * timeout error will only occur if this function has read the first word of
+ * the message and can't read second word of the message from NPE's outFIFO
+ * after maximum retries (IX_NPE_MH_MAX_NUM_OF_RETRIES).
+ * <P>Note this function cannot be called from within
+ * an ISR as it will use resource protection mechanisms.<P><B>Re-entrancy:</B>
+ * This function will be callable from any thread at any time. IxOsal will be
+ * used for any necessary resource protection.
+ *
+ * @return The function returns a status indicating success, failure or timeout.
+ */
+
+PUBLIC IX_STATUS ixNpeMhMessagesReceive (
+ IxNpeMhNpeId npeId);
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhShow (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function will display the current state of the IxNpeMh
+ * component.
+ *
+ * <B>Re-entrancy:</B> This function will be callable from
+ * any thread at any time. However, no resource protection will be used
+ * so as not to impact system performance. As this function is only
+ * reading statistical information then this is acceptable.
+ *
+ * @param npeId @ref IxNpeMhNpeId [in] - The ID of the NPE to display state
+ * information for.
+ *
+ * @return The function returns a status indicating success or failure.
+ */
+
+PUBLIC IX_STATUS ixNpeMhShow (
+ IxNpeMhNpeId npeId);
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhShowReset (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function will reset the current state of the IxNpeMh
+ * component.
+ *
+ * <B>Re-entrancy:</B> This function will be callable from
+ * any thread at any time. However, no resource protection will be used
+ * so as not to impact system performance. As this function is only
+ * writing statistical information then this is acceptable.
+ *
+ * @param npeId @ref IxNpeMhNpeId [in] - The ID of the NPE to reset state
+ * information for.
+ *
+ * @return The function returns a status indicating success or failure.
+ */
+
+PUBLIC IX_STATUS ixNpeMhShowReset (
+ IxNpeMhNpeId npeId);
+
+#endif /* IXNPEMH_H */
+
+/**
+ * @} defgroup IxNpeMh
+ */
diff --git a/cpu/ixp/npe/include/IxNpeMhConfig_p.h b/cpu/ixp/npe/include/IxNpeMhConfig_p.h
new file mode 100644
index 0000000..375b346
--- /dev/null
+++ b/cpu/ixp/npe/include/IxNpeMhConfig_p.h
@@ -0,0 +1,555 @@
+/**
+ * @file IxNpeMhConfig_p.h
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the private API for the Configuration module.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeMhConfig_p IxNpeMhConfig_p
+ *
+ * @brief The private API for the Configuration module.
+ *
+ * @{
+ */
+
+#ifndef IXNPEMHCONFIG_P_H
+#define IXNPEMHCONFIG_P_H
+
+#include "IxOsal.h"
+
+#include "IxNpeMh.h"
+#include "IxNpeMhMacros_p.h"
+
+/*
+ * inline definition
+ */
+/* enable function inlining for performances */
+#ifdef IXNPEMHSOLICITEDCBMGR_C
+/* Non-inline functions will be defined in this translation unit.
+ Reason is that in GNU Compiler, if the Optimization is turn off, all extern inline
+ functions will not be compiled.
+*/
+# ifndef __wince
+# ifndef IXNPEMHCONFIG_INLINE
+# define IXNPEMHCONFIG_INLINE
+# endif
+# else
+# ifndef IXNPEMHCONFIG_INLINE
+# define IXNPEMHCONFIG_INLINE IX_OSAL_INLINE_EXTERN
+# endif
+# endif /* __wince*/
+
+#else
+
+# ifndef IXNPEMHCONFIG_INLINE
+# define IXNPEMHCONFIG_INLINE IX_OSAL_INLINE_EXTERN
+# endif /* IXNPEMHCONFIG_INLINE */
+#endif /* IXNPEMHSOLICITEDCBMGR_C */
+/*
+ * Typedefs and #defines, etc.
+ */
+
+typedef void (*IxNpeMhConfigIsr) (int); /**< ISR function pointer */
+
+/**
+ * @struct IxNpeMhConfigNpeInfo
+ *
+ * @brief This structure is used to maintain the configuration information
+ * associated with an NPE.
+ */
+
+typedef struct
+{
+ IxOsalMutex mutex; /**< mutex */
+ UINT32 interruptId; /**< interrupt ID */
+ UINT32 virtualRegisterBase; /**< register virtual base address */
+ UINT32 statusRegister; /**< status register virtual address */
+ UINT32 controlRegister; /**< control register virtual address */
+ UINT32 inFifoRegister; /**< inFIFO register virutal address */
+ UINT32 outFifoRegister; /**< outFIFO register virtual address */
+ IxNpeMhConfigIsr isr; /**< isr routine for handling interrupt */
+ BOOL oldInterruptState; /**< old interrupt state (TRUE => enabled) */
+} IxNpeMhConfigNpeInfo;
+
+
+/*
+ * #defines for function return types, etc.
+ */
+
+/**< NPE register base address */
+#define IX_NPEMH_NPE_BASE (IX_OSAL_IXP400_PERIPHERAL_PHYS_BASE)
+
+#define IX_NPEMH_NPEA_OFFSET (0x6000) /**< NPE-A register base offset */
+#define IX_NPEMH_NPEB_OFFSET (0x7000) /**< NPE-B register base offset */
+#define IX_NPEMH_NPEC_OFFSET (0x8000) /**< NPE-C register base offset */
+
+#define IX_NPEMH_NPESTAT_OFFSET (0x002C) /**< NPE status register offset */
+#define IX_NPEMH_NPECTL_OFFSET (0x0030) /**< NPE control register offset */
+#define IX_NPEMH_NPEFIFO_OFFSET (0x0038) /**< NPE FIFO register offset */
+
+/** NPE-A register base address */
+#define IX_NPEMH_NPEA_BASE (IX_NPEMH_NPE_BASE + IX_NPEMH_NPEA_OFFSET)
+/** NPE-B register base address */
+#define IX_NPEMH_NPEB_BASE (IX_NPEMH_NPE_BASE + IX_NPEMH_NPEB_OFFSET)
+/** NPE-C register base address */
+#define IX_NPEMH_NPEC_BASE (IX_NPEMH_NPE_BASE + IX_NPEMH_NPEC_OFFSET)
+
+/* NPE-A configuration */
+
+/** NPE-A interrupt */
+#define IX_NPEMH_NPEA_INT (IX_OSAL_IXP400_NPEA_IRQ_LVL)
+/** NPE-A FIFO register */
+#define IX_NPEMH_NPEA_FIFO (IX_NPEMH_NPEA_BASE + IX_NPEMH_NPEFIFO_OFFSET)
+/** NPE-A control register */
+#define IX_NPEMH_NPEA_CTL (IX_NPEMH_NPEA_BASE + IX_NPEMH_NPECTL_OFFSET)
+/** NPE-A status register */
+#define IX_NPEMH_NPEA_STAT (IX_NPEMH_NPEA_BASE + IX_NPEMH_NPESTAT_OFFSET)
+
+/* NPE-B configuration */
+
+/** NPE-B interrupt */
+#define IX_NPEMH_NPEB_INT (IX_OSAL_IXP400_NPEB_IRQ_LVL)
+/** NPE-B FIFO register */
+#define IX_NPEMH_NPEB_FIFO (IX_NPEMH_NPEB_BASE + IX_NPEMH_NPEFIFO_OFFSET)
+/** NPE-B control register */
+#define IX_NPEMH_NPEB_CTL (IX_NPEMH_NPEB_BASE + IX_NPEMH_NPECTL_OFFSET)
+/** NPE-B status register */
+#define IX_NPEMH_NPEB_STAT (IX_NPEMH_NPEB_BASE + IX_NPEMH_NPESTAT_OFFSET)
+
+/* NPE-C configuration */
+
+/** NPE-C interrupt */
+#define IX_NPEMH_NPEC_INT (IX_OSAL_IXP400_NPEC_IRQ_LVL)
+/** NPE-C FIFO register */
+#define IX_NPEMH_NPEC_FIFO (IX_NPEMH_NPEC_BASE + IX_NPEMH_NPEFIFO_OFFSET)
+/** NPE-C control register */
+#define IX_NPEMH_NPEC_CTL (IX_NPEMH_NPEC_BASE + IX_NPEMH_NPECTL_OFFSET)
+/** NPE-C status register */
+#define IX_NPEMH_NPEC_STAT (IX_NPEMH_NPEC_BASE + IX_NPEMH_NPESTAT_OFFSET)
+
+/* NPE control register bit definitions */
+#define IX_NPEMH_NPE_CTL_OFE (1 << 16) /**< OutFifoEnable */
+#define IX_NPEMH_NPE_CTL_IFE (1 << 17) /**< InFifoEnable */
+#define IX_NPEMH_NPE_CTL_OFEWE (1 << 24) /**< OutFifoEnableWriteEnable */
+#define IX_NPEMH_NPE_CTL_IFEWE (1 << 25) /**< InFifoEnableWriteEnable */
+
+/* NPE status register bit definitions */
+#define IX_NPEMH_NPE_STAT_OFNE (1 << 16) /**< OutFifoNotEmpty */
+#define IX_NPEMH_NPE_STAT_IFNF (1 << 17) /**< InFifoNotFull */
+#define IX_NPEMH_NPE_STAT_OFNF (1 << 18) /**< OutFifoNotFull */
+#define IX_NPEMH_NPE_STAT_IFNE (1 << 19) /**< InFifoNotEmpty */
+#define IX_NPEMH_NPE_STAT_MBINT (1 << 20) /**< Mailbox interrupt */
+#define IX_NPEMH_NPE_STAT_IFINT (1 << 21) /**< InFifo interrupt */
+#define IX_NPEMH_NPE_STAT_OFINT (1 << 22) /**< OutFifo interrupt */
+#define IX_NPEMH_NPE_STAT_WFINT (1 << 23) /**< WatchFifo interrupt */
+
+
+/**
+ * Variable declarations. Externs are followed by static variables.
+ */
+extern IxNpeMhConfigNpeInfo ixNpeMhConfigNpeInfo[IX_NPEMH_NUM_NPES];
+
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ * @fn void ixNpeMhConfigInitialize (
+ IxNpeMhNpeInterrupts npeInterrupts)
+ *
+ * @brief This function initialises the Configuration module.
+ *
+ * @param IxNpeMhNpeInterrupts npeInterrupts (in) - whether or not to
+ * service the NPE "outFIFO not empty" interrupts.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhConfigInitialize (
+ IxNpeMhNpeInterrupts npeInterrupts);
+
+/**
+ * @fn void ixNpeMhConfigUninit (void)
+ *
+ * @brief This function uninitialises the Configuration module.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhConfigUninit (void);
+
+/**
+ * @fn void ixNpeMhConfigIsrRegister (
+ IxNpeMhNpeId npeId,
+ IxNpeMhConfigIsr isr)
+ *
+ * @brief This function registers an ISR to handle NPE "outFIFO not
+ * empty" interrupts.
+ *
+ * @param IxNpeMhNpeId npeId (in) - the ID of the NPE whose interrupt will
+ * be handled.
+ * @param IxNpeMhConfigIsr isr (in) - the ISR function pointer that the
+ * interrupt will trigger.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhConfigIsrRegister (
+ IxNpeMhNpeId npeId,
+ IxNpeMhConfigIsr isr);
+
+/**
+ * @fn BOOL ixNpeMhConfigNpeInterruptEnable (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function enables a NPE's "outFIFO not empty" interrupt.
+ *
+ * @param IxNpeMhNpeId npeId (in) - the ID of the NPE whose interrupt will
+ * be enabled.
+ *
+ * @return Returns the previous state of the interrupt (TRUE => enabled).
+ */
+
+BOOL ixNpeMhConfigNpeInterruptEnable (
+ IxNpeMhNpeId npeId);
+
+/**
+ * @fn BOOL ixNpeMhConfigNpeInterruptDisable (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function disables a NPE's "outFIFO not empty" interrupt
+ *
+ * @param IxNpeMhNpeId npeId (in) - the ID of the NPE whose interrupt will
+ * be disabled.
+ *
+ * @return Returns the previous state of the interrupt (TRUE => enabled).
+ */
+
+BOOL ixNpeMhConfigNpeInterruptDisable (
+ IxNpeMhNpeId npeId);
+
+/**
+ * @fn IxNpeMhMessageId ixNpeMhConfigMessageIdGet (
+ IxNpeMhMessage message)
+ *
+ * @brief This function gets the ID of a message.
+ *
+ * @param IxNpeMhMessage message (in) - the message to get the ID of.
+ *
+ * @return the ID of the message
+ */
+
+IxNpeMhMessageId ixNpeMhConfigMessageIdGet (
+ IxNpeMhMessage message);
+
+/**
+ * @fn BOOL ixNpeMhConfigNpeIdIsValid (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function checks to see if a NPE ID is valid.
+ *
+ * @param IxNpeMhNpeId npeId (in) - the NPE ID to validate.
+ *
+ * @return True if the NPE ID is valid, otherwise False.
+ */
+
+BOOL ixNpeMhConfigNpeIdIsValid (
+ IxNpeMhNpeId npeId);
+
+/**
+ * @fn void ixNpeMhConfigLockGet (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function gets a lock for exclusive NPE interaction, and
+ * disables the NPE's "outFIFO not empty" interrupt.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE for which to get the
+ * lock and disable its interrupt.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhConfigLockGet (
+ IxNpeMhNpeId npeId);
+
+/**
+ * @fn void ixNpeMhConfigLockRelease (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function releases a lock for exclusive NPE interaction, and
+ * enables the NPE's "outFIFO not empty" interrupt.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE for which to release
+ * the lock and enable its interrupt.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhConfigLockRelease (
+ IxNpeMhNpeId npeId);
+
+/**
+ * @fn BOOL ixNpeMhConfigInFifoIsEmpty (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This inline function checks if a NPE's inFIFO is empty.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE for which the inFIFO
+ * will be checked.
+ *
+ * @return True if the inFIFO is empty, otherwise False.
+ */
+
+IXNPEMHCONFIG_INLINE BOOL ixNpeMhConfigInFifoIsEmpty (
+ IxNpeMhNpeId npeId);
+
+/**
+ * @fn BOOL ixNpeMhConfigInFifoIsFull (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This inline function checks if a NPE's inFIFO is full.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE for which the inFIFO
+ * will be checked.
+ *
+ * @return True if the inFIFO is full, otherwise False.
+ */
+
+IXNPEMHCONFIG_INLINE BOOL ixNpeMhConfigInFifoIsFull (
+ IxNpeMhNpeId npeId);
+
+/**
+ * @fn BOOL ixNpeMhConfigOutFifoIsEmpty (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This inline function checks if a NPE's outFIFO is empty.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE for which the outFIFO
+ * will be checked.
+ *
+ * @return True if the outFIFO is empty, otherwise False.
+ */
+
+IXNPEMHCONFIG_INLINE BOOL ixNpeMhConfigOutFifoIsEmpty (
+ IxNpeMhNpeId npeId);
+
+/**
+ * @fn BOOL ixNpeMhConfigOutFifoIsFull (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This inline function checks if a NPE's outFIFO is full.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE for which the outFIFO
+ * will be checked.
+ *
+ * @return True if the outFIFO is full, otherwise False.
+ */
+
+IXNPEMHCONFIG_INLINE BOOL ixNpeMhConfigOutFifoIsFull (
+ IxNpeMhNpeId npeId);
+
+/**
+ * @fn IX_STATUS ixNpeMhConfigInFifoWrite (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage message)
+ *
+ * @brief This function writes a message to a NPE's inFIFO. The caller
+ * must first check that the NPE's inFifo is not full. After writing the first
+ * word of the message, this function will keep polling NPE's inFIFO is not
+ * full to write the second word. If inFIFO is not available after maximum
+ * retries (IX_NPE_MH_MAX_NUM_OF_RETRIES), this function will return TIMEOUT
+ * status to indicate NPE hang / halt.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE for which the inFIFO
+ * will be written to.
+ * @param IxNpeMhMessage message (in) - The message to write.
+ *
+ * @return The function returns a status indicating success, failure or timeout.
+ */
+
+IX_STATUS ixNpeMhConfigInFifoWrite (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage message);
+
+/**
+ * @fn IX_STATUS ixNpeMhConfigOutFifoRead (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage *message)
+ *
+ * @brief This function reads a message from a NPE's outFIFO. The caller
+ * must first check that the NPE's outFifo is not empty. After reading the first
+ * word of the message, this function will keep polling NPE's outFIFO is not
+ * empty to read the second word. If outFIFO is empty after maximum
+ * retries (IX_NPE_MH_MAX_NUM_OF_RETRIES), this function will return TIMEOUT
+ * status to indicate NPE hang / halt.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE for which the outFIFO
+ * will be read from.
+ * @param IxNpeMhMessage message (out) - The message read.
+ *
+ * @return The function returns a status indicating success, failure or timeout.
+ */
+
+IX_STATUS ixNpeMhConfigOutFifoRead (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage *message);
+
+/**
+ * @fn void ixNpeMhConfigShow (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function will display the current state of the Configuration
+ * module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to display state
+ * information for.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhConfigShow (
+ IxNpeMhNpeId npeId);
+
+/**
+ * @fn void ixNpeMhConfigShowReset (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function will reset the current state of the Configuration
+ * module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to reset state
+ * information for.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhConfigShowReset (
+ IxNpeMhNpeId npeId);
+
+/*
+ * Inline functions
+ */
+
+/*
+ * This inline function checks if a NPE's inFIFO is empty.
+ */
+
+IXNPEMHCONFIG_INLINE
+BOOL ixNpeMhConfigInFifoIsEmpty (
+ IxNpeMhNpeId npeId)
+{
+ UINT32 ifne;
+ volatile UINT32 *statusReg =
+ (UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister;
+
+ /* get the IFNE (InFifoNotEmpty) bit of the status register */
+ IX_NPEMH_REGISTER_READ_BITS (statusReg, &ifne, IX_NPEMH_NPE_STAT_IFNE);
+
+ /* if the IFNE status bit is unset then the inFIFO is empty */
+ return (ifne == 0);
+}
+
+
+/*
+ * This inline function checks if a NPE's inFIFO is full.
+ */
+IXNPEMHCONFIG_INLINE
+BOOL ixNpeMhConfigInFifoIsFull (
+ IxNpeMhNpeId npeId)
+{
+ UINT32 ifnf;
+ volatile UINT32 *statusReg =
+ (UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister;
+
+ /* get the IFNF (InFifoNotFull) bit of the status register */
+ IX_NPEMH_REGISTER_READ_BITS (statusReg, &ifnf, IX_NPEMH_NPE_STAT_IFNF);
+
+ /* if the IFNF status bit is unset then the inFIFO is full */
+ return (ifnf == 0);
+}
+
+
+/*
+ * This inline function checks if a NPE's outFIFO is empty.
+ */
+IXNPEMHCONFIG_INLINE
+BOOL ixNpeMhConfigOutFifoIsEmpty (
+ IxNpeMhNpeId npeId)
+{
+ UINT32 ofne;
+ volatile UINT32 *statusReg =
+ (UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister;
+
+ /* get the OFNE (OutFifoNotEmpty) bit of the status register */
+ IX_NPEMH_REGISTER_READ_BITS (statusReg, &ofne, IX_NPEMH_NPE_STAT_OFNE);
+
+ /* if the OFNE status bit is unset then the outFIFO is empty */
+ return (ofne == 0);
+}
+
+/*
+ * This inline function checks if a NPE's outFIFO is full.
+ */
+IXNPEMHCONFIG_INLINE
+BOOL ixNpeMhConfigOutFifoIsFull (
+ IxNpeMhNpeId npeId)
+{
+ UINT32 ofnf;
+ volatile UINT32 *statusReg =
+ (UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister;
+
+ /* get the OFNF (OutFifoNotFull) bit of the status register */
+ IX_NPEMH_REGISTER_READ_BITS (statusReg, &ofnf, IX_NPEMH_NPE_STAT_OFNF);
+
+ /* if the OFNF status bit is unset then the outFIFO is full */
+ return (ofnf == 0);
+}
+
+#endif /* IXNPEMHCONFIG_P_H */
+
+/**
+ * @} defgroup IxNpeMhConfig_p
+ */
diff --git a/cpu/ixp/npe/include/IxNpeMhMacros_p.h b/cpu/ixp/npe/include/IxNpeMhMacros_p.h
new file mode 100644
index 0000000..68f34ef
--- /dev/null
+++ b/cpu/ixp/npe/include/IxNpeMhMacros_p.h
@@ -0,0 +1,296 @@
+/**
+ * @file IxNpeMhMacros_p.h
+ *
+ * @author Intel Corporation
+ * @date 21 Jan 2002
+ *
+ * @brief This file contains the macros for the IxNpeMh component.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeMhMacros_p IxNpeMhMacros_p
+ *
+ * @brief Macros for the IxNpeMh component.
+ *
+ * @{
+ */
+
+#ifndef IXNPEMHMACROS_P_H
+#define IXNPEMHMACROS_P_H
+
+/* if we are running as a unit test */
+#ifdef IX_UNIT_TEST
+#undef NDEBUG
+#endif /* #ifdef IX_UNIT_TEST */
+
+#include "IxOsal.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+#define IX_NPEMH_SHOW_TEXT_WIDTH (40) /**< text width for stats display */
+#define IX_NPEMH_SHOW_STAT_WIDTH (10) /**< stat width for stats display */
+
+/**
+ * @def IX_NPEMH_SHOW
+ *
+ * @brief Macro for displaying a stat preceded by a textual description.
+ */
+
+#define IX_NPEMH_SHOW(TEXT, STAT) \
+ ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, \
+ "%-40s: %10d\n", (int) TEXT, (int) STAT, 0, 0, 0, 0)
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ * @typedef IxNpeMhTraceTypes
+ *
+ * @brief Enumeration defining IxNpeMh trace levels
+ */
+
+typedef enum
+{
+ IX_NPEMH_TRACE_OFF = IX_OSAL_LOG_LVL_NONE, /**< no trace */
+ IX_NPEMH_WARNING = IX_OSAL_LOG_LVL_WARNING, /**< warning */
+ IX_NPEMH_DEBUG = IX_OSAL_LOG_LVL_MESSAGE, /**< debug */
+ IX_NPEMH_FN_ENTRY_EXIT = IX_OSAL_LOG_LVL_DEBUG3 /**< function entry/exit */
+} IxNpeMhTraceTypes;
+
+#ifdef IX_UNIT_TEST
+#define IX_NPEMH_TRACE_LEVEL (IX_NPEMH_FN_ENTRY_EXIT) /**< trace level */
+#else
+#define IX_NPEMH_TRACE_LEVEL (IX_NPEMH_TRACE_OFF) /**< trace level */
+#endif
+
+/**
+ * @def IX_NPEMH_TRACE0
+ *
+ * @brief Trace macro taking 0 arguments.
+ */
+
+#define IX_NPEMH_TRACE0(LEVEL, STR) \
+ IX_NPEMH_TRACE6(LEVEL, STR, 0, 0, 0, 0, 0, 0)
+
+/**
+ * @def IX_NPEMH_TRACE1
+ *
+ * @brief Trace macro taking 1 argument.
+ */
+
+#define IX_NPEMH_TRACE1(LEVEL, STR, ARG1) \
+ IX_NPEMH_TRACE6(LEVEL, STR, ARG1, 0, 0, 0, 0, 0)
+
+/**
+ * @def IX_NPEMH_TRACE2
+ *
+ * @brief Trace macro taking 2 arguments.
+ */
+
+#define IX_NPEMH_TRACE2(LEVEL, STR, ARG1, ARG2) \
+ IX_NPEMH_TRACE6(LEVEL, STR, ARG1, ARG2, 0, 0, 0, 0)
+
+/**
+ * @def IX_NPEMH_TRACE3
+ *
+ * @brief Trace macro taking 3 arguments.
+ */
+
+#define IX_NPEMH_TRACE3(LEVEL, STR, ARG1, ARG2, ARG3) \
+ IX_NPEMH_TRACE6(LEVEL, STR, ARG1, ARG2, ARG3, 0, 0, 0)
+
+/**
+ * @def IX_NPEMH_TRACE4
+ *
+ * @brief Trace macro taking 4 arguments.
+ */
+
+#define IX_NPEMH_TRACE4(LEVEL, STR, ARG1, ARG2, ARG3, ARG4) \
+ IX_NPEMH_TRACE6(LEVEL, STR, ARG1, ARG2, ARG3, ARG4, 0, 0)
+
+/**
+ * @def IX_NPEMH_TRACE5
+ *
+ * @brief Trace macro taking 5 arguments.
+ */
+
+#define IX_NPEMH_TRACE5(LEVEL, STR, ARG1, ARG2, ARG3, ARG4, ARG5) \
+ IX_NPEMH_TRACE6(LEVEL, STR, ARG1, ARG2, ARG3, ARG4, ARG5, 0)
+
+/**
+ * @def IX_NPEMH_TRACE6
+ *
+ * @brief Trace macro taking 6 arguments.
+ */
+
+#define IX_NPEMH_TRACE6(LEVEL, STR, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \
+{ \
+ if (LEVEL <= IX_NPEMH_TRACE_LEVEL) \
+ { \
+ (void) ixOsalLog (LEVEL, IX_OSAL_LOG_DEV_STDOUT, (STR), \
+ (int)(ARG1), (int)(ARG2), (int)(ARG3), \
+ (int)(ARG4), (int)(ARG5), (int)(ARG6)); \
+ } \
+}
+
+/**
+ * @def IX_NPEMH_ERROR_REPORT
+ *
+ * @brief Error reporting facility.
+ */
+
+#define IX_NPEMH_ERROR_REPORT(STR) \
+{ \
+ (void) ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, \
+ (STR), 0, 0, 0, 0, 0, 0); \
+}
+
+/* if we are running on XScale, i.e. real environment */
+#if CPU==XSCALE
+
+/**
+ * @def IX_NPEMH_REGISTER_READ
+ *
+ * @brief This macro reads a memory-mapped register.
+ */
+
+#define IX_NPEMH_REGISTER_READ(registerAddress, value) \
+{ \
+ *value = IX_OSAL_READ_LONG(registerAddress); \
+}
+
+/**
+ * @def IX_NPEMH_REGISTER_READ_BITS
+ *
+ * @brief This macro partially reads a memory-mapped register.
+ */
+
+#define IX_NPEMH_REGISTER_READ_BITS(registerAddress, value, mask) \
+{ \
+ *value = (IX_OSAL_READ_LONG(registerAddress) & mask); \
+}
+
+/**
+ * @def IX_NPEMH_REGISTER_WRITE
+ *
+ * @brief This macro writes a memory-mapped register.
+ */
+
+#define IX_NPEMH_REGISTER_WRITE(registerAddress, value) \
+{ \
+ IX_OSAL_WRITE_LONG(registerAddress, value); \
+}
+
+/**
+ * @def IX_NPEMH_REGISTER_WRITE_BITS
+ *
+ * @brief This macro partially writes a memory-mapped register.
+ */
+
+#define IX_NPEMH_REGISTER_WRITE_BITS(registerAddress, value, mask) \
+{ \
+ UINT32 orig = IX_OSAL_READ_LONG(registerAddress); \
+ orig &= (~mask); \
+ orig |= (value & mask); \
+ IX_OSAL_WRITE_LONG(registerAddress, orig); \
+}
+
+
+/* if we are running as a unit test */
+#else /* #if CPU==XSCALE */
+
+#include "IxNpeMhTestRegister.h"
+
+/**
+ * @def IX_NPEMH_REGISTER_READ
+ *
+ * @brief This macro reads a memory-mapped register.
+ */
+
+#define IX_NPEMH_REGISTER_READ(registerAddress, value) \
+{ \
+ ixNpeMhTestRegisterRead (registerAddress, value); \
+}
+
+/**
+ * @def IX_NPEMH_REGISTER_READ_BITS
+ *
+ * @brief This macro partially reads a memory-mapped register.
+ */
+
+#define IX_NPEMH_REGISTER_READ_BITS(registerAddress, value, mask) \
+{ \
+ ixNpeMhTestRegisterReadBits (registerAddress, value, mask); \
+}
+
+/**
+ * @def IX_NPEMH_REGISTER_WRITE
+ *
+ * @brief This macro writes a memory-mapped register.
+ */
+
+#define IX_NPEMH_REGISTER_WRITE(registerAddress, value) \
+{ \
+ ixNpeMhTestRegisterWrite (registerAddress, value); \
+}
+
+/**
+ * @def IX_NPEMH_REGISTER_WRITE_BITS
+ *
+ * @brief This macro partially writes a memory-mapped register.
+ */
+
+#define IX_NPEMH_REGISTER_WRITE_BITS(registerAddress, value, mask) \
+{ \
+ ixNpeMhTestRegisterWriteBits (registerAddress, value, mask); \
+}
+
+#endif /* #if CPU==XSCALE */
+
+#endif /* IXNPEMHMACROS_P_H */
+
+/**
+ * @} defgroup IxNpeMhMacros_p
+ */
diff --git a/cpu/ixp/npe/include/IxNpeMhReceive_p.h b/cpu/ixp/npe/include/IxNpeMhReceive_p.h
new file mode 100644
index 0000000..6416bed
--- /dev/null
+++ b/cpu/ixp/npe/include/IxNpeMhReceive_p.h
@@ -0,0 +1,139 @@
+/**
+ * @file IxNpeMhReceive_p.h
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the private API for the Receive module.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeMhReceive_p IxNpeMhReceive_p
+ *
+ * @brief The private API for the Receive module.
+ *
+ * @{
+ */
+
+#ifndef IXNPEMHRECEIVE_P_H
+#define IXNPEMHRECEIVE_P_H
+
+#include "IxNpeMh.h"
+#include "IxOsalTypes.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ * @fn void ixNpeMhReceiveInitialize (void)
+ *
+ * @brief This function registers an internal ISR to handle the NPEs'
+ * "outFIFO not empty" interrupts and receive messages from the NPEs when
+ * they become available.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhReceiveInitialize (void);
+
+/**
+ * @fn IX_STATUS ixNpeMhReceiveMessagesReceive (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function reads messages from a particular NPE's outFIFO
+ * until the outFIFO is empty, and for each message looks first for an
+ * unsolicited callback, then a solicited callback, to pass the message
+ * back to the client. If no callback can be found the message is
+ * discarded and an error reported. This function will return TIMEOUT
+ * status if NPE hang / halt.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to receive
+ * messages from.
+ *
+ * @return The function returns a status indicating success, failure or timeout.
+ */
+
+IX_STATUS ixNpeMhReceiveMessagesReceive (
+ IxNpeMhNpeId npeId);
+
+/**
+ * @fn void ixNpeMhReceiveShow (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function will display the current state of the Receive
+ * module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to display state
+ * information for.
+ *
+ * @return No return status.
+ */
+
+void ixNpeMhReceiveShow (
+ IxNpeMhNpeId npeId);
+
+/**
+ * @fn void ixNpeMhReceiveShowReset (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function will reset the current state of the Receive
+ * module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to reset state
+ * information for.
+ *
+ * @return No return status.
+ */
+
+void ixNpeMhReceiveShowReset (
+ IxNpeMhNpeId npeId);
+
+#endif /* IXNPEMHRECEIVE_P_H */
+
+/**
+ * @} defgroup IxNpeMhReceive_p
+ */
diff --git a/cpu/ixp/npe/include/IxNpeMhSend_p.h b/cpu/ixp/npe/include/IxNpeMhSend_p.h
new file mode 100644
index 0000000..977cc94
--- /dev/null
+++ b/cpu/ixp/npe/include/IxNpeMhSend_p.h
@@ -0,0 +1,163 @@
+/**
+ * @file IxNpeMhSend_p.h
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the private API for the Send module.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeMhSend_p IxNpeMhSend_p
+ *
+ * @brief The private API for the Send module.
+ *
+ * @{
+ */
+
+#ifndef IXNPEMHSEND_P_H
+#define IXNPEMHSEND_P_H
+
+#include "IxNpeMh.h"
+#include "IxOsalTypes.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ * @fn IX_STATUS ixNpeMhSendMessageSend (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage message,
+ UINT32 maxSendRetries)
+ *
+ * @brief This function writes a message to the specified NPE's inFIFO,
+ * and must be used when the message being sent does not solicit a response
+ * from the NPE. This function will return TIMEOUT status if NPE hang / halt.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to send the message
+ * to.
+ * @param IxNpeMhMessage message (in) - The message to send.
+ * @param UINT32 maxSendRetries (in) - Max num. of retries to perform
+ * if the NPE's inFIFO is full.
+ *
+ * @return The function returns a status indicating success, failure or timeout.
+ */
+
+IX_STATUS ixNpeMhSendMessageSend (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage message,
+ UINT32 maxSendRetries);
+
+/**
+ * @fn IX_STATUS ixNpeMhSendMessageWithResponseSend (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage message,
+ IxNpeMhMessageId solicitedMessageId,
+ IxNpeMhCallback solicitedCallback,
+ UINT32 maxSendRetries)
+ *
+ * @brief This function writes a message to the specified NPE's inFIFO,
+ * and must be used when the message being sent solicits a response from
+ * the NPE. The ID of the solicited response must be specified so that it
+ * can be recognised, and a callback provided to pass the response back to
+ * the client. This function will return TIMEOUT status if NPE hang / halt.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to send the message
+ * to.
+ * @param IxNpeMhMessage message (in) - The message to send.
+ * @param IxNpeMhMessageId solicitedMessageId (in) - The ID of the
+ * solicited response.
+ * @param IxNpeMhCallback solicitedCallback (in) - The callback to pass the
+ * solicited response back to the client.
+ * @param UINT32 maxSendRetries (in) - Max num. of retries to perform
+ * if the NPE's inFIFO is full.
+ *
+ * @return The function returns a status indicating success, failure or timeout.
+ */
+
+IX_STATUS ixNpeMhSendMessageWithResponseSend (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessage message,
+ IxNpeMhMessageId solicitedMessageId,
+ IxNpeMhCallback solicitedCallback,
+ UINT32 maxSendRetries);
+
+/**
+ * @fn void ixNpeMhSendShow (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function will display the current state of the Send module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to display state
+ * information for.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhSendShow (
+ IxNpeMhNpeId npeId);
+
+/**
+ * @fn void ixNpeMhSendShowReset (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function will reset the current state of the Send module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to reset state
+ * information for.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhSendShowReset (
+ IxNpeMhNpeId npeId);
+
+#endif /* IXNPEMHSEND_P_H */
+
+/**
+ * @} defgroup IxNpeMhSend_p
+ */
diff --git a/cpu/ixp/npe/include/IxNpeMhSolicitedCbMgr_p.h b/cpu/ixp/npe/include/IxNpeMhSolicitedCbMgr_p.h
new file mode 100644
index 0000000..40cd496
--- /dev/null
+++ b/cpu/ixp/npe/include/IxNpeMhSolicitedCbMgr_p.h
@@ -0,0 +1,171 @@
+/**
+ * @file IxNpeMhSolicitedCbMgr_p.h
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the private API for the Solicited Callback
+ * Manager module.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeMhSolicitedCbMgr_p IxNpeMhSolicitedCbMgr_p
+ *
+ * @brief The private API for the Solicited Callback Manager module.
+ *
+ * @{
+ */
+
+#ifndef IXNPEMHSOLICITEDCBMGR_P_H
+#define IXNPEMHSOLICITEDCBMGR_P_H
+
+#include "IxNpeMh.h"
+#include "IxOsalTypes.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+/** Maximum number of solicited callbacks that can be stored in the list */
+#define IX_NPEMH_MAX_CALLBACKS (16)
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ * @fn void ixNpeMhSolicitedCbMgrInitialize (void)
+ *
+ * @brief This function initializes the Solicited Callback Manager module,
+ * setting up a callback data structure for each NPE.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhSolicitedCbMgrInitialize (void);
+
+/**
+ * @fn IX_STATUS ixNpeMhSolicitedCbMgrCallbackSave (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId solicitedMessageId,
+ IxNpeMhCallback solicitedCallback)
+ *
+ * @brief This function saves a callback in the specified NPE's callback
+ * list. If the callback list is full the function will fail.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE in whose callback
+ * list the callback will be saved.
+ * @param IxNpeMhMessageId solicitedMessageId (in) - The ID of the message
+ * that this callback is for.
+ * @param IxNpeMhCallback solicitedCallback (in) - The callback function
+ * pointer to save.
+ *
+ * @return The function returns a status indicating success or failure.
+ */
+
+IX_STATUS ixNpeMhSolicitedCbMgrCallbackSave (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId solicitedMessageId,
+ IxNpeMhCallback solicitedCallback);
+
+/**
+ * @fn void ixNpeMhSolicitedCbMgrCallbackRetrieve (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId solicitedMessageId,
+ IxNpeMhCallback *solicitedCallback)
+ *
+ * @brief This function retrieves the first ID-matching callback from the
+ * specified NPE's callback list. If no matching callback can be found the
+ * function will fail.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE from whose callback
+ * list the callback will be retrieved.
+ * @param IxNpeMhMessageId solicitedMessageId (in) - The ID of the message
+ * that the callback is for.
+ * @param IxNpeMhCallback solicitedCallback (out) - The callback function
+ * pointer retrieved.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhSolicitedCbMgrCallbackRetrieve (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId solicitedMessageId,
+ IxNpeMhCallback *solicitedCallback);
+
+/**
+ * @fn void ixNpeMhSolicitedCbMgrShow (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function will display the current state of the Solicited
+ * Callback Manager module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to display state
+ * information for.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhSolicitedCbMgrShow (
+ IxNpeMhNpeId npeId);
+
+/**
+ * @fn void ixNpeMhSolicitedCbMgrShowReset (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function will reset the current state of the Solicited
+ * Callback Manager module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to reset state
+ * information for.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhSolicitedCbMgrShowReset (
+ IxNpeMhNpeId npeId);
+
+#endif /* IXNPEMHSOLICITEDCBMGR_P_H */
+
+/**
+ * @} defgroup IxNpeMhSolicitedCbMgr_p
+ */
diff --git a/cpu/ixp/npe/include/IxNpeMhUnsolicitedCbMgr_p.h b/cpu/ixp/npe/include/IxNpeMhUnsolicitedCbMgr_p.h
new file mode 100644
index 0000000..dea8caf
--- /dev/null
+++ b/cpu/ixp/npe/include/IxNpeMhUnsolicitedCbMgr_p.h
@@ -0,0 +1,169 @@
+/**
+ * @file IxNpeMhUnsolicitedCbMgr_p.h
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the private API for the Unsolicited Callback
+ * Manager module.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxNpeMhUnsolicitedCbMgr_p IxNpeMhUnsolicitedCbMgr_p
+ *
+ * @brief The private API for the Unsolicited Callback Manager module.
+ *
+ * @{
+ */
+
+#ifndef IXNPEMHUNSOLICITEDCBMGR_P_H
+#define IXNPEMHUNSOLICITEDCBMGR_P_H
+
+#include "IxNpeMh.h"
+#include "IxOsalTypes.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ * @fn void ixNpeMhUnsolicitedCbMgrInitialize (void)
+ *
+ * @brief This function initializes the Unsolicited Callback Manager
+ * module, setting up a callback data structure for each NPE.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhUnsolicitedCbMgrInitialize (void);
+
+/**
+ * @fn void ixNpeMhUnsolicitedCbMgrCallbackSave (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId unsolicitedMessageId,
+ IxNpeMhCallback unsolicitedCallback)
+ *
+ * @brief This function saves a callback in the specified NPE's callback
+ * table. If a callback already exists for the specified ID then it will
+ * be overwritten.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE in whose callback
+ * table the callback will be saved.
+ * @param IxNpeMhMessageId unsolicitedMessageId (in) - The ID of the
+ * messages that this callback is for.
+ * @param IxNpeMhCallback unsolicitedCallback (in) - The callback function
+ * pointer to save.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhUnsolicitedCbMgrCallbackSave (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId unsolicitedMessageId,
+ IxNpeMhCallback unsolicitedCallback);
+
+/**
+ * @fn void ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId unsolicitedMessageId,
+ IxNpeMhCallback *unsolicitedCallback)
+ *
+ * @brief This function retrieves the callback for the specified ID from
+ * the specified NPE's callback table. If no callback is registered for
+ * the specified ID and NPE then a callback value of NULL will be returned.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE from whose callback
+ * table the callback will be retrieved.
+ * @param IxNpeMhMessageId unsolicitedMessageId (in) - The ID of the
+ * messages that the callback is for.
+ * @param IxNpeMhCallback unsolicitedCallback (out) - The callback function
+ * pointer retrieved.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
+ IxNpeMhNpeId npeId,
+ IxNpeMhMessageId unsolicitedMessageId,
+ IxNpeMhCallback *unsolicitedCallback);
+
+/**
+ * @fn void ixNpeMhUnsolicitedCbMgrShow (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function will display the current state of the Unsolicited
+ * Callback Manager module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to display state
+ * information for.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhUnsolicitedCbMgrShow (
+ IxNpeMhNpeId npeId);
+
+/**
+ * @fn void ixNpeMhUnsolicitedCbMgrShowReset (
+ IxNpeMhNpeId npeId)
+ *
+ * @brief This function will reset the current state of the Unsolicited
+ * Callback Manager module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to reset state
+ * information for.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhUnsolicitedCbMgrShowReset (
+ IxNpeMhNpeId npeId);
+
+#endif /* IXNPEMHUNSOLICITEDCBMGR_P_H */
+
+/**
+ * @} defgroup IxNpeMhUnsolicitedCbMgr_p
+ */
diff --git a/cpu/ixp/npe/include/IxNpeMicrocode.h b/cpu/ixp/npe/include/IxNpeMicrocode.h
new file mode 100644
index 0000000..893d803
--- /dev/null
+++ b/cpu/ixp/npe/include/IxNpeMicrocode.h
@@ -0,0 +1,296 @@
+/**
+ * @date April 18, 2005
+ *
+ * @brief IXP400 NPE Microcode Image file
+ *
+ * This file was generated by the IxNpeDlImageGen tool.
+ * It contains a NPE microcode image suitable for use
+ * with the NPE Downloader (IxNpeDl) component in the
+ * IXP400 Access Driver software library.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeMicrocode IXP400 NPE Microcode Image Library
+ *
+ * @brief Library containing a set of NPE firmware images, for use
+ * with NPE Downloader s/w component
+ *
+ * @{
+ */
+
+/**
+ * @def IX_NPE_IMAGE_INCLUDE
+ *
+ * @brief Wrap the following Image identifiers with "#if IX_NPE_IMAGE_INCLUDE ... #endif" to include the image in the library
+ */
+#define IX_NPE_IMAGE_INCLUDE 1
+
+/**
+ * @def IX_NPE_IMAGE_OMIT
+ *
+ * @brief Wrap the following Image identifiers with "#if IX_NPE_IMAGE_OMIT ... #endif" to OMIT the image from the library
+ */
+#define IX_NPE_IMAGE_OMIT 0
+
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_HSS0
+ *
+ * @brief NPE Image Id for NPE-A with HSS-0 Only feature. It supports 32 channelized and 4 packetized.
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_HSS0 0x00010000
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_HSS0_ATM_SPHY_1_PORT
+ *
+ * @brief NPE Image Id for NPE-A with HSS-0 and ATM feature. For HSS, it supports 16/32 channelized and 4/0 packetized. For ATM, it supports AAL5, AAL0 and OAM for UTOPIA SPHY, 1 logical port, 32 VCs. It also has Fast Path support.
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_HSS0_ATM_SPHY_1_PORT 0x00020000
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_HSS0_ATM_MPHY_1_PORT
+ *
+ * @brief NPE Image Id for NPE-A with HSS-0 and ATM feature. For HSS, it supports 16/32 channelized and 4/0 packetized. For ATM, it supports AAL5, AAL0 and OAM for UTOPIA MPHY, 1 logical port, 32 VCs. It also has Fast Path support.
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_HSS0_ATM_MPHY_1_PORT 0x00030000
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_ATM_MPHY_12_PORT
+ *
+ * @brief NPE Image Id for NPE-A with ATM-Only feature. It supports AAL5, AAL0 and OAM for UTOPIA MPHY, 12 logical ports, 32 VCs. It also has Fast Path support.
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_ATM_MPHY_12_PORT 0x00040000
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_DMA
+ *
+ * @brief NPE Image Id for NPE-A with DMA-Only feature.
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_DMA 0x00150100
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_HSS_2_PORT
+ *
+ * @brief NPE Image Id for NPE-A with HSS-0 and HSS-1 feature. Each HSS port supports 32 channelized and 4 packetized.
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_HSS_2_PORT 0x00090000
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_ETH
+ *
+ * @brief NPE Image Id for NPE-A with Basic Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_ETH 0x10800200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_ETH_LEARN_FILTER_SPAN_FIREWALL
+ *
+ * @brief NPE Image Id for NPE-A with Basic Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_ETH_LEARN_FILTER_SPAN_FIREWALL 0x10800200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS
+ *
+ * @brief NPE Image Id for NPE-A with Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL, VLAN_QOS
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS 0x10810200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV
+ *
+ * @brief NPE Image Id for NPE-A with Ethernet Rx/Tx which includes: SPANNING_TREE, FIREWALL, VLAN_QOS, HEADER_CONVERSION
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV 0x10820200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEB_ETH
+ *
+ * @brief NPE Image Id for NPE-B with Basic Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL
+ */
+#define IX_NPEDL_NPEIMAGE_NPEB_ETH 0x01000200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL
+ *
+ * @brief NPE Image Id for NPE-B with Basic Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL
+ */
+#define IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL 0x01000200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS
+ *
+ * @brief NPE Image Id for NPE-B with Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL, VLAN_QOS
+ */
+#define IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS 0x01010200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEB_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV
+ *
+ * @brief NPE Image Id for NPE-B with Ethernet Rx/Tx which includes: SPANNING_TREE, FIREWALL, VLAN_QOS, HEADER_CONVERSION
+ */
+#define IX_NPEDL_NPEIMAGE_NPEB_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV 0x01020200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEB_DMA
+ *
+ * @brief NPE Image Id for NPE-B with DMA-Only feature.
+ */
+#define IX_NPEDL_NPEIMAGE_NPEB_DMA 0x01020100
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEC_ETH
+ *
+ * @brief NPE Image Id for NPE-C with Basic Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL
+ */
+#define IX_NPEDL_NPEIMAGE_NPEC_ETH 0x02000200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL
+ *
+ * @brief NPE Image Id for NPE-C with Basic Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL
+ */
+#define IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL 0x02000200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS
+ *
+ * @brief NPE Image Id for NPE-C with Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL, VLAN_QOS
+ */
+#define IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS 0x02010200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEC_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV
+ *
+ * @brief NPE Image Id for NPE-C with Ethernet Rx/Tx which includes: SPANNING_TREE, FIREWALL, VLAN_QOS, HEADER_CONVERSION
+ */
+#define IX_NPEDL_NPEIMAGE_NPEC_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV 0x02020200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEC_DMA
+ *
+ * @brief NPE Image Id for NPE-C with DMA-Only feature.
+ */
+#define IX_NPEDL_NPEIMAGE_NPEC_DMA 0x02080100
+#endif
+
+/* Number of NPE firmware images in this library */
+#define IX_NPE_MICROCODE_AVAILABLE_VERSIONS_COUNT 17
+
+/* Location of Microcode Images */
+#ifdef IX_NPE_MICROCODE_FIRMWARE_INCLUDED
+#ifdef IX_NPEDL_READ_MICROCODE_FROM_FILE
+
+extern UINT32* ixNpeMicrocode_binaryArray;
+
+#else
+
+extern unsigned IxNpeMicrocode_array[];
+
+#endif
+#endif
+
+/*
+ * sr: undef all but the bare minimum to reduce flash usage for U-Boot
+ */
+#undef IX_NPEDL_NPEIMAGE_NPEA_HSS0
+#undef IX_NPEDL_NPEIMAGE_NPEA_HSS0_ATM_SPHY_1_PORT
+#undef IX_NPEDL_NPEIMAGE_NPEA_HSS0_ATM_MPHY_1_PORT
+#undef IX_NPEDL_NPEIMAGE_NPEA_ATM_MPHY_12_PORT
+#undef IX_NPEDL_NPEIMAGE_NPEA_DMA
+#undef IX_NPEDL_NPEIMAGE_NPEA_HSS_2_PORT
+#undef IX_NPEDL_NPEIMAGE_NPEA_ETH
+#undef IX_NPEDL_NPEIMAGE_NPEA_ETH_LEARN_FILTER_SPAN_FIREWALL
+#undef IX_NPEDL_NPEIMAGE_NPEA_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS
+#undef IX_NPEDL_NPEIMAGE_NPEA_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV
+#undef IX_NPEDL_NPEIMAGE_NPEB_ETH
+#undef IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL
+/* #undef IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS */
+#undef IX_NPEDL_NPEIMAGE_NPEB_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV
+#undef IX_NPEDL_NPEIMAGE_NPEB_DMA
+#undef IX_NPEDL_NPEIMAGE_NPEC_ETH
+#undef IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL
+/* #undef IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS */
+#undef IX_NPEDL_NPEIMAGE_NPEC_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV
+#undef IX_NPEDL_NPEIMAGE_NPEC_DMA
+
+/**
+ * @} defgroup IxNpeMicrocode
+ */
diff --git a/cpu/ixp/npe/include/IxOsBufLib.h b/cpu/ixp/npe/include/IxOsBufLib.h
new file mode 100644
index 0000000..a297a97
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsBufLib.h
@@ -0,0 +1,55 @@
+/**
+ * @file IxOsBufLib.h (Replaced by OSAL)
+ *
+ * @date 9 Oct 2002
+ *
+ * @brief This file contains the mbuf pool initialisation entry point
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ *
+ */
+
+#ifndef IXOSBUFLIB_H
+#define IXOSBUFLIB_H
+
+#include "IxOsalBackward.h"
+
+#endif /* IXOSBUFLIB_H */
+
diff --git a/cpu/ixp/npe/include/IxOsBuffMgt.h b/cpu/ixp/npe/include/IxOsBuffMgt.h
new file mode 100644
index 0000000..b7de712
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsBuffMgt.h
@@ -0,0 +1,52 @@
+/**
+ * @file (Replaced by OSAL)
+ *
+ * @brief This file includes the OS dependant MBUF header files.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#ifndef IxOsBuffMgt_inc
+#define IxOsBuffMgt_inc
+
+#include "IxOsalBackward.h"
+
+#endif /* ndef IxOsBuffMgt_inc */
diff --git a/cpu/ixp/npe/include/IxOsBuffPoolMgt.h b/cpu/ixp/npe/include/IxOsBuffPoolMgt.h
new file mode 100644
index 0000000..4a983c7
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsBuffPoolMgt.h
@@ -0,0 +1,74 @@
+/**
+ * @file IxOsBuffPoolMgt.h (Replaced by OSAL)
+ *
+ * @date 9 Oct 2002
+ *
+ * @brief This file contains the mbuf pool implementation API
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ * This module contains the implementation of the OS Services buffer pool
+ * management service. This module provides routines for creating pools
+ * of buffers for exchange of network data, getting and returning buffers
+ * from and to the pool, and some other utility functions.
+ * <P>
+ * Currently, the pool has 2 underlying implementations - one for the vxWorks
+ * OS, and another which attempts to be OS-agnostic so that it can be used on
+ * other OS's such as Linux. The API is largely the same for all OS's,
+ * but there are some differences to be aware of. These are documented
+ * in the API descriptions below.
+ * <P>
+ * The most significant difference is this: when this module is used with
+ * the WindRiver VxWorks OS, it will create a pool of vxWorks "MBufs".
+ * These can be used directly with the vxWorks "netBufLib" OS Library.
+ * For other OS's, it will create a pool of generic buffers. These may need
+ * to be converted into other buffer types (sk_buff's in Linux, for example)
+ * before being used with any built-in OS routines available for
+ * manipulating network data buffers.
+ *
+ * @sa IxOsBuffMgt.h
+ */
+
+#ifndef IXOSBUFFPOOLMGT_H
+#define IXOSBUFFPOOLMGT_H
+
+#include "IxOsalBackward.h"
+
+#endif /* IXOSBUFFPOOLMGT_H */
+
diff --git a/cpu/ixp/npe/include/IxOsCacheMMU.h b/cpu/ixp/npe/include/IxOsCacheMMU.h
new file mode 100644
index 0000000..2c8592f
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsCacheMMU.h
@@ -0,0 +1,60 @@
+/**
+ * @file IxOsCacheMMU.h
+ *
+ * @brief this file contains the API of the @ref IxCacheMMU component
+ *
+ * <hr>
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsCacheMMU_H
+
+#ifndef __doxygen_hide
+#define IxOsCacheMMU_H
+#endif /* __doxygen_hide */
+
+#ifdef __doxygen_HIDE
+#define IX_OS_CACHE_DOXYGEN
+#endif /* __doxygen_HIDE */
+
+#include "IxOsalBackward.h"
+
+#endif /* IxOsCacheMMU_H */
+
diff --git a/cpu/ixp/npe/include/IxOsPrintf.h b/cpu/ixp/npe/include/IxOsPrintf.h
new file mode 100644
index 0000000..218e140
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsPrintf.h
@@ -0,0 +1,102 @@
+/**
+ * @file IxOsPrintf.h
+ *
+ * @brief this file contains the API of the @ref IxOsServices component
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxTypes.h"
+
+#ifndef IxOsPrintf_H
+
+#ifndef __doxygen_hide
+#define IxOsPrintf_H
+#endif /* __doxygen_hide */
+
+#ifdef __wince
+
+#ifndef IX_USE_SERCONSOLE
+
+static int
+ixLogMsg(
+ char *pFormat,
+ ...
+ )
+{
+#ifndef IN_KERNEL
+ static WCHAR pOutputString[256];
+ static char pNarrowStr[256];
+ int returnCnt = 0;
+ va_list ap;
+
+ pOutputString[0] = 0;
+ pNarrowStr[0] = 0;
+
+ va_start(ap, pFormat);
+
+ returnCnt = _vsnprintf(pNarrowStr, 256, pFormat, ap);
+
+ MultiByteToWideChar(
+ CP_ACP,
+ MB_PRECOMPOSED,
+ pNarrowStr,
+ -1,
+ pOutputString,
+ 256
+ );
+
+ OutputDebugString(pOutputString);
+
+ return returnCnt;
+#else
+ return 0;
+#endif
+}
+#define printf ixLogMsg
+
+#endif /* IX_USE_SERCONSOLE */
+
+#endif /* __wince */
+
+/**
+ * @} IxOsPrintf
+ */
+
+#endif /* IxOsPrintf_H */
diff --git a/cpu/ixp/npe/include/IxOsServices.h b/cpu/ixp/npe/include/IxOsServices.h
new file mode 100644
index 0000000..62e8a79
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsServices.h
@@ -0,0 +1,55 @@
+/**
+ * @file (Replaced by OSAL)
+ *
+ * @brief this file contains the API of the @ref IxOsServices component
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+#ifndef IxOsServices_H
+
+#ifndef __doxygen_hide
+#define IxOsServices_H
+#endif /* __doxygen_hide */
+
+#include "IxOsalBackward.h"
+
+#endif /* IxOsServices_H */
+
+
diff --git a/cpu/ixp/npe/include/IxOsServicesComponents.h b/cpu/ixp/npe/include/IxOsServicesComponents.h
new file mode 100644
index 0000000..d662cd3
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsServicesComponents.h
@@ -0,0 +1,134 @@
+/**
+ * @file IxOsServicesComponents.h (Replaced by OSAL)
+ *
+ * @brief Header file for memory access
+ *
+ * @par
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsServicesComponents_H
+#define IxOsServicesComponents_H
+
+#include "IxOsalBackward.h"
+ * codelets_parityENAcc
+ * timeSyncAcc
+ * parityENAcc
+ * sspAcc
+ * i2c
+ * integration_sspAcc
+ * integration_i2c
+#define ix_timeSyncAcc 36
+#define ix_parityENAcc 37
+#define ix_codelets_parityENAcc 38
+#define ix_sspAcc 39
+#define ix_i2c 40
+#define ix_integration_sspAcc 41
+#define ix_integration_i2c 42
+#define ix_osal 43
+#define ix_integration_parityENAcc 44
+#define ix_integration_timeSyncAcc 45
+
+/***************************
+ * timeSyncAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_timeSyncAcc)
+
+#if defined (IX_OSSERV_VXWORKS_LE)
+
+#define CSR_LE_DATA_COHERENT_MAPPING
+
+#endif /* IX_OSSERV_VXWORKS_LE */
+
+#endif /* timeSyncAcc */
+
+/***************************
+ * parityENAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_parityENAcc)
+
+#if defined (IX_OSSERV_VXWORKS_LE)
+
+#define CSR_LE_DATA_COHERENT_MAPPING
+
+#endif /* IX_OSSERV_VXWORKS_LE */
+
+#endif /* parityENAcc */
+
+/***************************
+ * codelets_parityENAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_parityENAcc)
+
+#if defined (IX_OSSERV_VXWORKS_LE)
+
+#define CSR_LE_DATA_COHERENT_MAPPING
+
+#endif /* IX_OSSERV_VXWORKS_LE */
+
+#endif /* codelets_parityENAcc */
+
+#endif /* IxOsServicesComponents_H */
+
+/***************************
+ * integration_timeSyncAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_integration_timeSyncAcc)
+
+#if defined (IX_OSSERV_VXWORKS_LE)
+
+#define CSR_LE_DATA_COHERENT_MAPPING
+
+#endif /* IX_OSSERV_VXWORKS_LE */
+
+#endif /* integration_timeSyncAcc */
+
+/***************************
+ * integration_parityENAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_integration_parityENAcc)
+
+#if defined (IX_OSSERV_VXWORKS_LE)
+
+#define CSR_LE_DATA_COHERENT_MAPPING
+
+#endif /* IX_OSSERV_VXWORKS_LE */
+
+#endif /* integration_parityENAcc */
diff --git a/cpu/ixp/npe/include/IxOsServicesEndianess.h b/cpu/ixp/npe/include/IxOsServicesEndianess.h
new file mode 100644
index 0000000..0d6cd8c
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsServicesEndianess.h
@@ -0,0 +1,52 @@
+/**
+ * @file IxOsServicesEndianess.h (Replaced by OSAL)
+ *
+ * @brief Header file for determining system endianess and OS
+ *
+ * @par
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsServicesEndianess_H
+#define IxOsServicesEndianess_H
+
+#include "IxOsalBackward.h"
+
+#endif /* IxOsServicesEndianess_H */
diff --git a/cpu/ixp/npe/include/IxOsServicesMemAccess.h b/cpu/ixp/npe/include/IxOsServicesMemAccess.h
new file mode 100644
index 0000000..58e9941
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsServicesMemAccess.h
@@ -0,0 +1,52 @@
+/**
+ * @file IxOsServicesMemAccess.h (Replaced by OSAL)
+ *
+ * @brief Header file for memory access
+ *
+ * @par
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsServicesMemAccess_H
+#define IxOsServicesMemAccess_H
+
+#include "IxOsalBackward.h"
+
+#endif /* IxOsServicesMemAccess_H */
diff --git a/cpu/ixp/npe/include/IxOsServicesMemMap.h b/cpu/ixp/npe/include/IxOsServicesMemMap.h
new file mode 100644
index 0000000..4ce37c3
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsServicesMemMap.h
@@ -0,0 +1,54 @@
+/**
+ * @file IxOsServicesMemMap.h (Replaced by OSAL)
+ *
+ * @brief Header file for memory access maps
+ *
+ * @par
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsServicesMemMap_H
+#define IxOsServicesMemMap_H
+
+#include "IxOsalBackward.h"
+#define IX_OSSERV_ETH_NPEA_MAP_SIZE (0x1000) /**< Eth for NPEA map size */
+#define IX_OSSERV_ETH_NPEA_PHYS_BASE IXP425_Eth_NPEA_BASE_PHYS
+
+#endif /* IxOsServicesMemMap_H */
diff --git a/cpu/ixp/npe/include/IxOsal.h b/cpu/ixp/npe/include/IxOsal.h
new file mode 100644
index 0000000..b2a93a5
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsal.h
@@ -0,0 +1,1517 @@
+/**
+ * @file IxOsal.h
+ *
+ * @brief Top include file for OSAL
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsal_H
+#define IxOsal_H
+
+/* Basic types */
+#include "IxOsalTypes.h"
+
+/* Include assert */
+#include "IxOsalAssert.h"
+
+/*
+ * Config header gives users option to choose IO MEM
+ * and buffer management modules
+ */
+
+#include "IxOsalConfig.h"
+
+/*
+ * Symbol file needed by some OS.
+ */
+#include "IxOsalUtilitySymbols.h"
+
+/* OS-specific header */
+#include "IxOsalOs.h"
+
+
+/**
+ * @defgroup IxOsal Operating System Abstraction Layer (IxOsal) API
+ *
+ * @brief This service provides a thin layer of OS dependency services.
+ *
+ * This file contains the API to the functions which are some what OS dependant and would
+ * require porting to a particular OS.
+ * A primary focus of the component development is to make them as OS independent as possible.
+ * All other components should abstract their OS dependency to this module.
+ * Services overview
+ * -# Data types, constants, defines
+ * -# Interrupts
+ * - bind interrupts to handlers
+ * - unbind interrupts from handlers
+ * - disables all interrupts
+ * - enables all interrupts
+ * - selectively disables interrupts
+ * - enables an interrupt level
+ * - disables an interrupt level
+ * -# Memory
+ * - allocates memory
+ * - frees memory
+ * - copies memory zones
+ * - fills a memory zone
+ * - allocates cache-safe memory
+ * - frees cache-safe memory
+ * - physical to virtual address translation
+ * - virtual to physical address translation
+ * - cache to memory flush
+ * - cache line invalidate
+ * -# Threads
+ * - creates a new thread
+ * - starts a newly created thread
+ * - kills an existing thread
+ * - exits a running thread
+ * - sets the priority of an existing thread
+ * - suspends thread execution
+ * - resumes thread execution
+ * -# IPC
+ * - creates a message queue
+ * - deletes a message queue
+ * - sends a message to a message queue
+ * - receives a message from a message queue
+ * -# Thread Synchronisation
+ * - initializes a mutex
+ * - locks a mutex
+ * - unlocks a mutex
+ * - non-blocking attempt to lock a mutex
+ * - destroys a mutex object
+ * - initializes a fast mutex
+ * - non-blocking attempt to lock a fast mutex
+ * - unlocks a fast mutex
+ * - destroys a fast mutex object
+ * - initializes a semaphore
+ * - posts to (increments) a semaphore
+ * - waits on (decrements) a semaphore
+ * - non-blocking wait on semaphore
+ * - gets semaphore value
+ * - destroys a semaphore object
+ * - yields execution of current thread
+ * -# Time functions
+ * - yielding sleep for a number of milliseconds
+ * - busy sleep for a number of microseconds
+ * - value of the timestamp counter
+ * - resolution of the timestamp counter
+ * - system clock rate, in ticks
+ * - current system time
+ * - converts ixOsalTimeVal into ticks
+ * - converts ticks into ixOsalTimeVal
+ * - converts ixOsalTimeVal to milliseconds
+ * - converts milliseconds to IxOsalTimeval
+ * - "equal" comparison for IxOsalTimeval
+ * - "less than" comparison for IxOsalTimeval
+ * - "greater than" comparison for IxOsalTimeval
+ * - "add" operator for IxOsalTimeval
+ * - "subtract" operator for IxOsalTimeval
+ * -# Logging
+ * - sets the current logging verbosity level
+ * - interrupt-safe logging function
+ * -# Timer services
+ * - schedules a repeating timer
+ * - schedules a single-shot timer
+ * - cancels a running timer
+ * - displays all the running timers
+ * -# Optional Modules
+ * - Buffer management module
+ * - I/O memory and endianess support module
+ *
+ * @{
+ */
+
+
+/*
+ * Prototypes
+ */
+
+/* ========================== Interrupts ================================
+ *
+ */
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Binds an interrupt handler to an interrupt level
+ *
+ * @param irqLevel (in) - interrupt level
+ * @param irqHandler (in) - interrupt handler
+ * @param parameter (in) - custom parameter to be passed to the
+ * interrupt handler
+ *
+ * Binds an interrupt handler to an interrupt level. The operation will
+ * fail if the wrong level is selected, if the handler is NULL, or if the
+ * interrupt is already bound. This functions binds the specified C
+ * routine to an interrupt level. When called, the "parameter" value will
+ * be passed to the routine.
+ *
+ * Reentrant: no
+ * IRQ safe: no
+ *
+ * @return IX_SUCCESS if the operation succeeded or IX_FAIL otherwise
+ */
+PUBLIC IX_STATUS ixOsalIrqBind (UINT32 irqLevel,
+ IxOsalVoidFnVoidPtr irqHandler,
+ void *parameter);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Unbinds an interrupt handler from an interrupt level
+ *
+ * @param irqLevel (in) - interrupt level
+ *
+ * Unbinds the selected interrupt level from any previously registered
+ * handler
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return IX_SUCCESS if the operation succeeded or IX_FAIL otherwise
+ */
+PUBLIC IX_STATUS ixOsalIrqUnbind (UINT32 irqLevel);
+
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Disables all interrupts
+ *
+ * @param - none
+ *
+ * Disables all the interrupts and prevents tasks scheduling
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: yes
+ *
+ * @return interrupt enable status prior to locking
+ */
+PUBLIC UINT32 ixOsalIrqLock (void);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Enables all interrupts
+ *
+ * @param irqEnable (in) - interrupt enable status, prior to interrupt
+ * locking
+ *
+ * Enables the interrupts and task scheduling, cancelling the effect
+ * of ixOsalIrqLock()
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: yes
+ *
+ * @return IX_SUCCESS if the operation succeeded or IX_FAIL otherwise
+ */
+PUBLIC void ixOsalIrqUnlock (UINT32 irqEnable);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Selectively disables interrupts
+ *
+ * @param irqLevel ­ new interrupt level
+ *
+ * Disables the interrupts below the specified interrupt level
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: yes
+ *
+ * @note Depending on the implementation this function can disable all
+ * the interrupts
+ *
+ * @return previous interrupt level
+ */
+PUBLIC UINT32 ixOsalIrqLevelSet (UINT32 irqLevel);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Enables an interrupt level
+ *
+ * @param irqLevel ­ interrupt level to enable
+ *
+ * Enables the specified interrupt level
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: yes
+ *
+ * @return - none
+ */
+PUBLIC void ixOsalIrqEnable (UINT32 irqLevel);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Disables an interrupt level
+ *
+ * @param irqLevel ­ interrupt level to disable
+ *
+ * Disables the specified interrupt level
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: yes
+ *
+ * @return - none
+ */
+PUBLIC void ixOsalIrqDisable (UINT32 irqLevel);
+
+
+/* ============================= Memory =================================
+ *
+ */
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Allocates memory
+ *
+ * @param size - memory size to allocate, in bytes
+ *
+ * Allocates a memory zone of a given size
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return Pointer to the allocated zone or NULL if the allocation failed
+ */
+PUBLIC void *ixOsalMemAlloc (UINT32 size);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Frees memory
+ *
+ * @param ptr - pointer to the memory zone
+ *
+ * Frees a previously allocated memory zone
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - none
+ */
+PUBLIC void ixOsalMemFree (void *ptr);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Copies memory zones
+ *
+ * @param dest - destination memory zone
+ * @param src - source memory zone
+ * @param count - number of bytes to copy
+ *
+ * Copies count bytes from the source memory zone pointed by src into the
+ * memory zone pointed by dest.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: yes
+ *
+ * @return Pointer to the destination memory zone
+ */
+PUBLIC void *ixOsalMemCopy (void *dest, void *src, UINT32 count);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Fills a memory zone
+ *
+ * @param ptr - pointer to the memory zone
+ * @param filler - byte to fill the memory zone with
+ * @param count - number of bytes to fill
+ *
+ * Fills a memory zone with a given constant byte
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: yes
+ *
+ * @return Pointer to the memory zone
+ */
+PUBLIC void *ixOsalMemSet (void *ptr, UINT8 filler, UINT32 count);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Allocates cache-safe memory
+ *
+ * @param size - size, in bytes, of the allocated zone
+ *
+ * Allocates a cache-safe memory zone of at least "size" bytes and returns
+ * the pointer to the memory zone. This memory zone, depending on the
+ * platform, is either uncached or aligned on a cache line boundary to make
+ * the CACHE_FLUSH and CACHE_INVALIDATE macros safe to use. The memory
+ * allocated with this function MUST be freed with ixOsalCacheDmaFree(),
+ * otherwise memory corruption can occur.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return Pointer to the memory zone or NULL if allocation failed
+ *
+ * @note It is important to note that cache coherence is maintained in
+ * software by using the IX_OSAL_CACHE_FLUSH and IX_OSAL_CACHE_INVALIDATE
+ * macros to maintain consistency between cache and external memory.
+ */
+PUBLIC void *ixOsalCacheDmaMalloc (UINT32 size);
+
+/* Macros for ixOsalCacheDmaMalloc*/
+#define IX_OSAL_CACHE_DMA_MALLOC(size) ixOsalCacheDmaMalloc(size)
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Frees cache-safe memory
+ *
+ * @param ptr - pointer to the memory zone
+ *
+ * Frees a memory zone previously allocated with ixOsalCacheDmaMalloc()
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - none
+ */
+PUBLIC void ixOsalCacheDmaFree (void *ptr);
+
+#define IX_OSAL_CACHE_DMA_FREE(ptr) ixOsalCacheDmaFree(ptr)
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief physical to virtual address translation
+ *
+ * @param physAddr - physical address
+ *
+ * Converts a physical address into its equivalent MMU-mapped virtual address
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: yes
+ *
+ * @return Corresponding virtual address, as UINT32
+ */
+#define IX_OSAL_MMU_PHYS_TO_VIRT(physAddr) \
+ IX_OSAL_OS_MMU_PHYS_TO_VIRT(physAddr)
+
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief virtual to physical address translation
+ *
+ * @param virtAddr - virtual address
+ *
+ * Converts a virtual address into its equivalent MMU-mapped physical address
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: yes
+ *
+ * @return Corresponding physical address, as UINT32
+ */
+#define IX_OSAL_MMU_VIRT_TO_PHYS(virtAddr) \
+ IX_OSAL_OS_MMU_VIRT_TO_PHYS(virtAddr)
+
+
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief cache to memory flush
+ *
+ * @param addr - memory address to flush from cache
+ * @param size - number of bytes to flush (rounded up to a cache line)
+ *
+ * Flushes the cached value of the memory zone pointed by "addr" into memory,
+ * rounding up to a cache line. Use before the zone is to be read by a
+ * processing unit which is not cache coherent with the main CPU.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: yes
+ *
+ * @return - none
+ */
+#define IX_OSAL_CACHE_FLUSH(addr, size) IX_OSAL_OS_CACHE_FLUSH(addr, size)
+
+
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief cache line invalidate
+ *
+ * @param addr - memory address to invalidate in cache
+ * @param size - number of bytes to invalidate (rounded up to a cache line)
+ *
+ * Invalidates the cached value of the memory zone pointed by "addr",
+ * rounding up to a cache line. Use before reading the zone from the main
+ * CPU, if the zone has been updated by a processing unit which is not cache
+ * coherent with the main CPU.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: yes
+ *
+ * @return - none
+ */
+#define IX_OSAL_CACHE_INVALIDATE(addr, size) IX_OSAL_OS_CACHE_INVALIDATE(addr, size)
+
+
+/* ============================= Threads =================================
+ *
+ */
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Creates a new thread
+ *
+ * @param thread - handle of the thread to be created
+ * @param threadAttr - pointer to a thread attribute object
+ * @param startRoutine - thread entry point
+ * @param arg - argument given to the thread
+ *
+ * Creates a thread given a thread handle and a thread attribute object. The
+ * same thread attribute object can be used to create separate threads. "NULL"
+ * can be specified as the attribute, in which case the default values will
+ * be used. The thread needs to be explicitly started using ixOsalThreadStart().
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalThreadCreate (IxOsalThread * thread,
+ IxOsalThreadAttr * threadAttr,
+ IxOsalVoidFnVoidPtr startRoutine,
+ void *arg);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Starts a newly created thread
+ *
+ * @param thread - handle of the thread to be started
+ *
+ * Starts a thread given its thread handle. This function is to be called
+ * only once, following the thread initialization.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalThreadStart (IxOsalThread * thread);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Kills an existing thread
+ *
+ * @param thread - handle of the thread to be killed
+ *
+ * Kills a thread given its thread handle.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @note It is not possible to kill threads in Linux kernel mode. This
+ * function will only send a SIGTERM signal, and it is the responsibility
+ * of the thread to check for the presence of this signal with
+ * signal_pending().
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalThreadKill (IxOsalThread * thread);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Exits a running thread
+ *
+ * Terminates the calling thread
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - This function never returns
+ */
+PUBLIC void ixOsalThreadExit (void);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Sets the priority of an existing thread
+ *
+ * @param thread - handle of the thread
+ * @param priority - new priority, between 0 and 255 (0 being the highest)
+ *
+ * Sets the thread priority
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalThreadPrioritySet (IxOsalThread * thread,
+ UINT32 priority);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Suspends thread execution
+ *
+ * @param thread - handle of the thread
+ *
+ * Suspends the thread execution
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalThreadSuspend (IxOsalThread * thread);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Resumes thread execution
+ *
+ * @param thread - handle of the thread
+ *
+ * Resumes the thread execution
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalThreadResume (IxOsalThread * thread);
+
+
+/* ======================= Message Queues (IPC) ==========================
+ *
+ */
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Creates a message queue
+ *
+ * @param queue - queue handle
+ * @param msgCount - maximum number of messages to hold in the queue
+ * @param msgLen - maximum length of each message, in bytes
+ *
+ * Creates a message queue of msgCount messages, each containing msgLen bytes
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMessageQueueCreate (IxOsalMessageQueue * queue,
+ UINT32 msgCount, UINT32 msgLen);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Deletes a message queue
+ *
+ * @param queue - queue handle
+ *
+ * Deletes a message queue
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMessageQueueDelete (IxOsalMessageQueue * queue);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Sends a message to a message queue
+ *
+ * @param queue - queue handle
+ * @param message - message to send
+ *
+ * Sends a message to the message queue. The message will be copied (at the
+ * configured size of the message) into the queue.
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMessageQueueSend (IxOsalMessageQueue * queue,
+ UINT8 * message);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Receives a message from a message queue
+ *
+ * @param queue - queue handle
+ * @param message - pointer to where the message should be copied to
+ *
+ * Retrieves the first message from the message queue
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMessageQueueReceive (IxOsalMessageQueue * queue,
+ UINT8 * message);
+
+
+/* ======================= Thread Synchronisation ========================
+ *
+ */
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief initializes a mutex
+ *
+ * @param mutex - mutex handle
+ *
+ * Initializes a mutex object
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMutexInit (IxOsalMutex * mutex);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief locks a mutex
+ *
+ * @param mutex - mutex handle
+ * @param timeout - timeout in ms; IX_OSAL_WAIT_FOREVER (-1) to wait forever
+ * or IX_OSAL_WAIT_NONE to return immediately
+ *
+ * Locks a mutex object
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMutexLock (IxOsalMutex * mutex, INT32 timeout);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Unlocks a mutex
+ *
+ * @param mutex - mutex handle
+ *
+ * Unlocks a mutex object
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMutexUnlock (IxOsalMutex * mutex);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Non-blocking attempt to lock a mutex
+ *
+ * @param mutex - mutex handle
+ *
+ * Attempts to lock a mutex object, returning immediately with IX_SUCCESS if
+ * the lock was successful or IX_FAIL if the lock failed
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMutexTryLock (IxOsalMutex * mutex);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Destroys a mutex object
+ *
+ * @param mutex - mutex handle
+ * @param
+ *
+ * Destroys a mutex object; the caller should ensure that no thread is
+ * blocked on this mutex
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMutexDestroy (IxOsalMutex * mutex);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Initializes a fast mutex
+ *
+ * @param mutex - fast mutex handle
+ *
+ * Initializes a fast mutex object
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalFastMutexInit (IxOsalFastMutex * mutex);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Non-blocking attempt to lock a fast mutex
+ *
+ * @param mutex - fast mutex handle
+ *
+ * Attempts to lock a fast mutex object, returning immediately with
+ * IX_SUCCESS if the lock was successful or IX_FAIL if the lock failed
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalFastMutexTryLock (IxOsalFastMutex * mutex);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Unlocks a fast mutex
+ *
+ * @param mutex - fast mutex handle
+ *
+ * Unlocks a fast mutex object
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalFastMutexUnlock (IxOsalFastMutex * mutex);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Destroys a fast mutex object
+ *
+ * @param mutex - fast mutex handle
+ *
+ * Destroys a fast mutex object
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalFastMutexDestroy (IxOsalFastMutex * mutex);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Initializes a semaphore
+ *
+ * @param semaphore - semaphore handle
+ * @param value - initial semaphore value
+ *
+ * Initializes a semaphore object
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalSemaphoreInit (IxOsalSemaphore * semaphore,
+ UINT32 value);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Posts to (increments) a semaphore
+ *
+ * @param semaphore - semaphore handle
+ *
+ * Increments a semaphore object
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalSemaphorePost (IxOsalSemaphore * semaphore);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Waits on (decrements) a semaphore
+ *
+ * @param semaphore - semaphore handle
+ * @param timeout - timeout, in ms; IX_OSAL_WAIT_FOREVER (-1) if the thread
+ * is to block indefinitely or IX_OSAL_WAIT_NONE (0) if the thread is to
+ * return immediately even if the call fails
+ *
+ * Decrements a semaphore, blocking if the semaphore is
+ * unavailable (value is 0).
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalSemaphoreWait (IxOsalSemaphore * semaphore,
+ INT32 timeout);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Non-blocking wait on semaphore
+ *
+ * @param semaphore - semaphore handle
+ *
+ * Decrements a semaphore, not blocking the calling thread if the semaphore
+ * is unavailable
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalSemaphoreTryWait (IxOsalSemaphore * semaphore);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Gets semaphore value
+ *
+ * @param semaphore - semaphore handle
+ * @param value - location to store the semaphore value
+ *
+ * Retrieves the current value of a semaphore object
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalSemaphoreGetValue (IxOsalSemaphore * semaphore,
+ UINT32 * value);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Destroys a semaphore object
+ *
+ * @param semaphore - semaphore handle
+ *
+ * Destroys a semaphore object; the caller should ensure that no thread is
+ * blocked on this semaphore
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalSemaphoreDestroy (IxOsalSemaphore * semaphore);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Yields execution of current thread
+ *
+ * Yields the execution of the current thread
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - none
+ */
+PUBLIC void ixOsalYield (void);
+
+
+/* ========================== Time functions ===========================
+ *
+ */
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Yielding sleep for a number of milliseconds
+ *
+ * @param milliseconds - number of milliseconds to sleep
+ *
+ * The calling thread will sleep for the specified number of milliseconds.
+ * This sleep is yielding, hence other tasks will be scheduled by the
+ * operating system during the sleep period. Calling this function with an
+ * argument of 0 will place the thread at the end of the current scheduling
+ * loop.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - none
+ */
+PUBLIC void ixOsalSleep (UINT32 milliseconds);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Busy sleep for a number of microseconds
+ *
+ * @param microseconds - number of microseconds to sleep
+ *
+ * Sleeps for the specified number of microseconds, without explicitly
+ * yielding thread execution to the OS scheduler
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - none
+ */
+PUBLIC void ixOsalBusySleep (UINT32 microseconds);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief XXX
+ *
+ * Retrieves the current timestamp
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - The current timestamp
+ *
+ * @note The implementation of this function is platform-specific. Not
+ * all the platforms provide a high-resolution timestamp counter.
+ */
+PUBLIC UINT32 ixOsalTimestampGet (void);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Resolution of the timestamp counter
+ *
+ * Retrieves the resolution (frequency) of the timestamp counter.
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - The resolution of the timestamp counter
+ *
+ * @note The implementation of this function is platform-specific. Not all
+ * the platforms provide a high-resolution timestamp counter.
+ */
+PUBLIC UINT32 ixOsalTimestampResolutionGet (void);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief System clock rate, in ticks
+ *
+ * Retrieves the resolution (number of ticks per second) of the system clock
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - The system clock rate
+ *
+ * @note The implementation of this function is platform and OS-specific.
+ * The system clock rate is not always available - e.g. Linux does not
+ * provide this information in user mode
+ */
+PUBLIC UINT32 ixOsalSysClockRateGet (void);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Current system time
+ *
+ * @param tv - pointer to an IxOsalTimeval structure to store the current
+ * time in
+ *
+ * Retrieves the current system time (real-time)
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - none
+ *
+ * @note The implementation of this function is platform-specific. Not all
+ * platforms have a real-time clock.
+ */
+PUBLIC void ixOsalTimeGet (IxOsalTimeval * tv);
+
+
+
+/* Internal function to convert timer val to ticks.
+ * NOTE - This should not be called by the user.
+ * Use the macro IX_OSAL_TIMEVAL_TO_TICKS
+ * OS-independent, implemented in framework.
+ */
+PUBLIC UINT32 ixOsalTimevalToTicks (IxOsalTimeval tv);
+
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Converts ixOsalTimeVal into ticks
+ *
+ * @param tv - an IxOsalTimeval structure
+ *
+ * Converts an IxOsalTimeval structure into OS ticks
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - Corresponding number of ticks
+ *
+ * Note: This function is OS-independent. Implemented by core.
+ */
+#define IX_OSAL_TIMEVAL_TO_TICKS(tv) ixOsalTimevalToTicks(tv)
+
+
+
+/* Internal function to convert ticks to timer val
+ * NOTE - This should not be called by the user.
+ * Use the macro IX_OSAL_TICKS_TO_TIMEVAL
+ */
+
+PUBLIC void ixOsalTicksToTimeval (UINT32 ticks, IxOsalTimeval * pTv);
+
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Converts ticks into ixOsalTimeVal
+ *
+ * @param ticks - number of ticks
+ * @param pTv - pointer to the destination structure
+ *
+ * Converts the specified number of ticks into an IxOsalTimeval structure
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - Corresponding IxOsalTimeval structure
+ * Note: This function is OS-independent. Implemented by core.
+ */
+#define IX_OSAL_TICKS_TO_TIMEVAL(ticks, pTv) \
+ ixOsalTicksToTimeval(ticks, pTv)
+
+
+
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Converts ixOsalTimeVal to milliseconds
+ *
+ * @param tv - IxOsalTimeval structure to convert
+ *
+ * Converts an IxOsalTimeval structure into milliseconds
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - Corresponding number of milliseconds
+ * Note: This function is OS-independent. Implemented by core.
+ */
+#define IX_OSAL_TIMEVAL_TO_MS(tv) ((tv.secs * 1000) + (tv.nsecs / 1000000))
+
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Converts milliseconds to IxOsalTimeval
+ *
+ * @param milliseconds - number of milliseconds to convert
+ * @param pTv - pointer to the destination structure
+ *
+ * Converts a millisecond value into an IxOsalTimeval structure
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - Corresponding IxOsalTimeval structure
+ * Note: This function is OS-independent. Implemented by core.
+ */
+#define IX_OSAL_MS_TO_TIMEVAL(milliseconds, pTv) \
+ ((IxOsalTimeval *) pTv)->secs = milliseconds / 1000; \
+ ((IxOsalTimeval *) pTv)->nsecs = (milliseconds % 1000) * 1000000
+
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief "equal" comparison for IxOsalTimeval
+ *
+ * @param tvA, tvB - IxOsalTimeval structures to compare
+ *
+ * Compares two IxOsalTimeval structures for equality
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - TRUE if the structures are equal
+ * - FALSE otherwise
+ * Note: This function is OS-independant
+ */
+#define IX_OSAL_TIME_EQ(tvA, tvB) \
+ ((tvA).secs == (tvB).secs && (tvA).nsecs == (tvB).nsecs)
+
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief "less than" comparison for IxOsalTimeval
+ *
+ * @param tvA, tvB - IxOsalTimeval structures to compare
+ *
+ * Compares two IxOsalTimeval structures to determine if the first one is
+ * less than the second one
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - TRUE if tvA < tvB
+ * - FALSE otherwise
+ * Note: This function is OS-independent. Implemented by core.
+ */
+#define IX_OSAL_TIME_LT(tvA,tvB) \
+ ((tvA).secs < (tvB).secs || \
+ ((tvA).secs == (tvB).secs && (tvA).nsecs < (tvB).nsecs))
+
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief "greater than" comparison for IxOsalTimeval
+ *
+ * @param tvA, tvB - IxOsalTimeval structures to compare
+ *
+ * Compares two IxOsalTimeval structures to determine if the first one is
+ * greater than the second one
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - TRUE if tvA > tvB
+ * - FALSE otherwise
+ * Note: This function is OS-independent.
+ */
+#define IX_OSAL_TIME_GT(tvA, tvB) \
+ ((tvA).secs > (tvB).secs || \
+ ((tvA).secs == (tvB).secs && (tvA).nsecs > (tvB).nsecs))
+
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief "add" operator for IxOsalTimeval
+ *
+ * @param tvA, tvB - IxOsalTimeval structures to add
+ *
+ * Adds the second IxOsalTimevalStruct to the first one (equivalent to
+ * tvA += tvB)
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - none
+ * Note: This function is OS-independent.
+ */
+#define IX_OSAL_TIME_ADD(tvA, tvB) \
+ (tvA).secs += (tvB).secs; \
+ (tvA).nsecs += (tvB).nsecs; \
+ if ((tvA).nsecs >= IX_OSAL_BILLION) \
+ { \
+ (tvA).secs++; \
+ (tvA).nsecs -= IX_OSAL_BILLION; }
+
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief "subtract" operator for IxOsalTimeval
+ *
+ * @param tvA, tvB - IxOsalTimeval structures to subtract
+ *
+ * Subtracts the second IxOsalTimevalStruct from the first one (equivalent
+ * to tvA -= tvB)
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - none
+ * Note: This function is OS-independent. Implemented by core.
+ */
+#define IX_OSAL_TIME_SUB(tvA, tvB) \
+ if ((tvA).nsecs >= (tvB).nsecs) \
+ { \
+ (tvA).secs -= (tvB).secs; \
+ (tvA).nsecs -= (tvB).nsecs; \
+ } \
+ else \
+ { \
+ (tvA).secs -= ((tvB).secs + 1); \
+ (tvA).nsecs += IX_OSAL_BILLION - (tvB).nsecs; \
+ }
+
+
+/* ============================= Logging ==============================
+ *
+ */
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Interrupt-safe logging function
+ *
+ * @param level - identifier prefix for the message
+ * @param device - output device
+ * @param format - message format, in a printf format
+ * @param ... - up to 6 arguments to be printed
+ *
+ * IRQ-safe logging function, similar to printf. Accepts up to 6 arguments
+ * to print (excluding the level, device and the format). This function will
+ * actually display the message only if the level is lower than the current
+ * verbosity level or if the IX_OSAL_LOG_USER level is used. An output device
+ * must be specified (see IxOsalTypes.h).
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - Beside the exceptions documented in the note below, the returned
+ * value is the number of printed characters, or -1 if the parameters are
+ * incorrect (NULL format, unknown output device)
+ *
+ * @note The exceptions to the return value are:
+ * VxWorks: The return value is 32 if the specified level is 1 and 64
+ * if the specified level is greater than 1 and less or equal than 9.
+ * WinCE: If compiled for EBOOT then the return value is always 0.
+ *
+ * @note The given print format should take into account the specified
+ * output device. IX_OSAL_STDOUT supports all the usual print formats,
+ * however a custom hex display specified by IX_OSAL_HEX would support
+ * only a fixed number of hexadecimal digits.
+ */
+PUBLIC INT32 ixOsalLog (IxOsalLogLevel level,
+ IxOsalLogDevice device,
+ char *format,
+ int arg1,
+ int arg2, int arg3, int arg4, int arg5, int arg6);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief sets the current logging verbosity level
+ *
+ * @param level - new log verbosity level
+ *
+ * Sets the log verbosity level. The default value is IX_OSAL_LOG_ERROR.
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * @return - Old log verbosity level
+ */
+PUBLIC UINT32 ixOsalLogLevelSet (UINT32 level);
+
+
+/* ============================= Logging ==============================
+ *
+ */
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Schedules a repeating timer
+ *
+ * @param timer - handle of the timer object
+ * @param period - timer trigger period, in milliseconds
+ * @param priority - timer priority (0 being the highest)
+ * @param callback - user callback to invoke when the timer triggers
+ * @param param - custom parameter passed to the callback
+ *
+ * Schedules a timer to be called every period milliseconds. The timer
+ * will invoke the specified callback function possibly in interrupt
+ * context, passing the given parameter. If several timers trigger at the
+ * same time contention issues are dealt according to the specified timer
+ * priorities.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalRepeatingTimerSchedule (IxOsalTimer * timer,
+ UINT32 period,
+ UINT32 priority,
+ IxOsalVoidFnVoidPtr callback,
+ void *param);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Schedules a single-shot timer
+ *
+ * @param timer - handle of the timer object
+ * @param period - timer trigger period, in milliseconds
+ * @param priority - timer priority (0 being the highest)
+ * @param callback - user callback to invoke when the timer triggers
+ * @param param - custom parameter passed to the callback
+ *
+ * Schedules a timer to be called after period milliseconds. The timer
+ * will cease to function past its first trigger. The timer will invoke
+ * the specified callback function, possibly in interrupt context, passing
+ * the given parameter. If several timers trigger at the same time contention
+ * issues are dealt according to the specified timer priorities.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS
+ixOsalSingleShotTimerSchedule (IxOsalTimer * timer,
+ UINT32 period,
+ UINT32 priority,
+ IxOsalVoidFnVoidPtr callback, void *param);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief Cancels a running timer
+ *
+ * @param timer - handle of the timer object
+ *
+ * Cancels a single-shot or repeating timer.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalTimerCancel (IxOsalTimer * timer);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief displays all the running timers
+ *
+ * Displays a list with all the running timers and their parameters (handle,
+ * period, type, priority, callback and user parameter)
+ *
+ * @li Reentrant: no
+ * @li IRQ safe: no
+ *
+ * @return - none
+ */
+PUBLIC void ixOsalTimersShow (void);
+
+
+/* ============================= Version ==============================
+ *
+ */
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief provides the name of the Operating System running
+ *
+ * @param osName - Pointer to a NULL-terminated string of characters
+ * that holds the name of the OS running.
+ * This is both an input and an ouput parameter
+ * @param maxSize - Input parameter that defines the maximum number of
+ * bytes that can be stored in osName
+ *
+ * Returns a string of characters that describe the Operating System name
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * return - IX_SUCCESS for successful retrieval
+ * - IX_FAIL if (osType == NULL | maxSize =< 0)
+ */
+PUBLIC IX_STATUS ixOsalOsNameGet (INT8* osName, INT32 maxSize);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief provides the version of the Operating System running
+ *
+ * @param osVersion - Pointer to a NULL terminated string of characters
+ * that holds the version of the OS running.
+ * This is both an input and an ouput parameter
+ * @param maxSize - Input parameter that defines the maximum number of
+ * bytes that can be stored in osVersion
+ *
+ * Returns a string of characters that describe the Operating System's version
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe: yes
+ *
+ * return - IX_SUCCESS for successful retrieval
+ * - IX_FAIL if (osVersion == NULL | maxSize =< 0)
+ */
+PUBLIC IX_STATUS ixOsalOsVersionGet(INT8* osVersion, INT32 maxSize);
+
+
+
+/**
+ * @} IxOsal
+ */
+
+#endif /* IxOsal_H */
diff --git a/cpu/ixp/npe/include/IxOsalAssert.h b/cpu/ixp/npe/include/IxOsalAssert.h
new file mode 100644
index 0000000..45cebcd
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalAssert.h
@@ -0,0 +1,81 @@
+/*
+ * @file IxOsalAssert.h
+ * @author Intel Corporation
+ * @date 25-08-2004
+ *
+ * @brief description goes here
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IX_OSAL_ASSERT_H
+#define IX_OSAL_ASSERT_H
+
+/*
+ * Put the system defined include files required
+ * @par
+ * <TAGGED>
+ */
+
+#include "IxOsalOsAssert.h"
+
+/**
+ * @brief Assert macro, assert the condition is true. This
+ * will not be compiled out.
+ * N.B. will result in a system crash if it is false.
+ */
+#define IX_OSAL_ASSERT(c) IX_OSAL_OS_ASSERT(c)
+
+
+/**
+ * @brief Ensure macro, ensure the condition is true.
+ * This will be conditionally compiled out and
+ * may be used for test purposes.
+ */
+#ifdef IX_OSAL_ENSURE_ON
+#define IX_OSAL_ENSURE(c, str) do { \
+if (!(c)) ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, str, \
+0, 0, 0, 0, 0, 0); } while (0)
+
+#else
+#define IX_OSAL_ENSURE(c, str)
+#endif
+
+
+#endif /* IX_OSAL_ASSERT_H */
diff --git a/cpu/ixp/npe/include/IxOsalBackward.h b/cpu/ixp/npe/include/IxOsalBackward.h
new file mode 100644
index 0000000..ea9f307
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalBackward.h
@@ -0,0 +1,65 @@
+/**
+ * This file is intended to provide backward
+ * compatibility for main osService/OSSL
+ * APIs.
+ *
+ * It shall be phased out gradually and users
+ * are strongly recommended to use IX_OSAL API.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IX_OSAL_BACKWARD_H
+#define IX_OSAL_BACKWARD_H
+
+#include "IxOsal.h"
+
+#include "IxOsalBackwardCacheMMU.h"
+
+#include "IxOsalBackwardOsServices.h"
+
+#include "IxOsalBackwardMemMap.h"
+
+#include "IxOsalBackwardBufferMgt.h"
+
+#include "IxOsalBackwardOssl.h"
+
+#include "IxOsalBackwardAssert.h"
+
+#endif /* IX_OSAL_BACKWARD_H */
diff --git a/cpu/ixp/npe/include/IxOsalBackwardAssert.h b/cpu/ixp/npe/include/IxOsalBackwardAssert.h
new file mode 100644
index 0000000..be1e272
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalBackwardAssert.h
@@ -0,0 +1,54 @@
+/**
+ * This file is intended to provide backward
+ * compatibility for main osService/OSSL
+ * APIs.
+ *
+ * It shall be phased out gradually and users
+ * are strongly recommended to use IX_OSAL API.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IX_OSAL_BACKWARD_ASSERT_H
+#define IX_OSAL_BACKWARD_ASSERT_H
+
+#define IX_ENSURE(c, str) IX_OSAL_ENSURE(c, str)
+#define IX_ASSERT(c) IX_OSAL_ASSERT(c)
+
+#endif /* IX_OSAL_BACKWARD_ASSERT_H */
diff --git a/cpu/ixp/npe/include/IxOsalBackwardBufferMgt.h b/cpu/ixp/npe/include/IxOsalBackwardBufferMgt.h
new file mode 100644
index 0000000..5ac3f0c
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalBackwardBufferMgt.h
@@ -0,0 +1,159 @@
+/**
+ * This file is intended to provide backward
+ * compatibility for main osService/OSSL
+ * APIs.
+ *
+ * It shall be phased out gradually and users
+ * are strongly recommended to use IX_OSAL API.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IX_OSAL_BACKWARD_BUFFER_MGT_H
+#define IX_OSAL_BACKWARD_BUFFER_MGT_H
+
+typedef IX_OSAL_MBUF IX_MBUF;
+
+typedef IX_OSAL_MBUF_POOL IX_MBUF_POOL;
+
+
+#define IX_MBUF_NEXT_BUFFER_IN_PKT_PTR(m_blk_ptr) \
+ IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m_blk_ptr)
+
+
+#define IX_MBUF_NEXT_PKT_IN_CHAIN_PTR(m_blk_ptr) \
+ IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m_blk_ptr)
+
+
+#define IX_MBUF_MDATA(m_blk_ptr) \
+ IX_OSAL_MBUF_MDATA(m_blk_ptr)
+
+
+#define IX_MBUF_MLEN(m_blk_ptr) \
+ IX_OSAL_MBUF_MLEN(m_blk_ptr)
+
+
+#define IX_MBUF_TYPE(m_blk_ptr) \
+ IX_OSAL_MBUF_MTYPE(m_blk_ptr)
+
+/* Same as IX_MBUF_TYPE */
+#define IX_MBUF_MTYPE(m_blk_ptr) \
+ IX_OSAL_MBUF_MTYPE(m_blk_ptr)
+
+#define IX_MBUF_FLAGS(m_blk_ptr) \
+ IX_OSAL_MBUF_FLAGS(m_blk_ptr)
+
+
+#define IX_MBUF_NET_POOL(m_blk_ptr) \
+ IX_OSAL_MBUF_NET_POOL(m_blk_ptr)
+
+
+#define IX_MBUF_PKT_LEN(m_blk_ptr) \
+ IX_OSAL_MBUF_PKT_LEN(m_blk_ptr)
+
+
+#define IX_MBUF_PRIV(m_blk_ptr) \
+ IX_OSAL_MBUF_PRIV(m_blk_ptr)
+
+
+#define IX_MBUF_ALLOCATED_BUFF_LEN(m_blk_ptr) \
+ IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(m_blk_ptr)
+
+
+#define IX_MBUF_ALLOCATED_BUFF_DATA(m_blk_ptr) \
+ IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(m_blk_ptr)
+
+
+#define IX_MBUF_POOL_SIZE_ALIGN(size) \
+ IX_OSAL_MBUF_POOL_SIZE_ALIGN(size)
+
+
+#define IX_MBUF_POOL_MBUF_AREA_SIZE_ALIGNED(count) \
+ IX_OSAL_MBUF_POOL_MBUF_AREA_SIZE_ALIGNED(count)
+
+
+#define IX_MBUF_POOL_DATA_AREA_SIZE_ALIGNED(count, size) \
+ IX_OSAL_MBUF_POOL_DATA_AREA_SIZE_ALIGNED(count, size)
+
+
+#define IX_MBUF_POOL_MBUF_AREA_ALLOC(count, memAreaSize) \
+ IX_OSAL_MBUF_POOL_MBUF_AREA_ALLOC(count, memAreaSize)
+
+
+#define IX_MBUF_POOL_DATA_AREA_ALLOC(count, size, memAreaSize) \
+ IX_OSAL_MBUF_POOL_DATA_AREA_ALLOC(count, size, memAreaSize)
+
+IX_STATUS
+ixOsalOsIxp400BackwardPoolInit (IX_OSAL_MBUF_POOL ** poolPtrPtr,
+ UINT32 count, UINT32 size, const char *name);
+
+
+/* This one needs extra steps*/
+#define IX_MBUF_POOL_INIT(poolPtr, count, size, name) \
+ ixOsalOsIxp400BackwardPoolInit( poolPtr, count, size, name)
+
+
+#define IX_MBUF_POOL_INIT_NO_ALLOC(poolPtrPtr, bufPtr, dataPtr, count, size, name) \
+ (*poolPtrPtr = IX_OSAL_MBUF_NO_ALLOC_POOL_INIT(bufPtr, dataPtr, count, size, name))
+
+
+IX_STATUS
+ixOsalOsIxp400BackwardMbufPoolGet (IX_OSAL_MBUF_POOL * poolPtr,
+ IX_OSAL_MBUF ** newBufPtrPtr);
+
+#define IX_MBUF_POOL_GET(poolPtr, bufPtrPtr) \
+ ixOsalOsIxp400BackwardMbufPoolGet(poolPtr, bufPtrPtr)
+
+
+#define IX_MBUF_POOL_PUT(bufPtr) \
+ IX_OSAL_MBUF_POOL_PUT(bufPtr)
+
+
+#define IX_MBUF_POOL_PUT_CHAIN(bufPtr) \
+ IX_OSAL_MBUF_POOL_PUT_CHAIN(bufPtr)
+
+
+#define IX_MBUF_POOL_SHOW(poolPtr) \
+ IX_OSAL_MBUF_POOL_SHOW(poolPtr)
+
+
+#define IX_MBUF_POOL_MDATA_RESET(bufPtr) \
+ IX_OSAL_MBUF_POOL_MDATA_RESET(bufPtr)
+
+#endif /* IX_OSAL_BACKWARD_BUFFER_MGT_H */
diff --git a/cpu/ixp/npe/include/IxOsalBackwardCacheMMU.h b/cpu/ixp/npe/include/IxOsalBackwardCacheMMU.h
new file mode 100644
index 0000000..fe570e6
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalBackwardCacheMMU.h
@@ -0,0 +1,69 @@
+/**
+ * This file is intended to provide backward
+ * compatibility for main osService/OSSL
+ * APIs.
+ *
+ * It shall be phased out gradually and users
+ * are strongly recommended to use IX_OSAL API.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IX_OSAL_BACKWARD_CACHE_MMU_H
+#define IX_OSAL_BACKWARD_CACHE_MMU_H
+
+#ifdef IX_OSAL_CACHED
+#define IX_ACC_CACHE_ENABLED
+#endif
+
+#define IX_XSCALE_CACHE_LINE_SIZE IX_OSAL_CACHE_LINE_SIZE
+
+#define IX_ACC_DRV_DMA_MALLOC(size) IX_OSAL_CACHE_DMA_MALLOC(size)
+
+#define IX_ACC_DRV_DMA_FREE(ptr,size) IX_OSAL_CACHE_DMA_FREE(ptr)
+
+#define IX_MMU_VIRTUAL_TO_PHYSICAL_TRANSLATION(addr) IX_OSAL_MMU_VIRT_TO_PHYS(addr)
+
+#define IX_MMU_PHYSICAL_TO_VIRTUAL_TRANSLATION(addr) IX_OSAL_MMU_PHYS_TO_VIRT(addr)
+
+#define IX_ACC_DATA_CACHE_INVALIDATE(addr,size) IX_OSAL_CACHE_INVALIDATE(addr, size)
+
+#define IX_ACC_DATA_CACHE_FLUSH(addr,size) IX_OSAL_CACHE_FLUSH(addr,size)
+
+#endif /* IX_OSAL_BACKWARD_CACHE_MMU_H */
diff --git a/cpu/ixp/npe/include/IxOsalBackwardMemMap.h b/cpu/ixp/npe/include/IxOsalBackwardMemMap.h
new file mode 100644
index 0000000..18f8f24
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalBackwardMemMap.h
@@ -0,0 +1,141 @@
+/**
+ * This file is intended to provide backward
+ * compatibility for main osService/OSSL
+ * APIs.
+ *
+ * It shall be phased out gradually and users
+ * are strongly recommended to use IX_OSAL API.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#ifndef IX_OSAL_BACKWARD_MEM_MAP_H
+#define IX_OSAL_BACKWARD_MEM_MAP_H
+
+#include "IxOsal.h"
+
+#define IX_OSSERV_SWAP_LONG(wData) IX_OSAL_SWAP_LONG(wData)
+#define IX_OSSERV_SWAP_SHORT(sData) IX_OSAL_SWAP_SHORT(sData)
+
+#define IX_OSSERV_SWAP_SHORT_ADDRESS(sAddr) IX_OSAL_SWAP_SHORT_ADDRESS(sAddr)
+#define IX_OSSERV_SWAP_BYTE_ADDRESS(bAddr) IX_OSAL_SWAP_BYTE_ADDRESS(bAddr)
+
+#define IX_OSSERV_BE_XSTOBUSL(wData) IX_OSAL_BE_XSTOBUSL(wData)
+#define IX_OSSERV_BE_XSTOBUSS(sData) IX_OSAL_BE_XSTOBUSS(sData)
+#define IX_OSSERV_BE_XSTOBUSB(bData) IX_OSAL_BE_XSTOBUSB(bData)
+#define IX_OSSERV_BE_BUSTOXSL(wData) IX_OSAL_BE_BUSTOXSL(wData)
+#define IX_OSSERV_BE_BUSTOXSS(sData) IX_OSAL_BE_BUSTOXSS(sData)
+#define IX_OSSERV_BE_BUSTOXSB(bData) IX_OSAL_BE_BUSTOXSB(bData)
+
+#define IX_OSSERV_LE_AC_XSTOBUSL(wAddr) IX_OSAL_LE_AC_XSTOBUSL(wAddr)
+#define IX_OSSERV_LE_AC_XSTOBUSS(sAddr) IX_OSAL_LE_AC_XSTOBUSS(sAddr)
+#define IX_OSSERV_LE_AC_XSTOBUSB(bAddr) IX_OSAL_LE_AC_XSTOBUSB(bAddr)
+#define IX_OSSERV_LE_AC_BUSTOXSL(wAddr) IX_OSAL_LE_AC_BUSTOXSL(wAddr)
+#define IX_OSSERV_LE_AC_BUSTOXSS(sAddr) IX_OSAL_LE_AC_BUSTOXSS(sAddr)
+#define IX_OSSERV_LE_AC_BUSTOXSB(bAddr) IX_OSAL_LE_AC_BUSTOXSB(bAddr)
+
+#define IX_OSSERV_LE_DC_XSTOBUSL(wData) IX_OSAL_LE_DC_XSTOBUSL(wData)
+#define IX_OSSERV_LE_DC_XSTOBUSS(sData) IX_OSAL_LE_DC_XSTOBUSS(sData)
+#define IX_OSSERV_LE_DC_XSTOBUSB(bData) IX_OSAL_LE_DC_XSTOBUSB(bData)
+#define IX_OSSERV_LE_DC_BUSTOXSL(wData) IX_OSAL_LE_DC_BUSTOXSL(wData)
+#define IX_OSSERV_LE_DC_BUSTOXSS(sData) IX_OSAL_LE_DC_BUSTOXSS(sData)
+#define IX_OSSERV_LE_DC_BUSTOXSB(bData) IX_OSAL_LE_DC_BUSTOXSB(bData)
+
+#define IX_OSSERV_READ_LONG(wAddr) IX_OSAL_READ_LONG(wAddr)
+#define IX_OSSERV_READ_SHORT(sAddr) IX_OSAL_READ_SHORT(sAddr)
+#define IX_OSSERV_READ_BYTE(bAddr) IX_OSAL_READ_BYTE(bAddr)
+#define IX_OSSERV_WRITE_LONG(wAddr, wData) IX_OSAL_WRITE_LONG(wAddr, wData)
+#define IX_OSSERV_WRITE_SHORT(sAddr, sData) IX_OSAL_WRITE_SHORT(sAddr, sData)
+#define IX_OSSERV_WRITE_BYTE(bAddr, bData) IX_OSAL_WRITE_BYTE(bAddr, bData)
+
+
+#define IX_OSSERV_READ_NPE_SHARED_LONG(wAddr) IX_OSAL_READ_BE_SHARED_LONG(wAddr)
+#define IX_OSSERV_READ_NPE_SHARED_SHORT(sAddr) IX_OSAL_READ_BE_SHARED_SHORT(sAddr)
+#define IX_OSSERV_WRITE_NPE_SHARED_LONG(wAddr, wData) IX_OSAL_WRITE_BE_SHARED_LONG(wAddr, wData)
+#define IX_OSSERV_WRITE_NPE_SHARED_SHORT(sAddr, sData) IX_OSAL_WRITE_BE_SHARED_SHORT(sAddr, sData)
+
+#define IX_OSSERV_SWAP_NPE_SHARED_LONG(wData) IX_OSAL_SWAP_BE_SHARED_LONG(wData)
+#define IX_OSSERV_SWAP_NPE_SHARED_SHORT(sData) IX_OSAL_SWAP_BE_SHARED_SHORT(sData)
+
+
+/* Map osServ address/size */
+#define IX_OSSERV_QMGR_MAP_SIZE IX_OSAL_IXP400_QMGR_MAP_SIZE
+#define IX_OSSERV_EXP_REG_MAP_SIZE IX_OSAL_IXP400_EXP_REG_MAP_SIZE
+#define IX_OSSERV_UART1_MAP_SIZE IX_OSAL_IXP400_UART1_MAP_SIZE
+#define IX_OSSERV_UART2_MAP_SIZE IX_OSAL_IXP400_UART2_MAP_SIZE
+#define IX_OSSERV_PMU_MAP_SIZE IX_OSAL_IXP400_PMU_MAP_SIZE
+#define IX_OSSERV_OSTS_MAP_SIZE IX_OSAL_IXP400_OSTS_MAP_SIZE
+#define IX_OSSERV_NPEA_MAP_SIZE IX_OSAL_IXP400_NPEA_MAP_SIZE
+#define IX_OSSERV_NPEB_MAP_SIZE IX_OSAL_IXP400_NPEB_MAP_SIZE
+#define IX_OSSERV_NPEC_MAP_SIZE IX_OSAL_IXP400_NPEC_MAP_SIZE
+#define IX_OSSERV_ETHA_MAP_SIZE IX_OSAL_IXP400_ETHA_MAP_SIZE
+#define IX_OSSERV_ETHB_MAP_SIZE IX_OSAL_IXP400_ETHB_MAP_SIZE
+#define IX_OSSERV_USB_MAP_SIZE IX_OSAL_IXP400_USB_MAP_SIZE
+#define IX_OSSERV_GPIO_MAP_SIZE IX_OSAL_IXP400_GPIO_MAP_SIZE
+#define IX_OSSERV_EXP_BUS_MAP_SIZE IX_OSAL_IXP400_EXP_BUS_MAP_SIZE
+#define IX_OSSERV_EXP_BUS_CS0_MAP_SIZE IX_OSAL_IXP400_EXP_BUS_CS0_MAP_SIZE
+#define IX_OSSERV_EXP_BUS_CS1_MAP_SIZE IX_OSAL_IXP400_EXP_BUS_CS1_MAP_SIZE
+#define IX_OSSERV_EXP_BUS_CS4_MAP_SIZE IX_OSAL_IXP400_EXP_BUS_CS4_MAP_SIZE
+
+
+#define IX_OSSERV_GPIO_PHYS_BASE IX_OSAL_IXP400_GPIO_PHYS_BASE
+#define IX_OSSERV_UART1_PHYS_BASE IX_OSAL_IXP400_UART1_PHYS_BASE
+#define IX_OSSERV_UART2_PHYS_BASE IX_OSAL_IXP400_UART2_PHYS_BASE
+#define IX_OSSERV_ETHA_PHYS_BASE IX_OSAL_IXP400_ETHA_PHYS_BASE
+#define IX_OSSERV_ETHB_PHYS_BASE IX_OSAL_IXP400_ETHB_PHYS_BASE
+#define IX_OSSERV_NPEA_PHYS_BASE IX_OSAL_IXP400_NPEA_PHYS_BASE
+#define IX_OSSERV_NPEB_PHYS_BASE IX_OSAL_IXP400_NPEB_PHYS_BASE
+#define IX_OSSERV_NPEC_PHYS_BASE IX_OSAL_IXP400_NPEC_PHYS_BASE
+#define IX_OSSERV_PERIPHERAL_PHYS_BASE IX_OSAL_IXP400_PERIPHERAL_PHYS_BASE
+#define IX_OSSERV_QMGR_PHYS_BASE IX_OSAL_IXP400_QMGR_PHYS_BASE
+#define IX_OSSERV_OSTS_PHYS_BASE IX_OSAL_IXP400_OSTS_PHYS_BASE
+#define IX_OSSERV_USB_PHYS_BASE IX_OSAL_IXP400_USB_PHYS_BASE
+#define IX_OSSERV_EXP_BUS_PHYS_BASE IX_OSAL_IXP400_EXP_BUS_PHYS_BASE
+#define IX_OSSERV_EXP_BUS_BOOT_PHYS_BASE IX_OSAL_IXP400_EXP_BUS_BOOT_PHYS_BASE
+#define IX_OSSERV_EXP_BUS_CS0_PHYS_BASE IX_OSAL_IXP400_EXP_BUS_CS0_PHYS_BASE
+#define IX_OSSERV_EXP_BUS_CS1_PHYS_BASE IX_OSAL_IXP400_EXP_BUS_CS1_PHYS_BASE
+#define IX_OSSERV_EXP_BUS_CS4_PHYS_BASE IX_OSAL_IXP400_EXP_BUS_CS4_PHYS_BASE
+#define IX_OSSERV_EXP_BUS_REGS_PHYS_BASE IX_OSAL_IXP400_EXP_BUS_REGS_PHYS_BASE
+
+#define IX_OSSERV_MEM_MAP(physAddr, size) IX_OSAL_MEM_MAP(physAddr, size)
+
+#define IX_OSSERV_MEM_UNMAP(virtAddr) IX_OSAL_MEM_UNMAP(virtAddr)
+
+#endif /* IX_OSAL_BACKWARD_MEM_MAP_H */
diff --git a/cpu/ixp/npe/include/IxOsalBackwardOsServices.h b/cpu/ixp/npe/include/IxOsalBackwardOsServices.h
new file mode 100644
index 0000000..0ccff84
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalBackwardOsServices.h
@@ -0,0 +1,125 @@
+/**
+ * This file is intended to provide backward
+ * compatibility for main osService/OSSL
+ * APIs.
+ *
+ * It shall be phased out gradually and users
+ * are strongly recommended to use IX_OSAL API.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IX_OSAL_BACKWARD_OSSERVICES_H
+#define IX_OSAL_BACKWARD_OSSERVICES_H
+
+#ifndef __vxworks
+typedef UINT32 IX_IRQ_STATUS;
+#else
+typedef int IX_IRQ_STATUS;
+#endif
+
+typedef IxOsalMutex IxMutex;
+
+typedef IxOsalFastMutex IxFastMutex;
+
+typedef IxOsalVoidFnVoidPtr IxVoidFnVoidPtr;
+
+typedef IxOsalVoidFnPtr IxVoidFnPtr;
+
+
+#define LOG_NONE IX_OSAL_LOG_LVL_NONE
+#define LOG_USER IX_OSAL_LOG_LVL_USER
+#define LOG_FATAL IX_OSAL_LOG_LVL_FATAL
+#define LOG_ERROR IX_OSAL_LOG_LVL_ERROR
+#define LOG_WARNING IX_OSAL_LOG_LVL_WARNING
+#define LOG_MESSAGE IX_OSAL_LOG_LVL_MESSAGE
+#define LOG_DEBUG1 IX_OSAL_LOG_LVL_DEBUG1
+#define LOG_DEBUG2 IX_OSAL_LOG_LVL_DEBUG2
+#define LOG_DEBUG3 IX_OSAL_LOG_LVL_DEBUG3
+#ifndef __vxworks
+#define LOG_ALL IX_OSAL_LOG_LVL_ALL
+#endif
+
+PUBLIC IX_STATUS
+ixOsServIntBind (int level, void (*routine) (void *), void *parameter);
+
+PUBLIC IX_STATUS ixOsServIntUnbind (int level);
+
+
+PUBLIC int ixOsServIntLock (void);
+
+PUBLIC void ixOsServIntUnlock (int lockKey);
+
+
+PUBLIC int ixOsServIntLevelSet (int level);
+
+PUBLIC IX_STATUS ixOsServMutexInit (IxMutex * mutex);
+
+PUBLIC IX_STATUS ixOsServMutexLock (IxMutex * mutex);
+
+PUBLIC IX_STATUS ixOsServMutexUnlock (IxMutex * mutex);
+
+PUBLIC IX_STATUS ixOsServMutexDestroy (IxMutex * mutex);
+
+PUBLIC IX_STATUS ixOsServFastMutexInit (IxFastMutex * mutex);
+
+PUBLIC IX_STATUS ixOsServFastMutexTryLock (IxFastMutex * mutex);
+
+PUBLIC IX_STATUS ixOsServFastMutexUnlock (IxFastMutex * mutex);
+
+PUBLIC int
+ixOsServLog (int level, char *format, int arg1, int arg2, int arg3, int arg4,
+ int arg5, int arg6);
+
+
+PUBLIC int ixOsServLogLevelSet (int level);
+
+PUBLIC void ixOsServSleep (int microseconds);
+
+PUBLIC void ixOsServTaskSleep (int milliseconds);
+
+PUBLIC unsigned int ixOsServTimestampGet (void);
+
+
+PUBLIC void ixOsServUnload (void);
+
+PUBLIC void ixOsServYield (void);
+
+#endif
+/* IX_OSAL_BACKWARD_OSSERVICES_H */
diff --git a/cpu/ixp/npe/include/IxOsalBackwardOssl.h b/cpu/ixp/npe/include/IxOsalBackwardOssl.h
new file mode 100644
index 0000000..634b494
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalBackwardOssl.h
@@ -0,0 +1,272 @@
+/**
+ * This file is intended to provide backward
+ * compatibility for main osService/OSSL
+ * APIs.
+ *
+ * It shall be phased out gradually and users
+ * are strongly recommended to use IX_OSAL API.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IX_OSAL_BACKWARD_OSSL_H
+#define IX_OSAL_BACKWARD_OSSL_H
+
+
+typedef IxOsalThread ix_ossl_thread_t;
+
+typedef IxOsalSemaphore ix_ossl_sem_t;
+
+typedef IxOsalMutex ix_ossl_mutex_t;
+
+typedef IxOsalTimeval ix_ossl_time_t;
+
+
+/* Map sub-fields for ix_ossl_time_t */
+#define tv_sec secs
+#define tv_nec nsecs
+
+
+typedef IX_STATUS ix_error;
+
+typedef UINT32 ix_ossl_thread_priority;
+
+typedef UINT32 ix_uint32;
+
+
+#define IX_OSSL_ERROR_SUCCESS IX_SUCCESS
+
+#define IX_ERROR_SUCCESS IX_SUCCESS
+
+
+typedef enum
+{
+ IX_OSSL_SEM_UNAVAILABLE = 0,
+ IX_OSSL_SEM_AVAILABLE
+} ix_ossl_sem_state;
+
+
+typedef enum
+{
+ IX_OSSL_MUTEX_UNLOCK = 0,
+ IX_OSSL_MUTEX_LOCK
+} ix_ossl_mutex_state;
+
+
+typedef IxOsalVoidFnVoidPtr ix_ossl_thread_entry_point_t;
+
+
+#define IX_OSSL_THREAD_PRI_HIGH 90
+#define IX_OSSL_THREAD_PRI_MEDIUM 160
+#define IX_OSSL_THREAD_PRI_LOW 240
+
+
+#define IX_OSSL_WAIT_FOREVER IX_OSAL_WAIT_FOREVER
+
+#define IX_OSSL_WAIT_NONE IX_OSAL_WAIT_NONE
+
+#define BILLION IX_OSAL_BILLION
+
+#define IX_OSSL_TIME_EQ(a,b) IX_OSAL_TIME_EQ(a,b)
+
+#define IX_OSSL_TIME_GT(a,b) IX_OSAL_TIME_GT(a,b)
+
+#define IX_OSSL_TIME_LT(a,b) IX_OSAL_TIME_LT(a,b)
+
+#define IX_OSSL_TIME_ADD(a,b) IX_OSAL_TIME_ADD(a,b)
+
+#define IX_OSSL_TIME_SUB(a,b) IX_OSAL_TIME_SUB(a,b)
+
+
+/* a is tick, b is timeval */
+#define IX_OSSL_TIME_CONVERT_TO_TICK(a,b) \
+ (a) = IX_OSAL_TIMEVAL_TO_TICKS(b)
+
+
+
+
+PUBLIC IX_STATUS
+ixOsalOsIxp400BackwardOsslThreadCreate (IxOsalVoidFnVoidPtr entryPoint,
+ void *arg, IxOsalThread * ptrThread);
+
+#define ix_ossl_thread_create(entryPoint, arg, ptrTid) \
+ ixOsalOsIxp400BackwardOsslThreadCreate(entryPoint, arg, ptrTid)
+
+
+/* void ix_ossl_thread_exit(ix_error retError, void* retObj) */
+#define ix_ossl_thread_exit(retError, retObj) \
+ ixOsalThreadExit()
+
+
+PUBLIC IX_STATUS ixOsalOsIxp400BackwardOsslThreadKill (IxOsalThread tid);
+
+/* ix_error ix_ossl_thread_kill(tid) */
+#define ix_ossl_thread_kill(tid) \
+ ixOsalOsIxp400BackwardOsslThreadKill(tid)
+
+
+PUBLIC IX_STATUS
+ixOsalOsIxp400BackwardOsslThreadSetPriority (IxOsalThread tid,
+ UINT32 priority);
+
+
+/*
+ * ix_error ix_ossl_thread_set_priority(ix_ossl_thread_t tid,
+ * ix_ossl_thread_priority priority
+ * );
+ */
+
+#define ix_ossl_thread_set_priority(tid, priority) \
+ ixOsalOsIxp400BackwardOsslThreadSetPriority(tid, priority)
+
+
+PUBLIC IX_STATUS ixOsalOsIxp400BackwardOsslTickGet (int *pticks);
+
+#define ix_ossl_tick_get(pticks) \
+ ixOsalOsIxp400BackwardOsslTickGet(pticks)
+
+PUBLIC IX_STATUS ixOsalOsIxp400BackwardOsslThreadDelay (int ticks);
+
+#define ix_ossl_thread_delay(ticks) ixOsalOsIxp400BackwardOsslThreadDelay(ticks)
+
+
+
+/* ix_error ix_ossl_sem_init(int start_value, ix_ossl_sem_t* sid); */
+/* Note sid is a pointer to semaphore */
+#define ix_ossl_sem_init(value, sid) \
+ ixOsalSemaphoreInit(sid, value)
+
+
+PUBLIC IX_STATUS
+ixOsalOsIxp400BackwardOsslSemaphoreWait (IxOsalSemaphore semaphore,
+ INT32 timeout);
+
+
+/*
+ix_error ix_ossl_sem_take(
+ ix_ossl_sem_t sid,
+ ix_uint32 timeout
+ );
+*/
+
+#define ix_ossl_sem_take( sid, timeout) \
+ ixOsalOsIxp400BackwardOsslSemaphoreWait(sid, timeout)
+
+
+
+PUBLIC IX_STATUS
+ixOsalOsIxp400BackwardOsslSemaphorePost (IxOsalSemaphore sid);
+
+/*ix_error ix_ossl_sem_give(ix_ossl_sem_t sid); */
+#define ix_ossl_sem_give(sid) \
+ ixOsalOsIxp400BackwardOsslSemaphorePost(sid);
+
+
+PUBLIC IX_STATUS ixOsalOsIxp400BackwardSemaphoreDestroy (IxOsalSemaphore sid);
+
+#define ix_ossl_sem_fini(sid) \
+ ixOsalOsIxp400BackwardSemaphoreDestroy(sid)
+
+
+PUBLIC IX_STATUS
+ixOsalOsIxp400BackwardOsslMutexInit (ix_ossl_mutex_state start_state,
+ IxOsalMutex * pMutex);
+
+
+/* ix_error ix_ossl_mutex_init(ix_ossl_mutex_state start_state, ix_ossl_mutex_t* mid); */
+#define ix_ossl_mutex_init(start_state, pMutex) \
+ ixOsalOsIxp400BackwardOsslMutexInit(start_state, pMutex)
+
+
+PUBLIC IX_STATUS
+ixOsalOsIxp400BackwardOsslMutexLock (IxOsalMutex mid, INT32 timeout);
+
+/*
+ix_error ix_ossl_mutex_lock(
+ ix_ossl_mutex_t mid,
+ ix_uint32 timeout
+ );
+*/
+#define ix_ossl_mutex_lock(mid, timeout) \
+ ixOsalOsIxp400BackwardOsslMutexLock(mid, timout)
+
+
+PUBLIC IX_STATUS ixOsalOsIxp400BackwardOsslMutexUnlock (IxOsalMutex mid);
+
+/* ix_error ix_ossl_mutex_unlock(ix_ossl_mutex_t mid); */
+#define ix_ossl_mutex_unlock(mid) \
+ ixOsalOsIxp400BackwardOsslMutexUnlock(mid)
+
+PUBLIC IX_STATUS ixOsalOsIxp400BackwardOsslMutexDestroy (IxOsalMutex mid);
+
+#define ix_ossl_mutex_fini(mid) \
+ ixOsalOsIxp400BackwardOsslMutexDestroy(mid);
+
+#define ix_ossl_sleep(sleeptime_ms) \
+ ixOsalSleep(sleeptime_ms)
+
+PUBLIC IX_STATUS ixOsalOsIxp400BackwardOsslSleepTick (UINT32 ticks);
+
+#define ix_ossl_sleep_tick(sleeptime_ticks) \
+ ixOsalOsIxp400BackwardOsslSleepTick(sleeptime_ticks)
+
+
+PUBLIC IX_STATUS ixOsalOsIxp400BackwardOsslTimeGet (IxOsalTimeval * pTv);
+
+#define ix_ossl_time_get(pTv) \
+ ixOsalOsIxp400BackwardOsslTimeGet(pTv)
+
+
+typedef UINT32 ix_ossl_size_t;
+
+#define ix_ossl_malloc(arg_size) \
+ ixOsalMemAlloc(arg_size)
+
+#define ix_ossl_free(arg_pMemory) \
+ ixOsalMemFree(arg_pMemory)
+
+
+#define ix_ossl_memcpy(arg_pDest, arg_pSrc,arg_Count) \
+ ixOsalMemCopy(arg_pDest, arg_pSrc,arg_Count)
+
+#define ix_ossl_memset(arg_pDest, arg_pChar, arg_Count) \
+ ixOsalMemSet(arg_pDest, arg_pChar, arg_Count)
+
+
+#endif /* IX_OSAL_BACKWARD_OSSL_H */
diff --git a/cpu/ixp/npe/include/IxOsalBufferMgt.h b/cpu/ixp/npe/include/IxOsalBufferMgt.h
new file mode 100644
index 0000000..497ed04
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalBufferMgt.h
@@ -0,0 +1,621 @@
+/**
+ * @file IxOsalBufferMgt.h
+ *
+ * @brief OSAL Buffer pool management and buffer management definitions.
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+/* @par
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsalBufferMgt_H
+#define IxOsalBufferMgt_H
+
+#include "IxOsal.h"
+/**
+ * @defgroup IxOsalBufferMgt OSAL Buffer Management Module.
+ *
+ * @brief Buffer management module for IxOsal
+ *
+ * @{
+ */
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_MAX_POOLS
+ *
+ * @brief The maximum number of pools that can be allocated, must be
+ * a multiple of 32 as required by implementation logic.
+ * @note This can safely be increased if more pools are required.
+ */
+#define IX_OSAL_MBUF_MAX_POOLS 32
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_NAME_LEN
+ *
+ * @brief The maximum string length of the pool name
+ */
+#define IX_OSAL_MBUF_POOL_NAME_LEN 64
+
+
+
+/**
+ * Define IX_OSAL_MBUF
+ */
+
+
+/* forward declaration of internal structure */
+struct __IXP_BUF;
+
+/*
+ * OS can define it in IxOsalOs.h to skip the following
+ * definition.
+ */
+#ifndef IX_OSAL_ATTRIBUTE_ALIGN32
+#define IX_OSAL_ATTRIBUTE_ALIGN32 __attribute__ ((aligned(32)))
+#endif
+
+/* release v1.4 backward compatible definitions */
+struct __IX_MBUF
+{
+ struct __IXP_BUF *ix_next IX_OSAL_ATTRIBUTE_ALIGN32;
+ struct __IXP_BUF *ix_nextPacket;
+ UINT8 *ix_data;
+ UINT32 ix_len;
+ unsigned char ix_type;
+ unsigned char ix_flags;
+ unsigned short ix_reserved;
+ UINT32 ix_rsvd;
+ UINT32 ix_PktLen;
+ void *ix_priv;
+};
+
+struct __IX_CTRL
+{
+ UINT32 ix_reserved[2]; /**< Reserved field */
+ UINT32 ix_signature; /**< Field to indicate if buffers are allocated by the system */
+ UINT32 ix_allocated_len; /**< Allocated buffer length */
+ UINT32 ix_allocated_data; /**< Allocated buffer data pointer */
+ void *ix_pool; /**< pointer to the buffer pool */
+ struct __IXP_BUF *ix_chain; /**< chaining */
+ void *ix_osbuf_ptr; /**< Storage for OS-specific buffer pointer */
+};
+
+struct __IX_NE_SHARED
+{
+ UINT32 reserved[8] IX_OSAL_ATTRIBUTE_ALIGN32; /**< Reserved area for NPE Service-specific usage */
+};
+
+
+/*
+ * IXP buffer structure
+ */
+typedef struct __IXP_BUF
+{
+ struct __IX_MBUF ix_mbuf IX_OSAL_ATTRIBUTE_ALIGN32; /**< buffer header */
+ struct __IX_CTRL ix_ctrl; /**< buffer management */
+ struct __IX_NE_SHARED ix_ne; /**< Reserved area for NPE Service-specific usage*/
+} IXP_BUF;
+
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def typedef IX_OSAL_MBUF
+ *
+ * @brief Generic IXP mbuf format.
+ */
+typedef IXP_BUF IX_OSAL_MBUF;
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_IXP_NEXT_BUFFER_IN_PKT_PTR(m_blk_ptr)
+ *
+ * @brief Return pointer to the next mbuf in a single packet
+ */
+#define IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m_blk_ptr) \
+ (m_blk_ptr)->ix_mbuf.ix_next
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m_blk_ptr)
+ *
+ * @brief Return pointer to the next packet in the chain
+ */
+#define IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m_blk_ptr) \
+ (m_blk_ptr)->ix_mbuf.ix_nextPacket
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_MDATA(m_blk_ptr)
+ *
+ * @brief Return pointer to the data in the mbuf
+ */
+#define IX_OSAL_MBUF_MDATA(m_blk_ptr) (m_blk_ptr)->ix_mbuf.ix_data
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_MLEN(m_blk_ptr)
+ *
+ * @brief Return the data length
+ */
+#define IX_OSAL_MBUF_MLEN(m_blk_ptr) \
+ (m_blk_ptr)->ix_mbuf.ix_len
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_MTYPE(m_blk_ptr)
+ *
+ * @brief Return the data type in the mbuf
+ */
+#define IX_OSAL_MBUF_MTYPE(m_blk_ptr) \
+ (m_blk_ptr)->ix_mbuf.ix_type
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_FLAGS(m_blk_ptr)
+ *
+ * @brief Return the buffer flags
+ */
+#define IX_OSAL_MBUF_FLAGS(m_blk_ptr) \
+ (m_blk_ptr)->ix_mbuf.ix_flags
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_NET_POOL(m_blk_ptr)
+ *
+ * @brief Return pointer to a network pool
+ */
+#define IX_OSAL_MBUF_NET_POOL(m_blk_ptr) \
+ (m_blk_ptr)->ix_ctrl.ix_pool
+
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_PKT_LEN(m_blk_ptr)
+ *
+ * @brief Return the total length of all the data in
+ * the mbuf chain for this packet
+ */
+#define IX_OSAL_MBUF_PKT_LEN(m_blk_ptr) \
+ (m_blk_ptr)->ix_mbuf.ix_PktLen
+
+
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_PRIV(m_blk_ptr)
+ *
+ * @brief Return the private field
+ */
+#define IX_OSAL_MBUF_PRIV(m_blk_ptr) \
+ (m_blk_ptr)->ix_mbuf.ix_priv
+
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_SIGNATURE(m_blk_ptr)
+ *
+ * @brief Return the signature field of IX_OSAL_MBUF
+ */
+#define IX_OSAL_MBUF_SIGNATURE(m_blk_ptr) \
+ (m_blk_ptr)->ix_ctrl.ix_signature
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_OSBUF_PTR(m_blk_ptr)
+ *
+ * @brief Return ix_osbuf_ptr field of IX_OSAL_MBUF, which is used to store OS-specific buffer pointer during a buffer conversion.
+ */
+#define IX_OSAL_MBUF_OSBUF_PTR(m_blk_ptr) \
+ (m_blk_ptr)->ix_ctrl.ix_osbuf_ptr
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(m_blk_ptr)
+ *
+ * @brief Return the allocated buffer size
+ */
+#define IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(m_blk_ptr) \
+ (m_blk_ptr)->ix_ctrl.ix_allocated_len
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(m_blk_ptr)
+ *
+ * @brief Return the allocated buffer pointer
+ */
+#define IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(m_blk_ptr) \
+ (m_blk_ptr)->ix_ctrl.ix_allocated_data
+
+
+
+/* Name length */
+#define IX_OSAL_MBUF_POOL_NAME_LEN 64
+
+
+/****************************************************
+ * Macros for buffer pool management
+ ****************************************************/
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_FREE_COUNT(m_pool_ptr
+ *
+ * @brief Return the total number of freed buffers left in the pool.
+ */
+#define IX_OSAL_MBUF_POOL_FREE_COUNT(m_pool_ptr) \
+ ixOsalBuffPoolFreeCountGet(m_pool_ptr)
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_SIZE_ALIGN
+ *
+ * @brief This macro takes an integer as an argument and
+ * rounds it up to be a multiple of the memory cache-line
+ * size.
+ *
+ * @param int [in] size - the size integer to be rounded up
+ *
+ * @return int - the size, rounded up to a multiple of
+ * the cache-line size
+ */
+#define IX_OSAL_MBUF_POOL_SIZE_ALIGN(size) \
+ ((((size) + (IX_OSAL_CACHE_LINE_SIZE - 1)) / \
+ IX_OSAL_CACHE_LINE_SIZE) * \
+ IX_OSAL_CACHE_LINE_SIZE)
+
+/* Don't use this directly, use macro */
+PUBLIC UINT32 ixOsalBuffPoolMbufAreaSizeGet (int count);
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_MBUF_AREA_SIZE_ALIGNED
+ *
+ * @brief This macro calculates, from the number of mbufs required, the
+ * size of the memory area required to contain the mbuf headers for the
+ * buffers in the pool. The size to be used for each mbuf header is
+ * rounded up to a multiple of the cache-line size, to ensure
+ * each mbuf header aligns on a cache-line boundary.
+ * This macro is used by IX_OSAL_MBUF_POOL_MBUF_AREA_ALLOC()
+ *
+ * @param int [in] count - the number of buffers the pool will contain
+ *
+ * @return int - the total size required for the pool mbuf area (aligned)
+ */
+#define IX_OSAL_MBUF_POOL_MBUF_AREA_SIZE_ALIGNED(count) \
+ ixOsalBuffPoolMbufAreaSizeGet(count)
+
+
+/* Don't use this directly, use macro */
+PUBLIC UINT32 ixOsalBuffPoolDataAreaSizeGet (int count, int size);
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_DATA_AREA_SIZE_ALIGNED
+ *
+ * @brief This macro calculates, from the number of mbufs required and the
+ * size of the data portion for each mbuf, the size of the data memory area
+ * required. The size is adjusted to ensure alignment on cache line boundaries.
+ * This macro is used by IX_OSAL_MBUF_POOL_DATA_AREA_ALLOC()
+ *
+ *
+ * @param int [in] count - The number of mbufs in the pool.
+ * @param int [in] size - The desired size for each mbuf data portion.
+ * This size will be rounded up to a multiple of the
+ * cache-line size to ensure alignment on cache-line
+ * boundaries for each data block.
+ *
+ * @return int - the total size required for the pool data area (aligned)
+ */
+#define IX_OSAL_MBUF_POOL_DATA_AREA_SIZE_ALIGNED(count, size) \
+ ixOsalBuffPoolDataAreaSizeGet((count), (size))
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_MBUF_AREA_ALLOC
+ *
+ * @brief Allocates the memory area needed for the number of mbuf headers
+ * specified by <i>count</i>.
+ * This macro ensures the mbuf headers align on cache line boundaries.
+ * This macro evaluates to a pointer to the memory allocated.
+ *
+ * @param int [in] count - the number of mbufs the pool will contain
+ * @param int [out] memAreaSize - the total amount of memory allocated
+ *
+ * @return void * - a pointer to the allocated memory area
+ */
+#define IX_OSAL_MBUF_POOL_MBUF_AREA_ALLOC(count, memAreaSize) \
+ IX_OSAL_CACHE_DMA_MALLOC((memAreaSize = \
+ IX_OSAL_MBUF_POOL_MBUF_AREA_SIZE_ALIGNED(count)))
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_DATA_AREA_ALLOC
+ *
+ * @brief Allocates the memory pool for the data portion of the pool mbufs.
+ * The number of mbufs is specified by <i>count</i>. The size of the data
+ * portion of each mbuf is specified by <i>size</i>.
+ * This macro ensures the mbufs are aligned on cache line boundaries
+ * This macro evaluates to a pointer to the memory allocated.
+ *
+ * @param int [in] count - the number of mbufs the pool will contain
+ * @param int [in] size - the desired size (in bytes) required for the data
+ * portion of each mbuf. Note that this size may be
+ * rounded up to ensure alignment on cache-line
+ * boundaries.
+ * @param int [out] memAreaSize - the total amount of memory allocated
+ *
+ * @return void * - a pointer to the allocated memory area
+ */
+#define IX_OSAL_MBUF_POOL_DATA_AREA_ALLOC(count, size, memAreaSize) \
+ IX_OSAL_CACHE_DMA_MALLOC((memAreaSize = \
+ IX_OSAL_MBUF_POOL_DATA_AREA_SIZE_ALIGNED(count,size)))
+
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_INIT
+ *
+ * @brief Wrapper macro for ixOsalPoolInit()
+ * See function description below for details.
+ */
+#define IX_OSAL_MBUF_POOL_INIT(count, size, name) \
+ ixOsalPoolInit((count), (size), (name))
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_NO_ALLOC_POOL_INIT
+ *
+ * @return Pointer to the new pool or NULL if the initialization failed.
+ *
+ * @brief Wrapper macro for ixOsalNoAllocPoolInit()
+ * See function description below for details.
+ *
+ */
+#define IX_OSAL_MBUF_NO_ALLOC_POOL_INIT(bufPtr, dataPtr, count, size, name) \
+ ixOsalNoAllocPoolInit( (bufPtr), (dataPtr), (count), (size), (name))
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_GET
+ *
+ * @brief Wrapper macro for ixOsalMbufAlloc()
+ * See function description below for details.
+ */
+#define IX_OSAL_MBUF_POOL_GET(poolPtr) \
+ ixOsalMbufAlloc(poolPtr)
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_PUT
+ *
+ * @brief Wrapper macro for ixOsalMbufFree()
+ * See function description below for details.
+ */
+#define IX_OSAL_MBUF_POOL_PUT(bufPtr) \
+ ixOsalMbufFree(bufPtr)
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_PUT_CHAIN
+ *
+ * @brief Wrapper macro for ixOsalMbufChainFree()
+ * See function description below for details.
+ */
+#define IX_OSAL_MBUF_POOL_PUT_CHAIN(bufPtr) \
+ ixOsalMbufChainFree(bufPtr)
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_SHOW
+ *
+ * @brief Wrapper macro for ixOsalMbufPoolShow()
+ * See function description below for details.
+ */
+#define IX_OSAL_MBUF_POOL_SHOW(poolPtr) \
+ ixOsalMbufPoolShow(poolPtr)
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_MDATA_RESET
+ *
+ * @brief Wrapper macro for ixOsalMbufDataPtrReset()
+ * See function description below for details.
+ */
+#define IX_OSAL_MBUF_POOL_MDATA_RESET(bufPtr) \
+ ixOsalMbufDataPtrReset(bufPtr)
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_UNINIT
+ *
+ * @brief Wrapper macro for ixOsalBuffPoolUninit()
+ * See function description below for details.
+ */
+#define IX_OSAL_MBUF_POOL_UNINIT(m_pool_ptr) \
+ ixOsalBuffPoolUninit(m_pool_ptr)
+
+/*
+ * Include OS-specific bufferMgt definitions
+ */
+#include "IxOsalOsBufferMgt.h"
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_CONVERT_OSBUF_TO_IXPBUF( osBufPtr, ixpBufPtr)
+ *
+ * @brief Convert pre-allocated os-specific buffer format to OSAL IXP_BUF (IX_OSAL_MBUF) format.
+ * It is users' responsibility to provide pre-allocated and valid buffer pointers.
+ * @param osBufPtr (in) - a pre-allocated os-specific buffer pointer.
+ * @param ixpBufPtr (in)- a pre-allocated OSAL IXP_BUF pointer
+ * @return None
+ */
+#define IX_OSAL_CONVERT_OSBUF_TO_IXPBUF( osBufPtr, ixpBufPtr) \
+ IX_OSAL_OS_CONVERT_OSBUF_TO_IXPBUF( osBufPtr, ixpBufPtr)
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_CONVERT_IXPBUF_TO_OSBUF( ixpBufPtr, osBufPtr)
+ *
+ * @brief Convert pre-allocated OSAL IXP_BUF (IX_OSAL_MBUF) format to os-specific buffer pointers.
+ * @param ixpBufPtr (in) - OSAL IXP_BUF pointer
+ * @param osBufPtr (out) - os-specific buffer pointer.
+ * @return None
+ */
+
+#define IX_OSAL_CONVERT_IXPBUF_TO_OSBUF( ixpBufPtr, osBufPtr) \
+ IX_OSAL_OS_CONVERT_IXPBUF_TO_OSBUF( ixpBufPtr, osBufPtr)
+
+
+PUBLIC IX_OSAL_MBUF_POOL *ixOsalPoolInit (UINT32 count,
+ UINT32 size, const char *name);
+
+PUBLIC IX_OSAL_MBUF_POOL *ixOsalNoAllocPoolInit (void *poolBufPtr,
+ void *poolDataPtr,
+ UINT32 count,
+ UINT32 size,
+ const char *name);
+
+PUBLIC IX_OSAL_MBUF *ixOsalMbufAlloc (IX_OSAL_MBUF_POOL * pool);
+
+PUBLIC IX_OSAL_MBUF *ixOsalMbufFree (IX_OSAL_MBUF * mbuf);
+
+PUBLIC void ixOsalMbufChainFree (IX_OSAL_MBUF * mbuf);
+
+PUBLIC void ixOsalMbufDataPtrReset (IX_OSAL_MBUF * mbuf);
+
+PUBLIC void ixOsalMbufPoolShow (IX_OSAL_MBUF_POOL * pool);
+
+PUBLIC IX_STATUS ixOsalBuffPoolUninit (IX_OSAL_MBUF_POOL * pool);
+
+PUBLIC UINT32 ixOsalBuffPoolFreeCountGet(IX_OSAL_MBUF_POOL * pool);
+
+
+/**
+ * @} IxOsalBufferMgt
+ */
+
+
+#endif /* IxOsalBufferMgt_H */
diff --git a/cpu/ixp/npe/include/IxOsalBufferMgtDefault.h b/cpu/ixp/npe/include/IxOsalBufferMgtDefault.h
new file mode 100644
index 0000000..684b52e
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalBufferMgtDefault.h
@@ -0,0 +1,88 @@
+/**
+ * @file IxOsalBufferMgtDefault.h
+ *
+ * @brief Default buffer pool management and buffer management
+ * definitions.
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IX_OSAL_BUFFER_MGT_DEFAULT_H
+#define IX_OSAL_BUFFER_MGT_DEFAULT_H
+
+/**
+ * @enum IxMbufPoolAllocationType
+ * @brief Used to indicate how the pool memory was allocated
+ */
+
+typedef enum
+{
+ IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC = 0, /**< mbuf pool allocated by the system */
+ IX_OSAL_MBUF_POOL_TYPE_USER_ALLOC /**< mbuf pool allocated by the user */
+} IxOsalMbufPoolAllocationType;
+
+
+/**
+ * @brief Implementation of buffer pool structure for use with non-VxWorks OS
+ */
+
+typedef struct
+{
+ IX_OSAL_MBUF *nextFreeBuf; /**< Pointer to the next free mbuf */
+ void *mbufMemPtr; /**< Pointer to the mbuf memory area */
+ void *dataMemPtr; /**< Pointer to the data memory area */
+ int bufDataSize; /**< The size of the data portion of each mbuf */
+ int totalBufsInPool; /**< Total number of mbufs in the pool */
+ int freeBufsInPool; /**< Number of free mbufs currently in the pool */
+ int mbufMemSize; /**< The size of the pool mbuf memory area */
+ int dataMemSize; /**< The size of the pool data memory area */
+ char name[IX_OSAL_MBUF_POOL_NAME_LEN + 1]; /**< Descriptive name for pool */
+ IxOsalMbufPoolAllocationType poolAllocType;
+ unsigned int poolIdx; /**< Pool Index */
+} IxOsalMbufPool;
+
+typedef IxOsalMbufPool IX_OSAL_MBUF_POOL;
+
+
+PUBLIC IX_STATUS ixOsalBuffPoolUninit (IX_OSAL_MBUF_POOL * pool);
+
+
+#endif /* IX_OSAL_BUFFER_MGT_DEFAULT_H */
diff --git a/cpu/ixp/npe/include/IxOsalConfig.h b/cpu/ixp/npe/include/IxOsalConfig.h
new file mode 100644
index 0000000..d56e796
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalConfig.h
@@ -0,0 +1,76 @@
+/**
+ * @file IxOsalConfig.h
+ *
+ * @brief OSAL Configuration header file
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/*
+ * This file contains user-editable fields for modules inclusion.
+ */
+#ifndef IxOsalConfig_H
+#define IxOsalConfig_H
+
+
+/*
+ * Note: in the future these config options may
+ * become build time decision.
+ */
+
+/* Choose cache */
+#define IX_OSAL_CACHED
+/* #define IX_OSAL_UNCACHED */
+
+
+/*
+ * Select the module headers to include
+ */
+#include "IxOsalIoMem.h" /* I/O Memory Management module API */
+#include "IxOsalBufferMgt.h" /* Buffer Management module API */
+
+/*
+ * Select main platform header file to use
+ */
+#include "IxOsalOem.h"
+
+
+
+#endif /* IxOsalConfig_H */
diff --git a/cpu/ixp/npe/include/IxOsalEndianess.h b/cpu/ixp/npe/include/IxOsalEndianess.h
new file mode 100644
index 0000000..3b1c739
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalEndianess.h
@@ -0,0 +1,134 @@
+/**
+ * @file IxOsalEndianess.h (Obsolete file)
+ *
+ * @brief Header file for determining system endianess and OS
+ *
+ * @par
+ * @version $Revision: 1.1
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#ifndef IxOsalEndianess_H
+#define IxOsalEndianess_H
+
+#if defined (__vxworks) || defined (__linux)
+
+/* get ntohl/ntohs/htohl/htons macros and CPU definitions for VxWorks */
+/* #include <netinet/in.h> */
+
+#elif defined (__wince)
+
+/* get ntohl/ntohs/htohl/htons macros definitions for WinCE */
+#include <Winsock2.h>
+
+#else
+
+#error Unknown OS, please add a section with the include file for htonl/htons/ntohl/ntohs
+
+#endif /* vxworks or linux or wince */
+
+/* Compiler specific endianness selector - WARNING this works only with arm gcc, use appropriate defines with diab */
+
+#ifndef __wince
+
+#if defined (__ARMEL__)
+
+#ifndef __LITTLE_ENDIAN
+
+#define __LITTLE_ENDIAN
+
+#endif /* _LITTLE_ENDIAN */
+
+#elif defined (__ARMEB__) || CPU == SIMSPARCSOLARIS
+
+#ifndef __BIG_ENDIAN
+
+#define __BIG_ENDIAN
+
+#endif /* __BIG_ENDIAN */
+
+#else
+
+#error Error, could not identify target endianness
+
+#endif /* endianness selector no WinCE OSes */
+
+#else /* ndef __wince */
+
+#define __LITTLE_ENDIAN
+
+#endif /* def __wince */
+
+
+/* OS mode selector */
+#if defined (__vxworks) && defined (__LITTLE_ENDIAN)
+
+#define IX_OSAL_VXWORKS_LE
+
+#elif defined (__vxworks) && defined (__BIG_ENDIAN)
+
+#define IX_OSAL_VXWORKS_BE
+
+#elif defined (__linux) && defined (__BIG_ENDIAN)
+
+#define IX_OSAL_LINUX_BE
+
+#elif defined (__linux) && defined (__LITTLE_ENDIAN)
+
+#define IX_OSAL_LINUX_LE
+
+#elif defined (BOOTLOADER_BLD) && defined (__LITTLE_ENDIAN)
+
+#define IX_OSAL_EBOOT_LE
+
+#elif defined (__wince) && defined (__LITTLE_ENDIAN)
+
+#define IX_OSAL_WINCE_LE
+
+#else
+
+#error Unknown OS/Endianess combination - only vxWorks BE LE, Linux BE LE, WinCE BE LE are supported
+
+#endif /* mode selector */
+
+
+
+#endif /* IxOsalEndianess_H */
diff --git a/cpu/ixp/npe/include/IxOsalIoMem.h b/cpu/ixp/npe/include/IxOsalIoMem.h
new file mode 100644
index 0000000..ac0ce65
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalIoMem.h
@@ -0,0 +1,322 @@
+/*
+ * @file IxOsalIoMem.h
+ * @author Intel Corporation
+ * @date 25-08-2004
+ *
+ * @brief description goes here
+ */
+
+/**
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsalIoMem_H
+#define IxOsalIoMem_H
+
+
+/*
+ * Decide OS and Endianess, such as IX_OSAL_VXWORKS_LE.
+ */
+#include "IxOsalEndianess.h"
+
+/**
+ * @defgroup IxOsalIoMem Osal IoMem module
+ *
+ * @brief I/O memory and endianess support.
+ *
+ * @{
+ */
+
+/* Low-level conversion macros - DO NOT USE UNLESS ABSOLUTELY NEEDED */
+#ifndef __wince
+
+
+/*
+ * Private function to swap word
+ */
+#ifdef __XSCALE__
+static __inline__ UINT32
+ixOsalCoreWordSwap (UINT32 wordIn)
+{
+ /*
+ * Storage for the swapped word
+ */
+ UINT32 wordOut;
+
+ /*
+ * wordIn = A, B, C, D
+ */
+ __asm__ (" eor r1, %1, %1, ror #16;" /* R1 = A^C, B^D, C^A, D^B */
+ " bic r1, r1, #0x00ff0000;" /* R1 = A^C, 0 , C^A, D^B */
+ " mov %0, %1, ror #8;" /* wordOut = D, A, B, C */
+ " eor %0, %0, r1, lsr #8;" /* wordOut = D, C, B, A */
+ : "=r" (wordOut): "r" (wordIn):"r1");
+
+ return wordOut;
+}
+
+#define IX_OSAL_SWAP_LONG(wData) (ixOsalCoreWordSwap(wData))
+#else
+#define IX_OSAL_SWAP_LONG(wData) ((wData >> 24) | (((wData >> 16) & 0xFF) << 8) | (((wData >> 8) & 0xFF) << 16) | ((wData & 0xFF) << 24))
+#endif
+
+#else /* ndef __wince */
+#define IX_OSAL_SWAP_LONG(wData) ((((UINT32)wData << 24) | ((UINT32)wData >> 24)) | (((wData << 8) & 0xff0000) | ((wData >> 8) & 0xff00)))
+#endif /* ndef __wince */
+
+#define IX_OSAL_SWAP_SHORT(sData) ((sData >> 8) | ((sData & 0xFF) << 8))
+#define IX_OSAL_SWAP_SHORT_ADDRESS(sAddr) ((sAddr) ^ 0x2)
+#define IX_OSAL_SWAP_BYTE_ADDRESS(bAddr) ((bAddr) ^ 0x3)
+
+#define IX_OSAL_BE_XSTOBUSL(wData) (wData)
+#define IX_OSAL_BE_XSTOBUSS(sData) (sData)
+#define IX_OSAL_BE_XSTOBUSB(bData) (bData)
+#define IX_OSAL_BE_BUSTOXSL(wData) (wData)
+#define IX_OSAL_BE_BUSTOXSS(sData) (sData)
+#define IX_OSAL_BE_BUSTOXSB(bData) (bData)
+
+#define IX_OSAL_LE_AC_XSTOBUSL(wAddr) (wAddr)
+#define IX_OSAL_LE_AC_XSTOBUSS(sAddr) IX_OSAL_SWAP_SHORT_ADDRESS(sAddr)
+#define IX_OSAL_LE_AC_XSTOBUSB(bAddr) IX_OSAL_SWAP_BYTE_ADDRESS(bAddr)
+#define IX_OSAL_LE_AC_BUSTOXSL(wAddr) (wAddr)
+#define IX_OSAL_LE_AC_BUSTOXSS(sAddr) IX_OSAL_SWAP_SHORT_ADDRESS(sAddr)
+#define IX_OSAL_LE_AC_BUSTOXSB(bAddr) IX_OSAL_SWAP_BYTE_ADDRESS(bAddr)
+
+#define IX_OSAL_LE_DC_XSTOBUSL(wData) IX_OSAL_SWAP_LONG(wData)
+#define IX_OSAL_LE_DC_XSTOBUSS(sData) IX_OSAL_SWAP_SHORT(sData)
+#define IX_OSAL_LE_DC_XSTOBUSB(bData) (bData)
+#define IX_OSAL_LE_DC_BUSTOXSL(wData) IX_OSAL_SWAP_LONG(wData)
+#define IX_OSAL_LE_DC_BUSTOXSS(sData) IX_OSAL_SWAP_SHORT(sData)
+#define IX_OSAL_LE_DC_BUSTOXSB(bData) (bData)
+
+
+/*
+ * Decide SDRAM mapping, then implement read/write
+ */
+#include "IxOsalMemAccess.h"
+
+
+/**
+ * @ingroup IxOsalIoMem
+ * @enum IxOsalMapEntryType
+ * @brief This is an emum for OSAL I/O mem map type.
+ */
+typedef enum
+{
+ IX_OSAL_STATIC_MAP = 0, /**<Set map entry type to static map */
+ IX_OSAL_DYNAMIC_MAP /**<Set map entry type to dynamic map */
+} IxOsalMapEntryType;
+
+
+/**
+ * @ingroup IxOsalIoMem
+ * @enum IxOsalMapEndianessType
+ * @brief This is an emum for OSAL I/O mem Endianess and Coherency mode.
+ */
+typedef enum
+{
+ IX_OSAL_BE = 0x1, /**<Set map endian mode to Big Endian */
+ IX_OSAL_LE_AC = 0x2, /**<Set map endian mode to Little Endian, Address Coherent */
+ IX_OSAL_LE_DC = 0x4, /**<Set map endian mode to Little Endian, Data Coherent */
+ IX_OSAL_LE = 0x8 /**<Set map endian mode to Little Endian without specifying coherency mode */
+} IxOsalMapEndianessType;
+
+
+/**
+ * @struct IxOsalMemoryMap
+ * @brief IxOsalMemoryMap structure
+ */
+typedef struct _IxOsalMemoryMap
+{
+ IxOsalMapEntryType type; /**< map type - IX_OSAL_STATIC_MAP or IX_OSAL_DYNAMIC_MAP */
+
+ UINT32 physicalAddress; /**< physical address of the memory mapped I/O zone */
+
+ UINT32 size; /**< size of the map */
+
+ UINT32 virtualAddress; /**< virtual address of the zone; must be predefined
+ in the global memory map for static maps and has
+ to be NULL for dynamic maps (populated on allocation)
+ */
+ /*
+ * pointer to a map function called to map a dynamic map;
+ * will populate the virtualAddress field
+ */
+ void (*mapFunction) (struct _IxOsalMemoryMap * map); /**< pointer to a map function called to map a dynamic map */
+
+ /*
+ * pointer to a map function called to unmap a dynamic map;
+ * will reset the virtualAddress field to NULL
+ */
+ void (*unmapFunction) (struct _IxOsalMemoryMap * map); /**< pointer to a map function called to unmap a dynamic map */
+
+ /*
+ * reference count describing how many components share this map;
+ * actual allocation/deallocation for dynamic maps is done only
+ * between 0 <=> 1 transitions of the counter
+ */
+ UINT32 refCount; /**< reference count describing how many components share this map */
+
+ /*
+ * memory endian type for the map; can be a combination of IX_OSAL_BE (Big
+ * Endian) and IX_OSAL_LE or IX_OSAL_LE_AC or IX_OSAL_LE_DC
+ * (Little Endian, Address Coherent or Data Coherent). Any combination is
+ * allowed provided it contains at most one LE flag - e.g.
+ * (IX_OSAL_BE), (IX_OSAL_LE_AC), (IX_OSAL_BE | IX_OSAL_LE_DC) are valid
+ * combinations while (IX_OSAL_BE | IX_OSAL_LE_DC | IX_OSAL_LE_AC) is not.
+ */
+ IxOsalMapEndianessType mapEndianType; /**< memory endian type for the map */
+
+ char *name; /**< user-friendly name */
+} IxOsalMemoryMap;
+
+
+
+
+/* Internal function to map a memory zone
+ * NOTE - This should not be called by the user.
+ * Use the macro IX_OSAL_MEM_MAP instead
+ */
+PUBLIC void *ixOsalIoMemMap (UINT32 requestedAddress,
+ UINT32 size,
+ IxOsalMapEndianessType requestedCoherency);
+
+
+/* Internal function to unmap a memory zone mapped with ixOsalIoMemMap
+ * NOTE - This should not be called by the user.
+ * Use the macro IX_OSAL_MEM_UNMAP instead
+ */
+PUBLIC void ixOsalIoMemUnmap (UINT32 requestedAddress, UINT32 coherency);
+
+
+/* Internal function to convert virtual address to physical address
+ * NOTE - This should not be called by the user.
+ * Use the macro IX_OSAL_MMAP_VIRT_TO_PHYS */
+PUBLIC UINT32 ixOsalIoMemVirtToPhys (UINT32 virtualAddress, UINT32 coherency);
+
+
+/* Internal function to convert physical address to virtual address
+ * NOTE - This should not be called by the user.
+ * Use the macro IX_OSAL_MMAP_PHYS_TO_VIRT */
+PUBLIC UINT32
+ixOsalIoMemPhysToVirt (UINT32 physicalAddress, UINT32 coherency);
+
+/**
+ * @ingroup IxOsalIoMem
+ *
+ * @def IX_OSAL_MEM_MAP(physAddr, size)
+ *
+ * @brief Map an I/O mapped physical memory zone to virtual zone and return virtual
+ * pointer.
+ * @param physAddr - the physical address
+ * @param size - the size
+ * @return start address of the virtual memory zone.
+ *
+ * @note This function maps an I/O mapped physical memory zone of the given size
+ * into a virtual memory zone accessible by the caller and returns a cookie -
+ * the start address of the virtual memory zone.
+ * IX_OSAL_MMAP_PHYS_TO_VIRT should NOT therefore be used on the returned
+ * virtual address.
+ * The memory zone is to be unmapped using IX_OSAL_MEM_UNMAP once the caller has
+ * finished using this zone (e.g. on driver unload) using the cookie as
+ * parameter.
+ * The IX_OSAL_READ/WRITE_LONG/SHORT macros should be used to read and write
+ * the mapped memory, adding the necessary offsets to the address cookie.
+ */
+#define IX_OSAL_MEM_MAP(physAddr, size) \
+ ixOsalIoMemMap((physAddr), (size), IX_OSAL_COMPONENT_MAPPING)
+
+
+/**
+ * @ingroup IxOsalIoMem
+ *
+ * @def IX_OSAL_MEM_UNMAP(virtAddr)
+ *
+ * @brief Unmap a previously mapped I/O memory zone using virtual pointer obtained
+ * during the mapping operation.
+ * pointer.
+ * @param virtAddr - the virtual pointer to the zone to be unmapped.
+ * @return none
+ *
+ * @note This function unmaps a previously mapped I/O memory zone using
+ * the cookie obtained in the mapping operation. The memory zone in question
+ * becomes unavailable to the caller once unmapped and the cookie should be
+ * discarded.
+ *
+ * This function cannot fail if the given parameter is correct and does not
+ * return a value.
+ */
+#define IX_OSAL_MEM_UNMAP(virtAddr) \
+ ixOsalIoMemUnmap ((virtAddr), IX_OSAL_COMPONENT_MAPPING)
+
+/**
+ * @ingroup IxOsalIoMem
+ *
+ * @def IX_OSAL_MMAP_VIRT_TO_PHYS(virtAddr)
+ *
+ * @brief This function Converts a virtual address into a physical
+ * address, including the dynamically mapped memory.
+ *
+ * @param virtAddr - virtual address to convert
+ * Return value: corresponding physical address, or NULL
+ */
+#define IX_OSAL_MMAP_VIRT_TO_PHYS(virtAddr) \
+ ixOsalIoMemVirtToPhys(virtAddr, IX_OSAL_COMPONENT_MAPPING)
+
+
+/**
+ * @ingroup IxOsalIoMem
+ *
+ * @def IX_OSAL_MMAP_PHYS_TO_VIRT(physAddr)
+ *
+ * @brief This function Converts a virtual address into a physical
+ * address, including the dynamically mapped memory.
+ *
+ * @param physAddr - physical address to convert
+ * Return value: corresponding virtual address, or NULL
+ *
+ */
+#define IX_OSAL_MMAP_PHYS_TO_VIRT(physAddr) \
+ ixOsalIoMemPhysToVirt(physAddr, IX_OSAL_COMPONENT_MAPPING)
+
+/**
+ * @} IxOsalIoMem
+ */
+
+#endif /* IxOsalIoMem_H */
diff --git a/cpu/ixp/npe/include/IxOsalMemAccess.h b/cpu/ixp/npe/include/IxOsalMemAccess.h
new file mode 100644
index 0000000..2ad0ccf
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalMemAccess.h
@@ -0,0 +1,494 @@
+/**
+ * @file IxOsalMemAccess.h
+ *
+ * @brief Header file for memory access
+ *
+ * @par
+ * @version $Revision: 1.0 $
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsalMemAccess_H
+#define IxOsalMemAccess_H
+
+
+/* Global BE switch
+ *
+ * Should be set only in BE mode and only if the component uses I/O memory.
+ */
+
+#if defined (__BIG_ENDIAN)
+
+#define IX_OSAL_BE_MAPPING
+
+#endif /* Global switch */
+
+
+/* By default only static memory maps in use;
+ define IX_OSAL_DYNAMIC_MEMORY_MAP per component if dynamic maps are
+ used instead in that component */
+#define IX_OSAL_STATIC_MEMORY_MAP
+
+
+/*
+ * SDRAM coherency mode
+ * Must be defined to BE, LE_DATA_COHERENT or LE_ADDRESS_COHERENT.
+ * The mode changes depending on OS
+ */
+#if defined (IX_OSAL_LINUX_BE) || defined (IX_OSAL_VXWORKS_BE)
+
+#define IX_SDRAM_BE
+
+#elif defined (IX_OSAL_VXWORKS_LE)
+
+#define IX_SDRAM_LE_DATA_COHERENT
+
+#elif defined (IX_OSAL_LINUX_LE)
+
+#define IX_SDRAM_LE_DATA_COHERENT
+
+#elif defined (IX_OSAL_WINCE_LE)
+
+#define IX_SDRAM_LE_DATA_COHERENT
+
+#elif defined (IX_OSAL_EBOOT_LE)
+
+#define IX_SDRAM_LE_ADDRESS_COHERENT
+
+#endif
+
+
+
+
+/**************************************
+ * Retrieve current component mapping *
+ **************************************/
+
+/*
+ * Only use customized mapping for LE.
+ *
+ */
+#if defined (IX_OSAL_VXWORKS_LE) || defined (IX_OSAL_LINUX_LE) || defined (IX_OSAL_WINCE_LE) || defined (IX_OSAL_EBOOT_LE)
+
+#include "IxOsalOsIxp400CustomizedMapping.h"
+
+#endif
+
+
+/*******************************************************************
+ * Turn off IX_STATIC_MEMORY map for components using dynamic maps *
+ *******************************************************************/
+#ifdef IX_OSAL_DYNAMIC_MEMORY_MAP
+
+#undef IX_OSAL_STATIC_MEMORY_MAP
+
+#endif
+
+
+/************************************************************
+ * Turn off BE access for components using LE or no mapping *
+ ************************************************************/
+
+#if ( defined (IX_OSAL_LE_AC_MAPPING) || defined (IX_OSAL_LE_DC_MAPPING) || defined (IX_OSAL_NO_MAPPING) )
+
+#undef IX_OSAL_BE_MAPPING
+
+#endif
+
+
+/*****************
+ * Safety checks *
+ *****************/
+
+/* Default to no_mapping */
+#if !defined (IX_OSAL_BE_MAPPING) && !defined (IX_OSAL_LE_AC_MAPPING) && !defined (IX_OSAL_LE_DC_MAPPING) && !defined (IX_OSAL_NO_MAPPING)
+
+#define IX_OSAL_NO_MAPPING
+
+#endif /* check at least one mapping */
+
+/* No more than one mapping can be defined for a component */
+#if (defined (IX_OSAL_BE_MAPPING) && defined (IX_OSAL_LE_AC_MAPPING)) \
+ ||(defined (IX_OSAL_BE_MAPPING) && defined (IX_OSAL_LE_DC_MAPPING)) \
+ ||(defined (IX_OSAL_BE_MAPPING) && defined (IX_OSAL_NO_MAPPING)) \
+ ||(defined (IX_OSAL_LE_DC_MAPPING) && defined (IX_OSAL_NO_MAPPING)) \
+ ||(defined (IX_OSAL_LE_DC_MAPPING) && defined (IX_OSAL_LE_AC_MAPPING)) \
+ ||(defined (IX_OSAL_LE_AC_MAPPING) && defined (IX_OSAL_NO_MAPPING))
+
+
+#ifdef IX_OSAL_BE_MAPPING
+#warning IX_OSAL_BE_MAPPING is defined
+#endif
+
+#ifdef IX_OSAL_LE_AC_MAPPING
+#warning IX_OSAL_LE_AC_MAPPING is defined
+#endif
+
+#ifdef IX_OSAL_LE_DC_MAPPING
+#warning IX_OSAL_LE_DC_MAPPING is defined
+#endif
+
+#ifdef IX_OSAL_NO_MAPPING
+#warning IX_OSAL_NO_MAPPING is defined
+#endif
+
+#error More than one I/O mapping is defined, please check your component mapping
+
+#endif /* check at most one mapping */
+
+
+/* Now set IX_OSAL_COMPONENT_MAPPING */
+
+#ifdef IX_OSAL_BE_MAPPING
+#define IX_OSAL_COMPONENT_MAPPING IX_OSAL_BE
+#endif
+
+#ifdef IX_OSAL_LE_AC_MAPPING
+#define IX_OSAL_COMPONENT_MAPPING IX_OSAL_LE_AC
+#endif
+
+#ifdef IX_OSAL_LE_DC_MAPPING
+#define IX_OSAL_COMPONENT_MAPPING IX_OSAL_LE_DC
+#endif
+
+#ifdef IX_OSAL_NO_MAPPING
+#define IX_OSAL_COMPONENT_MAPPING IX_OSAL_LE
+#endif
+
+
+/* SDRAM coherency should be defined */
+#if !defined (IX_SDRAM_BE) && !defined (IX_SDRAM_LE_DATA_COHERENT) && !defined (IX_SDRAM_LE_ADDRESS_COHERENT)
+
+#error SDRAM coherency must be defined
+
+#endif /* SDRAM coherency must be defined */
+
+/* SDRAM coherency cannot be defined in several ways */
+#if (defined (IX_SDRAM_BE) && (defined (IX_SDRAM_LE_DATA_COHERENT) || defined (IX_SDRAM_LE_ADDRESS_COHERENT))) \
+ || (defined (IX_SDRAM_LE_DATA_COHERENT) && (defined (IX_SDRAM_BE) || defined (IX_SDRAM_LE_ADDRESS_COHERENT))) \
+ || (defined (IX_SDRAM_LE_ADDRESS_COHERENT) && (defined (IX_SDRAM_BE) || defined (IX_SDRAM_LE_DATA_COHERENT)))
+
+#error SDRAM coherency cannot be defined in more than one way
+
+#endif /* SDRAM coherency must be defined exactly once */
+
+
+/*********************
+ * Read/write macros *
+ *********************/
+
+/* WARNING - except for addition of special cookie read/write macros (see below)
+ these macros are NOT user serviceable. Please do not modify */
+
+#define IX_OSAL_READ_LONG_RAW(wAddr) (*(wAddr))
+#define IX_OSAL_READ_SHORT_RAW(sAddr) (*(sAddr))
+#define IX_OSAL_READ_BYTE_RAW(bAddr) (*(bAddr))
+#define IX_OSAL_WRITE_LONG_RAW(wAddr, wData) (*(wAddr) = (wData))
+#define IX_OSAL_WRITE_SHORT_RAW(sAddr,sData) (*(sAddr) = (sData))
+#define IX_OSAL_WRITE_BYTE_RAW(bAddr, bData) (*(bAddr) = (bData))
+
+#ifdef __linux
+
+/* Linux - specific cookie reads/writes.
+ Redefine per OS if dynamic memory maps are used
+ and I/O memory is accessed via functions instead of raw pointer access. */
+
+#define IX_OSAL_READ_LONG_COOKIE(wCookie) (readl((UINT32) (wCookie) ))
+#define IX_OSAL_READ_SHORT_COOKIE(sCookie) (readw((UINT32) (sCookie) ))
+#define IX_OSAL_READ_BYTE_COOKIE(bCookie) (readb((UINT32) (bCookie) ))
+#define IX_OSAL_WRITE_LONG_COOKIE(wCookie, wData) (writel(wData, (UINT32) (wCookie) ))
+#define IX_OSAL_WRITE_SHORT_COOKIE(sCookie, sData) (writew(sData, (UINT32) (sCookie) ))
+#define IX_OSAL_WRITE_BYTE_COOKIE(bCookie, bData) (writeb(bData, (UINT32) (bCookie) ))
+
+#endif /* linux */
+
+#ifdef __wince
+
+/* WinCE - specific cookie reads/writes. */
+
+static __inline__ UINT32
+ixOsalWinCEReadLCookie (volatile UINT32 * lCookie)
+{
+ return *lCookie;
+}
+
+static __inline__ UINT16
+ixOsalWinCEReadWCookie (volatile UINT16 * wCookie)
+{
+#if 0
+ UINT32 auxVal = *((volatile UINT32 *) wCookie);
+ if ((unsigned) wCookie & 3)
+ return (UINT16) (auxVal >> 16);
+ else
+ return (UINT16) (auxVal & 0xffff);
+#else
+ return *wCookie;
+#endif
+}
+
+static __inline__ UINT8
+ixOsalWinCEReadBCookie (volatile UINT8 * bCookie)
+{
+#if 0
+ UINT32 auxVal = *((volatile UINT32 *) bCookie);
+ return (UINT8) ((auxVal >> (3 - (((unsigned) bCookie & 3) << 3)) & 0xff));
+#else
+ return *bCookie;
+#endif
+}
+
+static __inline__ void
+ixOsalWinCEWriteLCookie (volatile UINT32 * lCookie, UINT32 lVal)
+{
+ *lCookie = lVal;
+}
+
+static __inline__ void
+ixOsalWinCEWriteWCookie (volatile UINT16 * wCookie, UINT16 wVal)
+{
+#if 0
+ volatile UINT32 *auxCookie =
+ (volatile UINT32 *) ((unsigned) wCookie & ~3);
+ if ((unsigned) wCookie & 3)
+ {
+ *auxCookie &= 0xffff;
+ *auxCookie |= (UINT32) wVal << 16;
+ }
+ else
+ {
+ *auxCookie &= ~0xffff;
+ *auxCookie |= (UINT32) wVal & 0xffff;
+ }
+#else
+ *wCookie = wVal;
+#endif
+}
+
+static __inline__ void
+ixOsalWinCEWriteBCookie (volatile UINT8 * bCookie, UINT8 bVal)
+{
+#if 0
+ volatile UINT32 *auxCookie =
+ (volatile UINT32 *) ((unsigned) bCookie & ~3);
+ *auxCookie &= 0xff << (3 - (((unsigned) bCookie & 3) << 3));
+ *auxCookie |= (UINT32) bVal << (3 - (((unsigned) bCookie & 3) << 3));
+#else
+ *bCookie = bVal;
+#endif
+}
+
+
+#define IX_OSAL_READ_LONG_COOKIE(wCookie) (ixOsalWinCEReadLCookie(wCookie))
+#define IX_OSAL_READ_SHORT_COOKIE(sCookie) (ixOsalWinCEReadWCookie(sCookie))
+#define IX_OSAL_READ_BYTE_COOKIE(bCookie) (ixOsalWinCEReadBCookie(bCookie))
+#define IX_OSAL_WRITE_LONG_COOKIE(wCookie, wData) (ixOsalWinCEWriteLCookie(wCookie, wData))
+#define IX_OSAL_WRITE_SHORT_COOKIE(sCookie, sData) (ixOsalWinCEWriteWCookie(sCookie, sData))
+#define IX_OSAL_WRITE_BYTE_COOKIE(bCookie, bData) (ixOsalWinCEWriteBCookie(bCookie, bData))
+
+#endif /* wince */
+
+#if defined (__vxworks) || (defined (__linux) && defined (IX_OSAL_STATIC_MEMORY_MAP)) || \
+ (defined (__wince) && defined (IX_OSAL_STATIC_MEMORY_MAP))
+
+#define IX_OSAL_READ_LONG_IO(wAddr) IX_OSAL_READ_LONG_RAW(wAddr)
+#define IX_OSAL_READ_SHORT_IO(sAddr) IX_OSAL_READ_SHORT_RAW(sAddr)
+#define IX_OSAL_READ_BYTE_IO(bAddr) IX_OSAL_READ_BYTE_RAW(bAddr)
+#define IX_OSAL_WRITE_LONG_IO(wAddr, wData) IX_OSAL_WRITE_LONG_RAW(wAddr, wData)
+#define IX_OSAL_WRITE_SHORT_IO(sAddr, sData) IX_OSAL_WRITE_SHORT_RAW(sAddr, sData)
+#define IX_OSAL_WRITE_BYTE_IO(bAddr, bData) IX_OSAL_WRITE_BYTE_RAW(bAddr, bData)
+
+#elif (defined (__linux) && !defined (IX_OSAL_STATIC_MEMORY_MAP)) || \
+ (defined (__wince) && !defined (IX_OSAL_STATIC_MEMORY_MAP))
+
+#ifndef __wince
+#include <asm/io.h>
+#endif /* ndef __wince */
+
+#define IX_OSAL_READ_LONG_IO(wAddr) IX_OSAL_READ_LONG_COOKIE(wAddr)
+#define IX_OSAL_READ_SHORT_IO(sAddr) IX_OSAL_READ_SHORT_COOKIE(sAddr)
+#define IX_OSAL_READ_BYTE_IO(bAddr) IX_OSAL_READ_BYTE_COOKIE(bAddr)
+#define IX_OSAL_WRITE_LONG_IO(wAddr, wData) IX_OSAL_WRITE_LONG_COOKIE(wAddr, wData)
+#define IX_OSAL_WRITE_SHORT_IO(sAddr, sData) IX_OSAL_WRITE_SHORT_COOKIE(sAddr, sData)
+#define IX_OSAL_WRITE_BYTE_IO(bAddr, bData) IX_OSAL_WRITE_BYTE_COOKIE(bAddr, bData)
+
+#endif
+
+/* Define BE macros */
+#define IX_OSAL_READ_LONG_BE(wAddr) IX_OSAL_BE_BUSTOXSL(IX_OSAL_READ_LONG_IO((volatile UINT32 *) (wAddr) ))
+#define IX_OSAL_READ_SHORT_BE(sAddr) IX_OSAL_BE_BUSTOXSS(IX_OSAL_READ_SHORT_IO((volatile UINT16 *) (sAddr) ))
+#define IX_OSAL_READ_BYTE_BE(bAddr) IX_OSAL_BE_BUSTOXSB(IX_OSAL_READ_BYTE_IO((volatile UINT8 *) (bAddr) ))
+#define IX_OSAL_WRITE_LONG_BE(wAddr, wData) IX_OSAL_WRITE_LONG_IO((volatile UINT32 *) (wAddr), IX_OSAL_BE_XSTOBUSL((UINT32) (wData) ))
+#define IX_OSAL_WRITE_SHORT_BE(sAddr, sData) IX_OSAL_WRITE_SHORT_IO((volatile UINT16 *) (sAddr), IX_OSAL_BE_XSTOBUSS((UINT16) (sData) ))
+#define IX_OSAL_WRITE_BYTE_BE(bAddr, bData) IX_OSAL_WRITE_BYTE_IO((volatile UINT8 *) (bAddr), IX_OSAL_BE_XSTOBUSB((UINT8) (bData) ))
+
+/* Define LE AC macros */
+#define IX_OSAL_READ_LONG_LE_AC(wAddr) IX_OSAL_READ_LONG_IO((volatile UINT32 *) IX_OSAL_LE_AC_BUSTOXSL((UINT32) (wAddr) ))
+#define IX_OSAL_READ_SHORT_LE_AC(sAddr) IX_OSAL_READ_SHORT_IO((volatile UINT16 *) IX_OSAL_LE_AC_BUSTOXSS((UINT32) (sAddr) ))
+#define IX_OSAL_READ_BYTE_LE_AC(bAddr) IX_OSAL_READ_BYTE_IO((volatile UINT8 *) IX_OSAL_LE_AC_BUSTOXSB((UINT32) (bAddr) ))
+#define IX_OSAL_WRITE_LONG_LE_AC(wAddr, wData) IX_OSAL_WRITE_LONG_IO((volatile UINT32 *) IX_OSAL_LE_AC_XSTOBUSL((UINT32) (wAddr) ), (UINT32) (wData))
+#define IX_OSAL_WRITE_SHORT_LE_AC(sAddr, sData) IX_OSAL_WRITE_SHORT_IO((volatile UINT16 *) IX_OSAL_LE_AC_XSTOBUSS((UINT32) (sAddr) ), (UINT16) (sData))
+#define IX_OSAL_WRITE_BYTE_LE_AC(bAddr, bData) IX_OSAL_WRITE_BYTE_IO((volatile UINT8 *) IX_OSAL_LE_AC_XSTOBUSB((UINT32) (bAddr) ), (UINT8) (bData))
+
+
+/* Inline functions are required here to avoid reading the same I/O location 2 or 4 times for the byte swap */
+static __inline__ UINT32
+ixOsalDataCoherentLongReadSwap (volatile UINT32 * wAddr)
+{
+ UINT32 wData = IX_OSAL_READ_LONG_IO (wAddr);
+ return IX_OSAL_LE_DC_BUSTOXSL (wData);
+}
+
+static __inline__ UINT16
+ixOsalDataCoherentShortReadSwap (volatile UINT16 * sAddr)
+{
+ UINT16 sData = IX_OSAL_READ_SHORT_IO (sAddr);
+ return IX_OSAL_LE_DC_BUSTOXSS (sData);
+}
+
+static __inline__ void
+ixOsalDataCoherentLongWriteSwap (volatile UINT32 * wAddr, UINT32 wData)
+{
+ wData = IX_OSAL_LE_DC_XSTOBUSL (wData);
+ IX_OSAL_WRITE_LONG_IO (wAddr, wData);
+}
+
+static __inline__ void
+ixOsalDataCoherentShortWriteSwap (volatile UINT16 * sAddr, UINT16 sData)
+{
+ sData = IX_OSAL_LE_DC_XSTOBUSS (sData);
+ IX_OSAL_WRITE_SHORT_IO (sAddr, sData);
+}
+
+/* Define LE DC macros */
+
+#define IX_OSAL_READ_LONG_LE_DC(wAddr) ixOsalDataCoherentLongReadSwap((volatile UINT32 *) (wAddr) )
+#define IX_OSAL_READ_SHORT_LE_DC(sAddr) ixOsalDataCoherentShortReadSwap((volatile UINT16 *) (sAddr) )
+#define IX_OSAL_READ_BYTE_LE_DC(bAddr) IX_OSAL_LE_DC_BUSTOXSB(IX_OSAL_READ_BYTE_IO((volatile UINT8 *) (bAddr) ))
+#define IX_OSAL_WRITE_LONG_LE_DC(wAddr, wData) ixOsalDataCoherentLongWriteSwap((volatile UINT32 *) (wAddr), (UINT32) (wData))
+#define IX_OSAL_WRITE_SHORT_LE_DC(sAddr, sData) ixOsalDataCoherentShortWriteSwap((volatile UINT16 *) (sAddr), (UINT16) (sData))
+#define IX_OSAL_WRITE_BYTE_LE_DC(bAddr, bData) IX_OSAL_WRITE_BYTE_IO((volatile UINT8 *) (bAddr), IX_OSAL_LE_DC_XSTOBUSB((UINT8) (bData)))
+
+#if defined (IX_OSAL_BE_MAPPING)
+
+#define IX_OSAL_READ_LONG(wAddr) IX_OSAL_READ_LONG_BE(wAddr)
+#define IX_OSAL_READ_SHORT(sAddr) IX_OSAL_READ_SHORT_BE(sAddr)
+#define IX_OSAL_READ_BYTE(bAddr) IX_OSAL_READ_BYTE_BE(bAddr)
+#define IX_OSAL_WRITE_LONG(wAddr, wData) IX_OSAL_WRITE_LONG_BE(wAddr, wData)
+#define IX_OSAL_WRITE_SHORT(sAddr, sData) IX_OSAL_WRITE_SHORT_BE(sAddr, sData)
+#define IX_OSAL_WRITE_BYTE(bAddr, bData) IX_OSAL_WRITE_BYTE_BE(bAddr, bData)
+
+#elif defined (IX_OSAL_LE_AC_MAPPING)
+
+#define IX_OSAL_READ_LONG(wAddr) IX_OSAL_READ_LONG_LE_AC(wAddr)
+#define IX_OSAL_READ_SHORT(sAddr) IX_OSAL_READ_SHORT_LE_AC(sAddr)
+#define IX_OSAL_READ_BYTE(bAddr) IX_OSAL_READ_BYTE_LE_AC(bAddr)
+#define IX_OSAL_WRITE_LONG(wAddr, wData) IX_OSAL_WRITE_LONG_LE_AC(wAddr, wData)
+#define IX_OSAL_WRITE_SHORT(sAddr, sData) IX_OSAL_WRITE_SHORT_LE_AC(sAddr, sData)
+#define IX_OSAL_WRITE_BYTE(bAddr, bData) IX_OSAL_WRITE_BYTE_LE_AC(bAddr, bData)
+
+#elif defined (IX_OSAL_LE_DC_MAPPING)
+
+#define IX_OSAL_READ_LONG(wAddr) IX_OSAL_READ_LONG_LE_DC(wAddr)
+#define IX_OSAL_READ_SHORT(sAddr) IX_OSAL_READ_SHORT_LE_DC(sAddr)
+#define IX_OSAL_READ_BYTE(bAddr) IX_OSAL_READ_BYTE_LE_DC(bAddr)
+#define IX_OSAL_WRITE_LONG(wAddr, wData) IX_OSAL_WRITE_LONG_LE_DC(wAddr, wData)
+#define IX_OSAL_WRITE_SHORT(sAddr, sData) IX_OSAL_WRITE_SHORT_LE_DC(sAddr, sData)
+#define IX_OSAL_WRITE_BYTE(bAddr, bData) IX_OSAL_WRITE_BYTE_LE_DC(bAddr, bData)
+
+#endif /* End of BE and LE coherency mode switch */
+
+
+/* Reads/writes to and from memory shared with NPEs - depends on the SDRAM coherency */
+
+#if defined (IX_SDRAM_BE)
+
+#define IX_OSAL_READ_BE_SHARED_LONG(wAddr) IX_OSAL_READ_LONG_RAW(wAddr)
+#define IX_OSAL_READ_BE_SHARED_SHORT(sAddr) IX_OSAL_READ_SHORT_RAW(sAddr)
+#define IX_OSAL_READ_BE_SHARED_BYTE(bAddr) IX_OSAL_READ_BYTE_RAW(bAddr)
+
+#define IX_OSAL_WRITE_BE_SHARED_LONG(wAddr, wData) IX_OSAL_WRITE_LONG_RAW(wAddr, wData)
+#define IX_OSAL_WRITE_BE_SHARED_SHORT(sAddr, sData) IX_OSAL_WRITE_SHORT_RAW(sAddr, sData)
+#define IX_OSAL_WRITE_BE_SHARED_BYTE(bAddr, bData) IX_OSAL_WRITE_BYTE_RAW(bAddr, bData)
+
+#define IX_OSAL_SWAP_BE_SHARED_LONG(wData) (wData)
+#define IX_OSAL_SWAP_BE_SHARED_SHORT(sData) (sData)
+#define IX_OSAL_SWAP_BE_SHARED_BYTE(bData) (bData)
+
+#elif defined (IX_SDRAM_LE_ADDRESS_COHERENT)
+
+#define IX_OSAL_READ_BE_SHARED_LONG(wAddr) IX_OSAL_READ_LONG_RAW(wAddr)
+#define IX_OSAL_READ_BE_SHARED_SHORT(sAddr) IX_OSAL_READ_SHORT_RAW(IX_OSAL_SWAP_SHORT_ADDRESS(sAddr))
+#define IX_OSAL_READ_BE_SHARED_BYTE(bAddr) IX_OSAL_READ_BYTE_RAW(IX_OSAL_SWAP_BYTE_ADDRESS(bAddr))
+
+#define IX_OSAL_WRITE_BE_SHARED_LONG(wAddr, wData) IX_OSAL_WRITE_LONG_RAW(wAddr, wData)
+#define IX_OSAL_WRITE_BE_SHARED_SHORT(sAddr, sData) IX_OSAL_WRITE_SHORT_RAW(IX_OSAL_SWAP_SHORT_ADDRESS(sAddr), sData)
+#define IX_OSAL_WRITE_BE_SHARED_BYTE(bAddr, bData) IX_OSAL_WRITE_BYTE_RAW(IX_OSAL_SWAP_BYTE_ADDRESS(bAddr), bData)
+
+#define IX_OSAL_SWAP_BE_SHARED_LONG(wData) (wData)
+#define IX_OSAL_SWAP_BE_SHARED_SHORT(sData) (sData)
+#define IX_OSAL_SWAP_BE_SHARED_BYTE(bData) (bData)
+
+#elif defined (IX_SDRAM_LE_DATA_COHERENT)
+
+#define IX_OSAL_READ_BE_SHARED_LONG(wAddr) IX_OSAL_SWAP_LONG(IX_OSAL_READ_LONG_RAW(wAddr))
+#define IX_OSAL_READ_BE_SHARED_SHORT(sAddr) IX_OSAL_SWAP_SHORT(IX_OSAL_READ_SHORT_RAW(sAddr))
+#define IX_OSAL_READ_BE_SHARED_BYTE(bAddr) IX_OSAL_READ_BYTE_RAW(bAddr)
+
+#define IX_OSAL_WRITE_BE_SHARED_LONG(wAddr, wData) IX_OSAL_WRITE_LONG_RAW(wAddr, IX_OSAL_SWAP_LONG(wData))
+#define IX_OSAL_WRITE_BE_SHARED_SHORT(sAddr, sData) IX_OSAL_WRITE_SHORT_RAW(sAddr, IX_OSAL_SWAP_SHORT(sData))
+#define IX_OSAL_WRITE_BE_SHARED_BYTE(bAddr, bData) IX_OSAL_WRITE_BYTE_RAW(bAddr, bData)
+
+#define IX_OSAL_SWAP_BE_SHARED_LONG(wData) IX_OSAL_SWAP_LONG(wData)
+#define IX_OSAL_SWAP_BE_SHARED_SHORT(sData) IX_OSAL_SWAP_SHORT(sData)
+
+#endif
+
+
+#define IX_OSAL_COPY_BE_SHARED_LONG_ARRAY(wDestAddr, wSrcAddr, wCount) \
+ { \
+ UINT32 i; \
+ \
+ for ( i = 0 ; i < wCount ; i++ ) \
+ { \
+ * (((UINT32 *) wDestAddr) + i) = IX_OSAL_READ_BE_SHARED_LONG(((UINT32 *) wSrcAddr) + i); \
+ }; \
+ };
+
+#endif /* IxOsalMemAccess_H */
diff --git a/cpu/ixp/npe/include/IxOsalOem.h b/cpu/ixp/npe/include/IxOsalOem.h
new file mode 100644
index 0000000..f894026
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalOem.h
@@ -0,0 +1,97 @@
+/**
+ * @file IxOsalIxpOem.h
+ *
+ * @brief this file contains platform-specific defines.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsalOem_H
+#define IxOsalOem_H
+
+#include "IxOsalTypes.h"
+
+/* OS-specific header for Platform package */
+#include "IxOsalOsIxp400.h"
+
+/*
+ * Platform Name
+ */
+#define IX_OSAL_PLATFORM_NAME ixp400
+
+/*
+ * Cache line size
+ */
+#define IX_OSAL_CACHE_LINE_SIZE (32)
+
+
+/* Platform-specific fastmutex implementation */
+PUBLIC IX_STATUS ixOsalOemFastMutexTryLock (IxOsalFastMutex * mutex);
+
+/* Platform-specific init (MemMap) */
+PUBLIC IX_STATUS
+ixOsalOemInit (void);
+
+/* Platform-specific unload (MemMap) */
+PUBLIC void
+ixOsalOemUnload (void);
+
+/* Default implementations */
+
+PUBLIC UINT32
+ixOsalIxp400SharedTimestampGet (void);
+
+
+UINT32
+ixOsalIxp400SharedTimestampRateGet (void);
+
+UINT32
+ixOsalIxp400SharedSysClockRateGet (void);
+
+void
+ixOsalIxp400SharedTimeGet (IxOsalTimeval * tv);
+
+
+INT32
+ixOsalIxp400SharedLog (UINT32 level, UINT32 device, char *format,
+ int arg1, int arg2, int arg3, int arg4,
+ int arg5, int arg6);
+
+#endif /* IxOsal_Oem_H */
diff --git a/cpu/ixp/npe/include/IxOsalOs.h b/cpu/ixp/npe/include/IxOsalOs.h
new file mode 100644
index 0000000..6c66613
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalOs.h
@@ -0,0 +1,30 @@
+#ifndef IxOsalOs_H
+#define IxOsalOs_H
+
+#ifndef IX_OSAL_CACHED
+#error "Uncached memory not supported in linux environment"
+#endif
+
+static inline unsigned long __v2p(unsigned long v)
+{
+ if (v < 0x40000000)
+ return (v & 0xfffffff);
+ else
+ return v;
+}
+
+#define IX_OSAL_OS_MMU_VIRT_TO_PHYS(addr) __v2p((u32)addr)
+#define IX_OSAL_OS_MMU_PHYS_TO_VIRT(addr) (addr)
+
+/*
+ * Data cache not enabled (hopefully)
+ */
+#define IX_OSAL_OS_CACHE_INVALIDATE(addr, size)
+#define IX_OSAL_OS_CACHE_FLUSH(addr, size)
+#define HAL_DCACHE_INVALIDATE(addr, size)
+#define HAL_DCACHE_FLUSH(addr, size)
+
+#define __ixp42X /* sr: U-Boot needs this define */
+
+#endif /* IxOsalOs_H */
+
diff --git a/cpu/ixp/npe/include/IxOsalOsAssert.h b/cpu/ixp/npe/include/IxOsalOsAssert.h
new file mode 100644
index 0000000..e4c3e1f
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalOsAssert.h
@@ -0,0 +1,10 @@
+#ifndef IxOsalOsAssert_H
+#define IxOsalOsAssert_H
+
+#define IX_OSAL_OS_ASSERT(c) if(!(c)) \
+ { \
+ ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "Assertion failure \n", 0, 0, 0, 0, 0, 0);\
+ while(1); \
+ }
+
+#endif /* IxOsalOsAssert_H */
diff --git a/cpu/ixp/npe/include/IxOsalOsBufferMgt.h b/cpu/ixp/npe/include/IxOsalOsBufferMgt.h
new file mode 100644
index 0000000..8e46586
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalOsBufferMgt.h
@@ -0,0 +1,96 @@
+/**
+ * @file IxOsalOsBufferMgt.h
+ *
+ * @brief vxworks-specific buffer management module definitions.
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#ifndef IX_OSAL_OS_BUFFER_MGT_H
+#define IX_OSAL_OS_BUFFER_MGT_H
+
+/*
+ * use the defaul bufferMgt provided by OSAL framework.
+ */
+#define IX_OSAL_USE_DEFAULT_BUFFER_MGT
+
+#include "IxOsalBufferMgtDefault.h"
+
+#if 0 /* FIXME */
+/* Define os-specific buffer macros for subfields */
+#define IX_OSAL_OSBUF_MDATA(osBufPtr) IX_OSAL_MBUF_MDATA(osBufPtr)
+ ( ((M_BLK *) osBufPtr)->m_data )
+
+#define IX_OSAL_OSBUF_MLEN(osBufPtr) \
+ ( ((M_BLK *) osBufPtr)->m_len )
+
+#define IX_OSAL_OSBUF_PKT_LEN(osBufPtr) \
+ ( ((M_BLK *) osBufPtr)->m_pkthdr.len )
+
+#define IX_OSAL_OS_CONVERT_OSBUF_TO_IXPBUF( osBufPtr, ixpBufPtr) \
+ { \
+ IX_OSAL_MBUF_OSBUF_PTR( (IX_OSAL_MBUF *) ixpBufPtr) = (void *) osBufPtr; \
+ IX_OSAL_MBUF_MDATA((IX_OSAL_MBUF *) ixpBufPtr) = IX_OSAL_OSBUF_MDATA(osBufPtr); \
+ IX_OSAL_MBUF_PKT_LEN((IX_OSAL_MBUF *) ixpBufPtr) = IX_OSAL_OSBUF_PKT_LEN(osBufPtr); \
+ IX_OSAL_MBUF_MLEN((IX_OSAL_MBUF *) ixpBufPtr) = IX_OSAL_OSBUF_MLEN(osBufPtr); \
+ }
+
+#define IX_OSAL_OS_CONVERT_IXPBUF_TO_OSBUF( ixpBufPtr, osBufPtr) \
+ { \
+ if (ixpBufPtr == NULL) \
+ { /* Do nothing */ } \
+ else \
+ { \
+ (M_BLK *) osBufPtr = (M_BLK *) IX_OSAL_MBUF_OSBUF_PTR((IX_OSAL_MBUF *) ixpBufPtr); \
+ if (osBufPtr == NULL) \
+ { /* Do nothing */ } \
+ else \
+ { \
+ IX_OSAL_OSBUF_MLEN(osBufPtr) =IX_OSAL_MBUF_MLEN((IX_OSAL_MBUF *) ixpBufPtr); \
+ IX_OSAL_OSBUF_PKT_LEN(osBufPtr) =IX_OSAL_MBUF_PKT_LEN((IX_OSAL_MBUF *) ixpBufPtr); \
+ } \
+ } \
+ }
+
+#endif /* FIXME */
+
+#endif /* #define IX_OSAL_OS_BUFFER_MGT_H */
diff --git a/cpu/ixp/npe/include/IxOsalOsIxp400.h b/cpu/ixp/npe/include/IxOsalOsIxp400.h
new file mode 100644
index 0000000..44a94fb
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalOsIxp400.h
@@ -0,0 +1,316 @@
+/**
+ * @file IxOsalOsIxp400.h
+ *
+ * @brief OS and platform specific definitions
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsalOsIxp400_H
+#define IxOsalOsIxp400_H
+
+#define BIT(x) (1<<(x))
+
+#define IXP425_EthA_BASE 0xc8009000
+#define IXP425_EthB_BASE 0xc800a000
+
+#define IXP425_PSMA_BASE 0xc8006000
+#define IXP425_PSMB_BASE 0xc8007000
+#define IXP425_PSMC_BASE 0xc8008000
+
+#define IXP425_PERIPHERAL_BASE 0xc8000000
+
+#define IXP425_QMGR_BASE 0x60000000
+#define IXP425_OSTS 0xC8005000
+
+#define IXP425_INT_LVL_NPEA 0
+#define IXP425_INT_LVL_NPEB 1
+#define IXP425_INT_LVL_NPEC 2
+
+#define IXP425_INT_LVL_QM1 3
+#define IXP425_INT_LVL_QM2 4
+
+#define IXP425_EXPANSION_BUS_BASE1 0x50000000
+#define IXP425_EXPANSION_BUS_BASE2 0x50000000
+#define IXP425_EXPANSION_BUS_CS1_BASE 0x51000000
+
+#define IXP425_EXP_CONFIG_BASE 0xC4000000
+
+/* physical addresses to be used when requesting memory with IX_OSAL_MEM_MAP */
+#define IX_OSAL_IXP400_INTC_PHYS_BASE IXP425_INTC_BASE
+#define IX_OSAL_IXP400_GPIO_PHYS_BASE IXP425_GPIO_BASE
+#define IX_OSAL_IXP400_UART1_PHYS_BASE IXP425_UART1_BASE
+#define IX_OSAL_IXP400_UART2_PHYS_BASE IXP425_UART2_BASE
+#define IX_OSAL_IXP400_ETHA_PHYS_BASE IXP425_EthA_BASE
+#define IX_OSAL_IXP400_ETHB_PHYS_BASE IXP425_EthB_BASE
+#define IX_OSAL_IXP400_NPEA_PHYS_BASE IXP425_NPEA_BASE
+#define IX_OSAL_IXP400_NPEB_PHYS_BASE IXP425_NPEB_BASE
+#define IX_OSAL_IXP400_NPEC_PHYS_BASE IXP425_NPEC_BASE
+#define IX_OSAL_IXP400_PERIPHERAL_PHYS_BASE IXP425_PERIPHERAL_BASE
+#define IX_OSAL_IXP400_QMGR_PHYS_BASE IXP425_QMGR_BASE
+#define IX_OSAL_IXP400_OSTS_PHYS_BASE IXP425_TIMER_BASE
+#define IX_OSAL_IXP400_USB_PHYS_BASE IXP425_USB_BASE
+#define IX_OSAL_IXP400_EXP_CFG_PHYS_BASE IXP425_EXP_CFG_BASE
+#define IX_OSAL_IXP400_EXP_BUS_PHYS_BASE IXP425_EXP_BUS_BASE2
+#define IX_OSAL_IXP400_EXP_BUS_BOOT_PHYS_BASE IXP425_EXP_BUS_BASE1
+#define IX_OSAL_IXP400_EXP_BUS_CS0_PHYS_BASE IXP425_EXP_BUS_CS0_BASE
+#define IX_OSAL_IXP400_EXP_BUS_CS1_PHYS_BASE IXP425_EXP_BUS_CS1_BASE
+#define IX_OSAL_IXP400_EXP_BUS_CS4_PHYS_BASE IXP425_EXP_BUS_CS4_BASE
+#define IX_OSAL_IXP400_EXP_BUS_REGS_PHYS_BASE IXP425_EXP_CFG_BASE
+#define IX_OSAL_IXP400_PCI_CFG_PHYS_BASE IXP425_PCI_CFG_BASE
+
+/* map sizes to be used when requesting memory with IX_OSAL_MEM_MAP */
+#define IX_OSAL_IXP400_QMGR_MAP_SIZE (0x4000) /**< Queue Manager map size */
+#define IX_OSAL_IXP400_PERIPHERAL_MAP_SIZE (0xC000) /**< Peripheral space map size */
+#define IX_OSAL_IXP400_UART1_MAP_SIZE (0x1000) /**< UART1 map size */
+#define IX_OSAL_IXP400_UART2_MAP_SIZE (0x1000) /**< UART2 map size */
+#define IX_OSAL_IXP400_PMU_MAP_SIZE (0x1000) /**< PMU map size */
+#define IX_OSAL_IXP400_OSTS_MAP_SIZE (0x1000) /**< OS Timers map size */
+#define IX_OSAL_IXP400_NPEA_MAP_SIZE (0x1000) /**< NPE A map size */
+#define IX_OSAL_IXP400_NPEB_MAP_SIZE (0x1000) /**< NPE B map size */
+#define IX_OSAL_IXP400_NPEC_MAP_SIZE (0x1000) /**< NPE C map size */
+#define IX_OSAL_IXP400_ETHA_MAP_SIZE (0x1000) /**< Eth A map size */
+#define IX_OSAL_IXP400_ETHB_MAP_SIZE (0x1000) /**< Eth B map size */
+#define IX_OSAL_IXP400_USB_MAP_SIZE (0x1000) /**< USB map size */
+#define IX_OSAL_IXP400_GPIO_MAP_SIZE (0x1000) /**< GPIO map size */
+#define IX_OSAL_IXP400_EXP_REG_MAP_SIZE (0x1000) /**< Exp Bus Config Registers map size */
+#define IX_OSAL_IXP400_EXP_BUS_MAP_SIZE (0x08000000) /**< Expansion bus map size */
+#define IX_OSAL_IXP400_EXP_BUS_CS0_MAP_SIZE (0x01000000) /**< CS0 map size */
+#define IX_OSAL_IXP400_EXP_BUS_CS1_MAP_SIZE (0x01000000) /**< CS1 map size */
+#define IX_OSAL_IXP400_EXP_BUS_CS4_MAP_SIZE (0x01000000) /**< CS4 map size */
+#define IX_OSAL_IXP400_PCI_CFG_MAP_SIZE (0x1000) /**< PCI Bus Config Registers map size */
+
+#define IX_OSAL_IXP400_EXP_FUSE (IXP425_EXP_CONFIG_BASE + 0x28)
+#define IX_OSAL_IXP400_ETH_NPEA_PHYS_BASE 0xC800C000
+#define IX_OSAL_IXP400_ETH_NPEA_MAP_SIZE 0x1000
+
+/*
+ * Interrupt Levels
+ */
+#define IX_OSAL_IXP400_NPEA_IRQ_LVL (0)
+#define IX_OSAL_IXP400_NPEB_IRQ_LVL (1)
+#define IX_OSAL_IXP400_NPEC_IRQ_LVL (2)
+#define IX_OSAL_IXP400_QM1_IRQ_LVL (3)
+#define IX_OSAL_IXP400_QM2_IRQ_LVL (4)
+#define IX_OSAL_IXP400_TIMER1_IRQ_LVL (5)
+#define IX_OSAL_IXP400_GPIO0_IRQ_LVL (6)
+#define IX_OSAL_IXP400_GPIO1_IRQ_LVL (7)
+#define IX_OSAL_IXP400_PCI_INT_IRQ_LVL (8)
+#define IX_OSAL_IXP400_PCI_DMA1_IRQ_LVL (9)
+#define IX_OSAL_IXP400_PCI_DMA2_IRQ_LVL (10)
+#define IX_OSAL_IXP400_TIMER2_IRQ_LVL (11)
+#define IX_OSAL_IXP400_USB_IRQ_LVL (12)
+#define IX_OSAL_IXP400_UART2_IRQ_LVL (13)
+#define IX_OSAL_IXP400_TIMESTAMP_IRQ_LVL (14)
+#define IX_OSAL_IXP400_UART1_IRQ_LVL (15)
+#define IX_OSAL_IXP400_WDOG_IRQ_LVL (16)
+#define IX_OSAL_IXP400_AHB_PMU_IRQ_LVL (17)
+#define IX_OSAL_IXP400_XSCALE_PMU_IRQ_LVL (18)
+#define IX_OSAL_IXP400_GPIO2_IRQ_LVL (19)
+#define IX_OSAL_IXP400_GPIO3_IRQ_LVL (20)
+#define IX_OSAL_IXP400_GPIO4_IRQ_LVL (21)
+#define IX_OSAL_IXP400_GPIO5_IRQ_LVL (22)
+#define IX_OSAL_IXP400_GPIO6_IRQ_LVL (23)
+#define IX_OSAL_IXP400_GPIO7_IRQ_LVL (24)
+#define IX_OSAL_IXP400_GPIO8_IRQ_LVL (25)
+#define IX_OSAL_IXP400_GPIO9_IRQ_LVL (26)
+#define IX_OSAL_IXP400_GPIO10_IRQ_LVL (27)
+#define IX_OSAL_IXP400_GPIO11_IRQ_LVL (28)
+#define IX_OSAL_IXP400_GPIO12_IRQ_LVL (29)
+#define IX_OSAL_IXP400_SW_INT1_IRQ_LVL (30)
+#define IX_OSAL_IXP400_SW_INT2_IRQ_LVL (31)
+
+/* USB interrupt level mask */
+#define IX_OSAL_IXP400_INT_LVL_USB IRQ_IXP425_USB
+
+/* USB IRQ */
+#define IX_OSAL_IXP400_USB_IRQ IRQ_IXP425_USB
+
+/*
+ * OS name retrieval
+ */
+#define IX_OSAL_OEM_OS_NAME_GET(name, limit) \
+ixOsalOsIxp400NameGet((INT8*)(name), (INT32) (limit))
+
+/*
+ * OS version retrieval
+ */
+#define IX_OSAL_OEM_OS_VERSION_GET(version, limit) \
+ixOsalOsIxp400VersionGet((INT8*)(version), (INT32) (limit))
+
+/*
+ * Function to retrieve the OS name
+ */
+PUBLIC IX_STATUS ixOsalOsIxp400NameGet(INT8* osName, INT32 maxSize);
+
+/*
+ * Function to retrieve the OS version
+ */
+PUBLIC IX_STATUS ixOsalOsIxp400VersionGet(INT8* osVersion, INT32 maxSize);
+
+/*
+ * TimestampGet
+ */
+PUBLIC UINT32 ixOsalOsIxp400TimestampGet (void);
+
+/*
+ * Timestamp
+ */
+#define IX_OSAL_OEM_TIMESTAMP_GET ixOsalOsIxp400TimestampGet
+
+
+/*
+ * Timestamp resolution
+ */
+PUBLIC UINT32 ixOsalOsIxp400TimestampResolutionGet (void);
+
+#define IX_OSAL_OEM_TIMESTAMP_RESOLUTION_GET ixOsalOsIxp400TimestampResolutionGet
+
+/*
+ * Retrieves the system clock rate
+ */
+PUBLIC UINT32 ixOsalOsIxp400SysClockRateGet (void);
+
+#define IX_OSAL_OEM_SYS_CLOCK_RATE_GET ixOsalOsIxp400SysClockRateGet
+
+/*
+ * required by FS but is not really platform-specific.
+ */
+#define IX_OSAL_OEM_TIME_GET(pTv) ixOsalTimeGet(pTv)
+
+
+
+/* linux map/unmap functions */
+PUBLIC void ixOsalLinuxMemMap (IxOsalMemoryMap * map);
+
+PUBLIC void ixOsalLinuxMemUnmap (IxOsalMemoryMap * map);
+
+
+/*********************
+ * Memory map
+ ********************/
+
+/* Global memmap only visible to IO MEM module */
+
+#ifdef IxOsalIoMem_C
+
+IxOsalMemoryMap ixOsalGlobalMemoryMap[] = {
+ {
+ /* Global BE and LE_AC map */
+ IX_OSAL_STATIC_MAP, /* type */
+ 0x00000000, /* physicalAddress */
+ 0x30000000, /* size */
+ 0x00000000, /* virtualAddress */
+ NULL, /* mapFunction */
+ NULL, /* unmapFunction */
+ 0, /* refCount */
+ IX_OSAL_BE | IX_OSAL_LE_AC,/* endianType */
+ "global_low" /* name */
+ },
+
+ /* SDRAM LE_DC alias */
+ {
+ IX_OSAL_STATIC_MAP, /* type */
+ 0x00000000, /* physicalAddress */
+ 0x10000000, /* size */
+ 0x30000000, /* virtualAddress */
+ NULL, /* mapFunction */
+ NULL, /* unmapFunction */
+ 0, /* refCount */
+ IX_OSAL_LE_DC, /* endianType */
+ "sdram_dc" /* name */
+ },
+
+ /* QMGR LE_DC alias */
+ {
+ IX_OSAL_STATIC_MAP, /* type */
+ 0x60000000, /* physicalAddress */
+ 0x00100000, /* size */
+ 0x60000000, /* virtualAddress */
+ NULL, /* mapFunction */
+ NULL, /* unmapFunction */
+ 0, /* refCount */
+ IX_OSAL_LE_DC, /* endianType */
+ "qmgr_dc" /* name */
+ },
+
+ /* QMGR BE alias */
+ {
+ IX_OSAL_STATIC_MAP, /* type */
+ 0x60000000, /* physicalAddress */
+ 0x00100000, /* size */
+ 0x60000000, /* virtualAddress */
+ NULL, /* mapFunction */
+ NULL, /* unmapFunction */
+ 0, /* refCount */
+ IX_OSAL_BE | IX_OSAL_LE_AC,/* endianType */
+ "qmgr_be" /* name */
+ },
+
+ /* Global BE and LE_AC map */
+ {
+ IX_OSAL_STATIC_MAP, /* type */
+ 0x40000000, /* physicalAddress */
+ 0x20000000, /* size */
+ 0x40000000, /* virtualAddress */
+ NULL, /* mapFunction */
+ NULL, /* unmapFunction */
+ 0, /* refCount */
+ IX_OSAL_BE | IX_OSAL_LE_AC,/* endianType */
+ "Misc Cfg" /* name */
+ },
+
+ /* Global BE and LE_AC map */
+ {
+ IX_OSAL_STATIC_MAP, /* type */
+ 0x70000000, /* physicalAddress */
+ 0x8FFFFFFF, /* size */
+ 0x70000000, /* virtualAddress */
+ NULL, /* mapFunction */
+ NULL, /* unmapFunction */
+ 0, /* refCount */
+ IX_OSAL_BE | IX_OSAL_LE_AC,/* endianType */
+ "Exp Cfg" /* name */
+ },
+};
+
+#endif /* IxOsalIoMem_C */
+#endif /* #define IxOsalOsIxp400_H */
diff --git a/cpu/ixp/npe/include/IxOsalOsIxp400CustomizedMapping.h b/cpu/ixp/npe/include/IxOsalOsIxp400CustomizedMapping.h
new file mode 100644
index 0000000..47ce3a2
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalOsIxp400CustomizedMapping.h
@@ -0,0 +1,404 @@
+/**
+ * @file IxOsalOsIxp400CustomizedMapping.h
+ *
+ * @brief Set LE coherency modes for components.
+ * The default setting is IX_OSAL_NO_MAPPING for LE.
+ *
+ *
+ * By default IX_OSAL_STATIC_MEMORY_MAP is defined for all the components.
+ * If any component uses a dynamic memory map it must define
+ * IX_OSAL_DYNAMIC_MEMORY_MAP in its corresponding section.
+ *
+ *
+ * @par
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsalOsIxp400CustomizedMapping_H
+#define IxOsalOsIxp400CustomizedMapping_H
+
+/*
+ * only include this file in Little Endian
+ */
+
+#if defined (IX_OSAL_LINUX_BE)
+#error Only include IxOsalOsIxp400CustomizedMapping.h in Little Endian
+#endif
+
+ /*
+ * Components don't have to be in this list if
+ * the default mapping is OK.
+ */
+#define ix_osal 1
+#define ix_dmaAcc 2
+#define ix_atmdAcc 3
+
+#define ix_atmsch 5
+#define ix_ethAcc 6
+#define ix_npeMh 7
+#define ix_qmgr 8
+#define ix_npeDl 9
+#define ix_atmm 10
+#define ix_hssAcc 11
+#define ix_ethDB 12
+#define ix_ethMii 13
+#define ix_timerCtrl 14
+#define ix_adsl 15
+#define ix_usb 16
+#define ix_uartAcc 17
+#define ix_featureCtrl 18
+#define ix_cryptoAcc 19
+#define ix_unloadAcc 33
+#define ix_perfProfAcc 34
+#define ix_parityENAcc 49
+#define ix_sspAcc 51
+#define ix_timeSyncAcc 52
+#define ix_i2c 53
+
+#define ix_codelets_uartAcc 21
+#define ix_codelets_timers 22
+#define ix_codelets_atm 23
+#define ix_codelets_ethAal5App 24
+#define ix_codelets_demoUtils 26
+#define ix_codelets_usb 27
+#define ix_codelets_hssAcc 28
+#define ix_codelets_dmaAcc 40
+#define ix_codelets_cryptoAcc 41
+#define ix_codelets_perfProfAcc 42
+#define ix_codelets_ethAcc 43
+#define ix_codelets_parityENAcc 54
+#define ix_codelets_timeSyncAcc 55
+
+
+#endif /* IxOsalOsIxp400CustomizedMapping_H */
+
+
+/***************************
+ * osal
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_osal)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* osal */
+
+/***************************
+ * dmaAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_dmaAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* dmaAcc */
+
+/***************************
+ * atmdAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_atmdAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* atmdAcc */
+
+/***************************
+ * atmsch
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_atmsch)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* atmsch */
+
+/***************************
+ * ethAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_ethAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* ethAcc */
+
+/***************************
+ * npeMh
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_npeMh)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* npeMh */
+
+/***************************
+ * qmgr
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_qmgr)
+
+#define IX_OSAL_LE_DC_MAPPING
+
+#endif /* qmgr */
+
+/***************************
+ * npeDl
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_npeDl)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* npeDl */
+
+/***************************
+ * atmm
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_atmm)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* atmm */
+
+/***************************
+ * ethMii
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_ethMii)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* ethMii */
+
+
+/***************************
+ * adsl
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_adsl)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* adsl */
+
+/***************************
+ * usb
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_usb)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* usb */
+
+/***************************
+ * uartAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_uartAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* uartAcc */
+
+/***************************
+ * featureCtrl
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_featureCtrl)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* featureCtrl */
+
+/***************************
+ * cryptoAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_cryptoAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* cryptoAcc */
+
+/***************************
+ * codelets_usb
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_usb)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_usb */
+
+
+/***************************
+ * codelets_uartAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_uartAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_uartAcc */
+
+
+
+/***************************
+ * codelets_timers
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_timers)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_timers */
+
+/***************************
+ * codelets_atm
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_atm)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_atm */
+
+/***************************
+ * codelets_ethAal5App
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_ethAal5App)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_ethAal5App */
+
+/***************************
+ * codelets_ethAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_ethAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_ethAcc */
+
+
+/***************************
+ * codelets_demoUtils
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_demoUtils)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_demoUtils */
+
+
+
+/***************************
+ * perfProfAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_perfProfAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* perfProfAcc */
+
+
+/***************************
+ * unloadAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_unloadAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* unloadAcc */
+
+
+
+
+
+/***************************
+ * parityENAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_parityENAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* parityENAcc */
+
+/***************************
+ * codelets_parityENAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_parityENAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_parityENAcc */
+
+
+
+
+/***************************
+ * timeSyncAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_timeSyncAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* timeSyncAcc */
+
+
+/***************************
+ * codelets_timeSyncAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_timeSyncAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_timeSyncAcc */
+
+
+
+
+/***************************
+ * i2c
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_i2c)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* i2c */
+
+
+
+/***************************
+ * sspAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_sspAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* sspAcc */
+
+
diff --git a/cpu/ixp/npe/include/IxOsalOsTypes.h b/cpu/ixp/npe/include/IxOsalOsTypes.h
new file mode 100644
index 0000000..272eef1
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalOsTypes.h
@@ -0,0 +1,60 @@
+#ifndef IxOsalOsTypes_H
+#define IxOsalOsTypes_H
+
+#include <asm/types.h>
+
+typedef s64 INT64;
+typedef u64 UINT64;
+typedef s32 INT32;
+typedef u32 UINT32;
+typedef s16 INT16;
+typedef u16 UINT16;
+typedef s8 INT8;
+typedef u8 UINT8;
+
+typedef u32 ULONG;
+typedef u16 USHORT;
+typedef u8 UCHAR;
+typedef u32 BOOL;
+
+#if 0 /* FIXME */
+
+/* Default stack limit is 10 KB */
+#define IX_OSAL_OS_THREAD_DEFAULT_STACK_SIZE (10240)
+
+/* Maximum stack limit is 32 MB */
+#define IX_OSAL_OS_THREAD_MAX_STACK_SIZE (33554432) /* 32 MBytes */
+
+/* Default thread priority */
+#define IX_OSAL_OS_DEFAULT_THREAD_PRIORITY (90)
+
+/* Thread maximum priority (0 - 255). 0 - highest priority */
+#define IX_OSAL_OS_MAX_THREAD_PRIORITY (255)
+
+#endif /* FIXME */
+
+#define IX_OSAL_OS_WAIT_FOREVER (-1L)
+#define IX_OSAL_OS_WAIT_NONE 0
+
+
+/* Thread handle is eventually an int type */
+typedef int IxOsalOsThread;
+
+/* Semaphore handle FIXME */
+typedef int IxOsalOsSemaphore;
+
+/* Mutex handle */
+typedef int IxOsalOsMutex;
+
+/*
+ * Fast mutex handle - fast mutex operations are implemented in
+ * native assembler code using atomic test-and-set instructions
+ */
+typedef int IxOsalOsFastMutex;
+
+typedef struct
+{
+} IxOsalOsMessageQueue;
+
+
+#endif /* IxOsalOsTypes_H */
diff --git a/cpu/ixp/npe/include/IxOsalOsUtilitySymbols.h b/cpu/ixp/npe/include/IxOsalOsUtilitySymbols.h
new file mode 100644
index 0000000..beb45a0
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalOsUtilitySymbols.h
@@ -0,0 +1,4 @@
+#ifndef IxOsalOsUtilitySymbols_H
+#define IxOsalOsUtilitySymbols_H
+
+#endif /* IxOsalOsUtilitySymbols_H */
diff --git a/cpu/ixp/npe/include/IxOsalTypes.h b/cpu/ixp/npe/include/IxOsalTypes.h
new file mode 100644
index 0000000..c617ec5
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalTypes.h
@@ -0,0 +1,401 @@
+/**
+ * @file IxOsalTypes.h
+ *
+ * @brief Define OSAL basic data types.
+ *
+ * This file contains fundamental data types used by OSAL.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#ifndef IxOsalTypes_H
+#define IxOsalTypes_H
+
+#include <config.h>
+#include <common.h>
+
+#define __ixp42X /* sr: U-Boot needs this define */
+#define IXP425_EXP_CFG_BASE 0xC4000000
+#define diag_printf debug
+
+#undef SIMSPARCSOLARIS
+#define SIMSPARCSOLARIS 0xaffe /* sr: U-Boot gets confused with this solaris define */
+
+/*
+ * Include the OS-specific type definitions
+ */
+#include "IxOsalOsTypes.h"
+/**
+ * @defgroup IxOsalTypes Osal basic data types.
+ *
+ * @brief Basic data types for Osal
+ *
+ * @{
+ */
+
+/**
+ * @brief OSAL status
+ *
+ * @note Possible OSAL return status include IX_SUCCESS and IX_FAIL.
+ */
+typedef UINT32 IX_STATUS;
+
+/**
+ * @brief VUINT32
+ *
+ * @note volatile UINT32
+ */
+typedef volatile UINT32 VUINT32;
+
+/**
+ * @brief VINT32
+ *
+ * @note volatile INT32
+ */
+typedef volatile INT32 VINT32;
+
+
+#ifndef NUMELEMS
+#define NUMELEMS(x) (sizeof(x) / sizeof((x)[0]))
+#endif
+
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_BILLION
+ *
+ * @brief Alias for 1,000,000,000
+ *
+ */
+#define IX_OSAL_BILLION (1000000000)
+
+#ifndef TRUE
+#define TRUE 1L
+#endif
+
+#if TRUE != 1
+#error TRUE is not defined to 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0L
+#endif
+
+#if FALSE != 0
+#error FALSE is not defined to 0
+#endif
+
+#ifndef NULL
+#define NULL 0L
+#endif
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_SUCCESS
+ *
+ * @brief Success status
+ *
+ */
+#ifndef IX_SUCCESS
+#define IX_SUCCESS 0L /**< #defined as 0L */
+#endif
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_FAIL
+ *
+ * @brief Failure status
+ *
+ */
+#ifndef IX_FAIL
+#define IX_FAIL 1L /**< #defined as 1L */
+#endif
+
+
+#ifndef PRIVATE
+#ifdef IX_PRIVATE_OFF
+#define PRIVATE /* nothing */
+#else
+#define PRIVATE static /**< #defined as static, except for debug builds */
+#endif /* IX_PRIVATE_OFF */
+#endif /* PRIVATE */
+
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_INLINE
+ *
+ * @brief Alias for __inline
+ *
+ */
+#ifndef IX_OSAL_INLINE
+#define IX_OSAL_INLINE __inline
+#endif /* IX_OSAL_INLINE */
+
+
+#ifndef __inline__
+#define __inline__ IX_OSAL_INLINE
+#endif
+
+
+/* Each OS can define its own PUBLIC, otherwise it will be empty. */
+#ifndef PUBLIC
+#define PUBLIC
+#endif /* PUBLIC */
+
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_INLINE_EXTERN
+ *
+ * @brief Alias for __inline extern
+ *
+ */
+#ifndef IX_OSAL_INLINE_EXTERN
+#define IX_OSAL_INLINE_EXTERN IX_OSAL_INLINE extern
+#endif
+
+/**
+ * @ingroup IxOsalTypes
+ * @enum IxOsalLogDevice
+ * @brief This is an emum for OSAL log devices.
+ */
+typedef enum
+{
+ IX_OSAL_LOG_DEV_STDOUT = 0, /**< standard output (implemented by default) */
+ IX_OSAL_LOG_DEV_STDERR = 1, /**< standard error (implemented */
+ IX_OSAL_LOG_DEV_HEX_DISPLAY = 2, /**< hexadecimal display (not implemented) */
+ IX_OSAL_LOG_DEV_ASCII_DISPLAY = 3 /**< ASCII-capable display (not implemented) */
+} IxOsalLogDevice;
+
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_LOG_ERROR
+ *
+ * @brief Alias for -1, used as log function error status
+ *
+ */
+#define IX_OSAL_LOG_ERROR (-1)
+
+/**
+ * @ingroup IxOsalTypes
+ * @enum IxOsalLogLevel
+ * @brief This is an emum for OSAL log trace level.
+ */
+typedef enum
+{
+ IX_OSAL_LOG_LVL_NONE = 0, /**<No trace level */
+ IX_OSAL_LOG_LVL_USER = 1, /**<Set trace level to user */
+ IX_OSAL_LOG_LVL_FATAL = 2, /**<Set trace level to fatal */
+ IX_OSAL_LOG_LVL_ERROR = 3, /**<Set trace level to error */
+ IX_OSAL_LOG_LVL_WARNING = 4, /**<Set trace level to warning */
+ IX_OSAL_LOG_LVL_MESSAGE = 5, /**<Set trace level to message */
+ IX_OSAL_LOG_LVL_DEBUG1 = 6, /**<Set trace level to debug1 */
+ IX_OSAL_LOG_LVL_DEBUG2 = 7, /**<Set trace level to debug2 */
+ IX_OSAL_LOG_LVL_DEBUG3 = 8, /**<Set trace level to debug3 */
+ IX_OSAL_LOG_LVL_ALL /**<Set trace level to all */
+} IxOsalLogLevel;
+
+
+/**
+ * @ingroup IxOsalTypes
+ * @brief Void function pointer prototype
+ *
+ * @note accepts a void pointer parameter
+ * and does not return a value.
+ */
+typedef void (*IxOsalVoidFnVoidPtr) (void *);
+
+typedef void (*IxOsalVoidFnPtr) (void);
+
+
+/**
+ * @brief Timeval structure
+ *
+ * @note Contain subfields of seconds and nanoseconds..
+ */
+typedef struct
+{
+ UINT32 secs; /**< seconds */
+ UINT32 nsecs; /**< nanoseconds */
+} IxOsalTimeval;
+
+
+/**
+ * @ingroup IxOsalTypes
+ * @brief IxOsalTimer
+ *
+ * @note OSAL timer handle
+ *
+ */
+typedef UINT32 IxOsalTimer;
+
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_WAIT_FOREVER
+ *
+ * @brief Definition for timeout forever, OS-specific.
+ *
+ */
+#define IX_OSAL_WAIT_FOREVER IX_OSAL_OS_WAIT_FOREVER
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_WAIT_NONE
+ *
+ * @brief Definition for timeout 0, OS-specific.
+ *
+ */
+#define IX_OSAL_WAIT_NONE IX_OSAL_OS_WAIT_NONE
+
+
+/**
+ * @ingroup IxOsalTypes
+ * @brief IxOsalMutex
+ *
+ * @note Mutex handle, OS-specific
+ *
+ */
+typedef IxOsalOsMutex IxOsalMutex;
+
+/**
+ * @ingroup IxOsalTypes
+ * @brief IxOsalFastMutex
+ *
+ * @note FastMutex handle, OS-specific
+ *
+ */
+typedef IxOsalOsFastMutex IxOsalFastMutex;
+
+/**
+ * @ingroup IxOsalTypes
+ * @brief IxOsalThread
+ *
+ * @note Thread handle, OS-specific
+ *
+ */
+typedef IxOsalOsThread IxOsalThread;
+
+/**
+ * @ingroup IxOsalTypes
+ * @brief IxOsalSemaphore
+ *
+ * @note Semaphore handle, OS-specific
+ *
+ */
+typedef IxOsalOsSemaphore IxOsalSemaphore;
+
+/**
+ * @ingroup IxOsalTypes
+ * @brief IxOsalMessageQueue
+ *
+ * @note Message Queue handle, OS-specific
+ *
+ */
+typedef IxOsalOsMessageQueue IxOsalMessageQueue;
+
+
+/**
+ * @brief Thread Attribute
+ * @note Default thread attribute
+ */
+typedef struct
+{
+ char *name; /**< name */
+ UINT32 stackSize; /**< stack size */
+ UINT32 priority; /**< priority */
+} IxOsalThreadAttr;
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_THREAD_DEFAULT_STACK_SIZE
+ *
+ * @brief Default thread stack size, OS-specific.
+ *
+ */
+#define IX_OSAL_THREAD_DEFAULT_STACK_SIZE (IX_OSAL_OS_THREAD_DEFAULT_STACK_SIZE)
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_THREAD_MAX_STACK_SIZE
+ *
+ * @brief Max stack size, OS-specific.
+ *
+ */
+#define IX_OSAL_THREAD_MAX_STACK_SIZE (IX_OSAL_OS_THREAD_MAX_STACK_SIZE)
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_DEFAULT_THREAD_PRIORITY
+ *
+ * @brief Default thread priority, OS-specific.
+ *
+ */
+#define IX_OSAL_DEFAULT_THREAD_PRIORITY (IX_OSAL_OS_DEFAULT_THREAD_PRIORITY)
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_MAX_THREAD_PRIORITY
+ *
+ * @brief Max thread priority, OS-specific.
+ *
+ */
+#define IX_OSAL_MAX_THREAD_PRIORITY (IX_OSAL_OS_MAX_THREAD_PRIORITY)
+
+/**
+ * @} IxOsalTypes
+ */
+
+
+#endif /* IxOsalTypes_H */
diff --git a/cpu/ixp/npe/include/IxOsalUtilitySymbols.h b/cpu/ixp/npe/include/IxOsalUtilitySymbols.h
new file mode 100644
index 0000000..f2a73db
--- /dev/null
+++ b/cpu/ixp/npe/include/IxOsalUtilitySymbols.h
@@ -0,0 +1,51 @@
+/**
+ * @file
+ *
+ * @brief OSAL Configuration header file
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsalUtilitySymbols_H
+#define IxOsalUtilitySymbols_H
+
+#include "IxOsalOsUtilitySymbols.h" /* OS-specific utility symbol definitions */
+
+#endif /* IxOsalUtilitySymbols_H */
diff --git a/cpu/ixp/npe/include/IxParityENAcc.h b/cpu/ixp/npe/include/IxParityENAcc.h
new file mode 100644
index 0000000..62fe171
--- /dev/null
+++ b/cpu/ixp/npe/include/IxParityENAcc.h
@@ -0,0 +1,785 @@
+/**
+ * @file IxParityENAcc.h
+ *
+ * @author Intel Corporation
+ * @date 24 Mar 2004
+ *
+ * @brief This file contains the public API for the IXP400 Parity Error
+ * Notifier access component.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxParityENAcc IXP400 Parity Error Notifier (IxParityENAcc) API
+ *
+ * @brief The public API for the Parity Error Notifier
+ *
+ * @{
+ */
+
+#ifndef IXPARITYENACC_H
+#define IXPARITYENACC_H
+
+#ifdef __ixp46X
+
+#include "IxOsal.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @enum IxParityENAccStatus
+ *
+ * @brief The status as returend from the API
+ */
+typedef enum /**< IxParityENAccStatus */
+{
+ IX_PARITYENACC_SUCCESS = IX_SUCCESS, /**< The request is successful */
+ IX_PARITYENACC_INVALID_PARAMETERS, /**< Invalid or NULL parameters passed */
+ IX_PARITYENACC_NOT_INITIALISED, /**< Access layer has not been initialised before accessing the APIs */
+ IX_PARITYENACC_ALREADY_INITIALISED, /**< Access layer has already been initialised */
+ IX_PARITYENACC_OPERATION_FAILED, /**< Operation did not succeed due to hardware failure */
+ IX_PARITYENACC_NO_PARITY /**< No parity condition exits or has already been cleared */
+} IxParityENAccStatus;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @enum IxParityENAccParityType
+ *
+ * @brief Odd or Even Parity Type
+ */
+typedef enum /**< IxParityENAccParityType */
+{
+ IX_PARITYENACC_EVEN_PARITY, /**< Even Parity */
+ IX_PARITYENACC_ODD_PARITY /**< Odd Parity */
+} IxParityENAccParityType;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @enum IxParityENAccConfigOption
+ *
+ * @brief The parity error enable/disable configuration option
+ */
+typedef enum /**< IxParityENAccConfigOption */
+{
+ IX_PARITYENACC_DISABLE, /**< Disable parity error detection */
+ IX_PARITYENACC_ENABLE /**< Enable parity error detection */
+} IxParityENAccConfigOption;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccNpeConfig
+ *
+ * @brief NPE parity detection is to be enabled/disabled
+ */
+typedef struct /**< IxParityENAccNpeConfig */
+{
+ IxParityENAccConfigOption ideEnabled; /**< NPE IMem, DMem and External */
+ IxParityENAccParityType parityOddEven; /**< Parity - Odd or Even */
+} IxParityENAccNpeConfig ;
+
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccMcuConfig
+ *
+ * @brief MCU pairty detection is to be enabled/disabled
+ */
+typedef struct /**< IxParityENAccMcuConfig */
+{
+ IxParityENAccConfigOption singlebitDetectEnabled; /**< Single-bit parity error detection */
+ IxParityENAccConfigOption singlebitCorrectionEnabled; /**< Single-bit parity error correction */
+ IxParityENAccConfigOption multibitDetectionEnabled; /**< Multi-bit parity error detection */
+} IxParityENAccMcuConfig ;
+
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccEbcConfig
+ *
+ * @brief Expansion Bus Controller parity detection is to be enabled or disabled
+ *
+ * Note: All the Chip Select(s) and External Masters will have the same parity
+ */
+typedef struct /**< IxParityENAccEbcConfig */
+{
+ IxParityENAccConfigOption ebcCs0Enabled; /**< Expansion Bus Controller - Chip Select 0 */
+ IxParityENAccConfigOption ebcCs1Enabled; /**< Expansion Bus Controller - Chip Select 1 */
+ IxParityENAccConfigOption ebcCs2Enabled; /**< Expansion Bus Controller - Chip Select 2 */
+ IxParityENAccConfigOption ebcCs3Enabled; /**< Expansion Bus Controller - Chip Select 3 */
+ IxParityENAccConfigOption ebcCs4Enabled; /**< Expansion Bus Controller - Chip Select 4 */
+ IxParityENAccConfigOption ebcCs5Enabled; /**< Expansion Bus Controller - Chip Select 5 */
+ IxParityENAccConfigOption ebcCs6Enabled; /**< Expansion Bus Controller - Chip Select 6 */
+ IxParityENAccConfigOption ebcCs7Enabled; /**< Expansion Bus Controller - Chip Select 7 */
+ IxParityENAccConfigOption ebcExtMstEnabled; /**< External Master on Expansion bus */
+ IxParityENAccParityType parityOddEven; /**< Parity - Odd or Even */
+} IxParityENAccEbcConfig ;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccHWParityConfig
+ *
+ * @brief Parity error configuration of the Hardware Blocks
+ */
+typedef struct /**< IxParityENAccHWParityConfig */
+{
+ IxParityENAccNpeConfig npeAConfig; /**< NPE A parity detection is to be enabled/disabled */
+ IxParityENAccNpeConfig npeBConfig; /**< NPE B parity detection is to be enabled/disabled */
+ IxParityENAccNpeConfig npeCConfig; /**< NPE C parity detection is to be enabled/disabled */
+ IxParityENAccMcuConfig mcuConfig; /**< MCU pairty detection is to be enabled/disabled */
+ IxParityENAccConfigOption swcpEnabled; /**< SWCP parity detection is to be enabled */
+ IxParityENAccConfigOption aqmEnabled; /**< AQM parity detection is to be enabled */
+ IxParityENAccEbcConfig ebcConfig; /**< Expansion Bus Controller parity detection is to be enabled/disabled */
+} IxParityENAccHWParityConfig;
+
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccNpeParityErrorStats
+ *
+ * @brief NPE parity error statistics
+ */
+typedef struct /* IxParityENAccNpeParityErrorStats */
+{
+ UINT32 parityErrorsIMem; /**< Parity errors in Instruction Memory */
+ UINT32 parityErrorsDMem; /**< Parity errors in Data Memory */
+ UINT32 parityErrorsExternal; /**< Parity errors in NPE External Entities */
+} IxParityENAccNpeParityErrorStats;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccMcuParityErrorStats
+ *
+ * @brief DDR Memory Control Unit parity error statistics
+ *
+ * Note: There could be two outstanding parity errors at any given time whose address
+ * details captured. If there is no room for the new interrupt then it would be treated
+ * as overflow parity condition.
+ */
+typedef struct /* IxParityENAccMcuParityErrorStats */
+{
+ UINT32 parityErrorsSingleBit; /**< Parity errors of the type Single-Bit */
+ UINT32 parityErrorsMultiBit; /**< Parity errors of the type Multi-Bit */
+ UINT32 parityErrorsOverflow; /**< Parity errors when more than two parity errors occured */
+} IxParityENAccMcuParityErrorStats;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccEbcParityErrorStats
+ *
+ * @brief Expansion Bus Controller parity error statistics
+ */
+typedef struct /* IxParityENAccEbcParityErrorStats */
+{
+ UINT32 parityErrorsInbound; /**< Odd bit parity errors on inbound transfers */
+ UINT32 parityErrorsOutbound; /**< Odd bit parity errors on outbound transfers */
+} IxParityENAccEbcParityErrorStats;
+
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccParityErrorStats
+ *
+ * @brief Parity Error Statistics for the all the hardware blocks
+ */
+typedef struct /**< IxParityENAccParityErrorStats */
+{
+ IxParityENAccNpeParityErrorStats npeStats; /**< NPE parity error statistics */
+ IxParityENAccMcuParityErrorStats mcuStats; /**< MCU parity error statistics */
+ IxParityENAccEbcParityErrorStats ebcStats; /**< EBC parity error statistics */
+ UINT32 swcpStats; /**< SWCP parity error statistics */
+ UINT32 aqmStats; /**< AQM parity error statistics */
+} IxParityENAccParityErrorStats;
+
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @enum IxParityENAccParityErrorSource
+ *
+ * @brief The source of the parity error notification
+ */
+typedef enum /**< IxParityENAccParityErrorSource */
+{
+ IX_PARITYENACC_NPE_A_IMEM, /**< NPE A - Instruction memory */
+ IX_PARITYENACC_NPE_A_DMEM, /**< NPE A - Data memory */
+ IX_PARITYENACC_NPE_A_EXT, /**< NPE A - External Entity*/
+ IX_PARITYENACC_NPE_B_IMEM, /**< NPE B - Instruction memory */
+ IX_PARITYENACC_NPE_B_DMEM, /**< NPE B - Data memory */
+ IX_PARITYENACC_NPE_B_EXT, /**< NPE B - External Entity*/
+ IX_PARITYENACC_NPE_C_IMEM, /**< NPE C - Instruction memory */
+ IX_PARITYENACC_NPE_C_DMEM, /**< NPE C - Data memory */
+ IX_PARITYENACC_NPE_C_EXT, /**< NPE C - External Entity*/
+ IX_PARITYENACC_SWCP, /**< SWCP */
+ IX_PARITYENACC_AQM, /**< AQM */
+ IX_PARITYENACC_MCU_SBIT, /**< DDR Memory Controller Unit - Single bit parity */
+ IX_PARITYENACC_MCU_MBIT, /**< DDR Memory Controller Unit - Multi bit parity */
+ IX_PARITYENACC_MCU_OVERFLOW, /**< DDR Memory Controller Unit - Parity errors in excess of two */
+ IX_PARITYENACC_EBC_CS, /**< Expansion Bus Controller - Chip Select */
+ IX_PARITYENACC_EBC_EXTMST /**< Expansion Bus Controller - External Master */
+} IxParityENAccParityErrorSource;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @enum IxParityENAccParityErrorAccess
+ *
+ * @brief The type of access resulting in parity error
+ */
+typedef enum /**< IxParityENAccParityErrorAccess */
+{
+ IX_PARITYENACC_READ, /**< Read Access */
+ IX_PARITYENACC_WRITE /**< Write Access */
+} IxParityENAccParityErrorAccess;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @typedef IxParityENAccParityErrorAddress
+ *
+ * @brief The memory location which has parity error
+ */
+typedef UINT32 IxParityENAccParityErrorAddress;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @typedef IxParityENAccParityErrorData
+ *
+ * @brief The data read from the memory location which has parity error
+ */
+typedef UINT32 IxParityENAccParityErrorData;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @enum IxParityENAccParityErrorRequester
+ *
+ * @brief The requester interface through which the SDRAM memory access
+ * resulted in the parity error.
+ */
+typedef enum /**< IxParityENAccParityErrorRequester */
+{
+ IX_PARITYENACC_MPI, /**< Direct Memory Port Interface */
+ IX_PARITYENACC_AHB_BUS /**< South or North AHB Bus */
+} IxParityENAccParityErrorRequester;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @enum IxParityENAccAHBErrorMaster
+ *
+ * @brief The Master on the AHB bus interface whose transaction might have
+ * resulted in the parity error notification to XScale.
+ */
+typedef enum /**< IxParityENAccAHBErrorMaster */
+{
+ IX_PARITYENACC_AHBN_MST_NPE_A, /**< NPE - A */
+ IX_PARITYENACC_AHBN_MST_NPE_B, /**< NPE - B */
+ IX_PARITYENACC_AHBN_MST_NPE_C, /**< NPE - C */
+ IX_PARITYENACC_AHBS_MST_XSCALE, /**< XScale Bus Interface Unit */
+ IX_PARITYENACC_AHBS_MST_PBC, /**< PCI Bus Controller */
+ IX_PARITYENACC_AHBS_MST_EBC, /**< Expansion Bus Controller */
+ IX_PARITYENACC_AHBS_MST_AHB_BRIDGE, /**< AHB Bridge */
+ IX_PARITYENACC_AHBS_MST_USBH /**< USB Host Controller */
+} IxParityENAccAHBErrorMaster;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @enum IxParityENAccAHBErrorSlave
+ *
+ * @brief The Slave on the AHB bus interface whose transaction might have
+ * resulted in the parity error notification to XScale.
+ */
+typedef enum /**< IxParityENAccAHBErrorSlave */
+{
+ IX_PARITYENACC_AHBN_SLV_MCU, /**< Memory Control Unit */
+ IX_PARITYENACC_AHBN_SLV_AHB_BRIDGE, /**< AHB Bridge */
+ IX_PARITYENACC_AHBS_SLV_MCU, /**< XScale Bus Interface Unit */
+ IX_PARITYENACC_AHBS_SLV_APB_BRIDGE, /**< APB Bridge */
+ IX_PARITYENACC_AHBS_SLV_AQM, /**< AQM */
+ IX_PARITYENACC_AHBS_SLV_RSA, /**< RSA (Crypto Bus) */
+ IX_PARITYENACC_AHBS_SLV_PBC, /**< PCI Bus Controller */
+ IX_PARITYENACC_AHBS_SLV_EBC, /**< Expansion Bus Controller */
+ IX_PARITYENACC_AHBS_SLV_USBH /**< USB Host Controller */
+} IxParityENAccAHBErrorSlave;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccAHBErrorTransaction
+ *
+ * @brief The Master and Slave on the AHB bus interface whose transaction might
+ * have resulted in the parity error notification to XScale.
+ *
+ * NOTE: This information may be used in the data abort exception handler
+ * to differentiate between the XScale and non-XScale access to the SDRAM
+ * memory.
+ */
+typedef struct /**< IxParityENAccAHBErrorTransaction */
+{
+ IxParityENAccAHBErrorMaster ahbErrorMaster; /**< Master on AHB bus */
+ IxParityENAccAHBErrorSlave ahbErrorSlave; /**< Slave on AHB bus */
+} IxParityENAccAHBErrorTransaction;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccParityErrorContextMessage
+ *
+ * @brief Parity Error Context Message
+ */
+typedef struct /**< IxParityENAccParityErrorContextMessage */
+{
+ IxParityENAccParityErrorSource pecParitySource; /**< Source info of parity error */
+ IxParityENAccParityErrorAccess pecAccessType; /**< Read or Write Access
+ Read - NPE, SWCP, AQM, DDR MCU,
+ Exp Bus Ctrlr (Outbound)
+ Write - DDR MCU,
+ Exp Bus Ctrlr (Inbound
+ i.e., External Master) */
+ IxParityENAccParityErrorAddress pecAddress; /**< Address faulty location
+ Valid only for AQM, DDR MCU,
+ Exp Bus Ctrlr */
+ IxParityENAccParityErrorData pecData; /**< Data read from the faulty location
+ Valid only for AQM and DDR MCU
+ For DDR MCU it is the bit location
+ of the Single-bit parity */
+ IxParityENAccParityErrorRequester pecRequester; /**< Requester of SDRAM memory access
+ Valid only for the DDR MCU */
+ IxParityENAccAHBErrorTransaction ahbErrorTran; /**< Master and Slave information on the
+ last AHB Error Transaction */
+} IxParityENAccParityErrorContextMessage;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @typedef IxParityENAccCallback
+ *
+ * @brief This prototype shows the format of a callback function.
+ *
+ * The callback will be used to notify the parity error to the client application.
+ * The callback will be registered by @ref ixParityENAccCallbackRegister.
+ *
+ * It will be called from an ISR when a parity error is detected and thus
+ * needs to follow the interrupt callable function conventions.
+ *
+ */
+typedef void (*IxParityENAccCallback) (void);
+
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccInit(void)
+ *
+ * @brief This function will initialise the IxParityENAcc component.
+ *
+ * This function will initialise the IxParityENAcc component. It should only be
+ * called once, prior to using the IxParityENAcc component.
+ *
+ * <OL><LI>It initialises the internal data structures, registers the ISR that
+ * will be triggered when a parity error occurs in IXP4xx silicon.</LI></OL>
+ *
+ * @li Re-entrant : No
+ * @li ISR Callable : No
+ *
+ * @return @li IX_PARITYENACC_SUCCESS - Initialization is successful
+ * @li IX_PARITYENACC_ALREADY_INITIALISED - The access layer has already
+ * been initialized
+ * @li IX_PARITYENACC_OPERATION_FAILED - The request failed because the
+ * operation didn't succeed on the hardware. Refer to error trace/log
+ * for details.
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccInit(void);
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccCallbackRegister (
+ IxParityENAccCallback parityErrNfyCallBack)
+ *
+ * @brief This function will register a new callback with IxParityENAcc component.
+ * It can also reregister a new callback replacing the old callback.
+ *
+ * @param parityErrNfyCallBack [in] - This parameter will specify the call-back
+ * function supplied by the client application.
+ *
+ * This interface registers the user application supplied call-back handler with
+ * the parity error handling access component after the init.
+ *
+ * The callback function will be called from an ISR that will be triggered by the
+ * parity error in the IXP400 silicon.
+ *
+ * The following actions will be performed by this function:
+ * <OL><LI>Check for the prior initialisation of the module before registering or
+ * re-registering of the callback.
+ * Check for parity error detection disabled before re-registration of the callback.
+ * </LI></OL>
+ *
+ * @li Re-entrant : No
+ * @li ISR Callable : No
+ *
+ * @return @li IX_PARITYENACC_SUCCESS - The parameters check passed and the
+ * registration is successful.
+ * @li IX_PARITYENACC_INVALID_PARAMETERS - Request failed due to NULL
+ * parameter passed.
+ * @li IX_PARITYENACC_OPERATION_FAILED - The request failed because the
+ * parity error detection not yet disabled.
+ * @li IX_PARITYENACC_NOT_INITIALISED - The operation requested prior to
+ * the initialisation of the access layer.
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccCallbackRegister (
+ IxParityENAccCallback parityErrNfyCallBack);
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccParityDetectionConfigure (
+ const IxParityENAccHWParityConfig *hwParityConfig)
+ *
+ * @brief This interface allows the client application to enable the parity
+ * error detection on the underlying hardware block.
+ *
+ * @param hwParityConfig [in] - Hardware blocks for which the parity error
+ * detection is to be enabled or disabled.
+ *
+ * The client application allocates and provides the reference to the buffer.
+ *
+ * It will also verify whether the specific hardware block is functional or not.
+ *
+ * NOTE: Failure in enabling or disabling of one or more components result in
+ * trace message but still returns IX_PARITYENACC_SUCCESS. Refer to the function
+ * @ref ixParityENAccParityDetectionQuery on how to verify the failures while
+ * enabling/disabling paritys error detection.
+ *
+ * It shall be invoked after the Init and CallbackRegister functions but before
+ * any other function of the IxParityENAcc layer.
+ *
+ * @li Re-entrant : No
+ * @li ISR Callable : No
+ *
+ * @return @li IX_PARITYENACC_SUCCESS - The parameters check passed and the
+ * request to enable/disable is successful.
+ * @li IX_PARITYENACC_INVALID_PARAMETERS-The request failed due to
+ * NULL parameter supplied.
+ * @li IX_PARITYENACC_OPERATION_FAILED - The request failed because the
+ * operation didn't succeed on the hardware.
+ * @li IX_PARITYENACC_NOT_INITIALISED - The operation requested prior to
+ * the initialisation of the access layer.
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccParityDetectionConfigure (
+ const IxParityENAccHWParityConfig *hwParityConfig);
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccParityDetectionQuery (
+ IxParityENAccHWParityConfig * const hwParityConfig)
+ *
+ * @brief This interface allows the client application to determine the
+ * status of the parity error detection on the specified hardware blocks
+ *
+ * @param hwParityConfig [out] - Hardware blocks whose parity error detection
+ * has been enabled or disabled.
+ *
+ * The client application allocates and provides the reference to the buffer.
+ *
+ * This interface can be used immediately after the interface @ref
+ * ixParityENAccParityDetectionConfigure to see on which of the hardware blocks
+ * the parity error detection has either been enabled or disabled based on the
+ * client application request.
+ *
+ * @li Re-entrant : No
+ * @li ISR Callable : No
+ *
+ * @return @li IX_PARITYENACC_SUCCESS - The parameters check passed and the
+ * request to query on whether the hardware parity error detection
+ * is enabled or disabled is successful.
+ * @li IX_PARITYENACC_INVALID_PARAMETERS-The request failed due to
+ * NULL parameter or invalid values supplied.
+ * @li IX_PARITYENACC_NOT_INITIALISED - The operation requested prior
+ * to the initialisation of the access layer.
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccParityDetectionQuery(
+ IxParityENAccHWParityConfig * const hwParityConfig);
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccParityErrorContextGet(
+ IxParityENAccParityErrorContextMessage * const pecMessage)
+ *
+ * @brief This interface allows the client application to determine the
+ * status of the parity error context on hardware block for which the
+ * current parity error interrupt triggered.
+ *
+ * @param pecMessage [out] - The parity error context information of the
+ * parity interrupt currently being process.
+ *
+ * The client application allocates and provides the reference to the buffer.
+ *
+ * Refer to the data structure @ref IxParityENAccParityErrorContextMessage
+ * for details.
+ *
+ * The routine will will fetch the parity error context in the following
+ * priority, if multiple parity errors observed.
+ *
+ * <pre>
+ * 0 - MCU (Multi-bit and single-bit in that order)
+ * 1 - NPE-A
+ * 2 - NPE-B
+ * 3 - NPE-C
+ * 4 - SWCP
+ * 5 - QM
+ * 6 - EXP
+ *
+ * NOTE: The information provided in the @ref IxParityENAccAHBErrorTransaction
+ * may be of help for the client application to decide on the course of action
+ * to take. This info is taken from the Performance Monitoring Unit register
+ * which records most recent error observed on the AHB bus. This information
+ * might have been overwritten by some other error by the time it is retrieved.
+ * </pre>
+ *
+ * @li Re-entrant : No
+ * @li ISR Callable : Yes
+ *
+ * @return @li IX_PARITYENACC_SUCCESS-The parameters check passed and the
+ * request to get the parity error context information is successful.
+ * @li IX_PARITYENACC_INVALID_PARAMETERS-The request failed due to
+ * NULL parameter is passed
+ * @li IX_PARITYENACC_OPERATION_FAILED - The request failed because
+ * the operation didn't succeed on the hardware.
+ * @li IX_PARITYENACC_NOT_INITIALISED - The operation requested prior
+ * to the initialisation of the access layer.
+ * @li IX_PARITYENACC_NO_PARITY - No parity condition exits or has
+ * already been cleared
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccParityErrorContextGet(
+ IxParityENAccParityErrorContextMessage * const pecMessage);
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccParityErrorInterruptClear (
+ const IxParityENAccParityErrorContextMessage *pecMessage)
+ *
+ * @brief This interface helps the client application to clear off the
+ * interrupt condition on the hardware block identified in the parity
+ * error context message. Please refer to the table below as the operation
+ * varies depending on the interrupt source.
+ *
+ * @param pecMessage [in] - The parity error context information of the
+ * hardware block whose parity error interrupt condition is to disabled.
+ *
+ * The client application allocates and provides the reference to the buffer.
+ *
+ * <pre>
+ * ****************************************************************************
+ * Following actions will be taken during the interrupt clear for respective
+ * hardware blocks.
+ *
+ * Parity Source Actions taken during Interrupt clear
+ * ------------- -------------------------------------------------------
+ * NPE-A Interrupt will be masked off at the interrupt controller
+ * so that it will not trigger continuously.
+ * Client application has to take appropriate action and
+ * re-configure the parity error detection subsequently.
+ * The client application will not be notified of further
+ * interrupts, until the re-configuration is done using
+ * @ref ixParityENAccParityDetectionConfigure.
+ *
+ * NPE-B Interrupt will be masked off at the interrupt controller
+ * so that it will not trigger continuously.
+ * Client application has to take appropriate action and
+ * re-configure the parity error detection subsequently.
+ * The client application will not be notified of further
+ * interrupts, until the re-configuration is done using
+ * @ref ixParityENAccParityDetectionConfigure.
+ *
+ * NPE-C Interrupt will be masked off at the interrupt controller
+ * Client application has to take appropriate action and
+ * re-configure the parity error detection subsequently.
+ * The client application will not be notified of further
+ * interrupts, until the re-configuration is done using
+ * @ref ixParityENAccParityDetectionConfigure.
+ *
+ * SWCP Interrupt will be masked off at the interrupt controller.
+ * Client application has to take appropriate action and
+ * re-configure the parity error detection subsequently.
+ * The client application will not be notified of further
+ * interrupts, until the re-configuration is done using
+ * @ref ixParityENAccParityDetectionConfigure.
+ *
+ * AQM Interrupt will be masked off at the interrupt controller.
+ * Client application has to take appropriate action and
+ * re-configure the parity error detection subsequently.
+ * The client application will not be notified of further
+ * interrupts, until the re-configuration is done using
+ * @ref ixParityENAccParityDetectionConfigure.
+ *
+ * MCU Parity interrupt condition is cleared at the SDRAM MCU for
+ * the following:
+ * 1. Single-bit
+ * 2. Multi-bit
+ * 3. Overflow condition i.e., more than two parity conditions
+ * occurred
+ * Note that single-parity errors do not result in data abort
+ * and not all data aborts caused by multi-bit parity error.
+ *
+ * EXP Parity interrupt condition is cleared at the expansion bus
+ * controller for the following:
+ * 1. External master initiated Inbound write
+ * 2. Internal master (IXP400) initiated Outbound read
+ * ****************************************************************************
+ * </pre>
+ * @li Re-entrant : No
+ * @li ISR Callable : No
+ *
+ * @return @li IX_PARITYENACC_SUCCESS-The parameters check passed and the request
+ * to clear the parity error interrupt condition is successful.
+ * @li IX_PARITYENACC_INVALID_PARAMETERS-The request failed due to
+ * NULL parameters have been passed or contents have been
+ * supplied with invalid values.
+ * @li IX_PARITYENACC_OPERATION_FAILED - The request failed because
+ * the operation didn't succeed on the hardware.
+ * @li IX_PARITYENACC_NOT_INITIALISED - The operation requested prior
+ * to the initialisation of the access layer.
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccParityErrorInterruptClear (
+ const IxParityENAccParityErrorContextMessage *pecMessage);
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccStatsGet (
+ IxParityENAccParityErrorStats * const ixParityErrorStats)
+ *
+ * @brief This interface allows the client application to retrieve parity
+ * error statistics for all the hardware blocks
+ *
+ * @param ixParityErrorStats - [out] The statistics for all the hardware blocks.
+ *
+ * The client application allocates and provides the reference to the buffer.
+ *
+ * @li Re-entrant : No
+ * @li ISR Callable : Yes
+ *
+ * @return @li IX_PARITYENACC_SUCCESS-The parameters check passed and the
+ * request to retrieve parity error statistics for the hardware
+ * block is successful.
+ * @li IX_PARITYENACC_INVALID_PARAMETERS-The request failed due to a
+ * NULL parameter passed.
+ * @li IX_PARITYENACC_NOT_INITIALISED - The operation requested prior
+ * to the initialisation of the access layer.
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccStatsGet (
+ IxParityENAccParityErrorStats * const ixParityErrorStats);
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccStatsShow (void)
+ *
+ * @brief This interface allows the client application to print all the
+ * parity error statistics.
+ *
+ * @li Re-entrant : No
+ * @li ISR Callable : No
+ *
+ * @return @li IX_PARITYENACC_SUCCESS - The request to show the pairty
+ * error statistics is successful.
+ * @li IX_PARITYENACC_NOT_INITIALISED - The operation requested
+ * prior to the initialisation of the access layer.
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccStatsShow (void);
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccStatsReset (void)
+ *
+ * @brief This interface allows the client application to reset all the
+ * parity error statistics.
+ *
+ * @li Re-entrant : No
+ * @li ISR Callable : No
+ *
+ * @return @li IX_PARITYENACC_SUCCESS - The request to reset the parity
+ * error statistics is successful.
+ * @li IX_PARITYENACC_NOT_INITIALISED - The operation requested
+ * prior to the initialisation of the access layer.
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccStatsReset (void);
+
+#endif /* IXPARITYENACC_H */
+#endif /* __ixp46X */
+
+/**
+ * @} defgroup IxParityENAcc
+ */
+
diff --git a/cpu/ixp/npe/include/IxPerfProfAcc.h b/cpu/ixp/npe/include/IxPerfProfAcc.h
new file mode 100644
index 0000000..65c0ba9
--- /dev/null
+++ b/cpu/ixp/npe/include/IxPerfProfAcc.h
@@ -0,0 +1,1358 @@
+/**
+ * @file IxPerfProfAcc.h
+ *
+ * @brief Header file for the IXP400 Perf Prof component (IxPerfProfAcc)
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxPerfProfAcc IXP400 Performance Profiling (IxPerfProfAcc) API
+ *
+ * @brief IXP400 Performance Profiling Utility component Public API.
+ * @li NOTE: Xcycle measurement is not supported in Linux.
+ *
+ *
+ * @{
+ */
+#ifndef IXPERFPROFACC_H
+#define IXPERFPROFACC_H
+
+#include "IxOsal.h"
+
+#ifdef __linux
+#include <linux/proc_fs.h>
+#endif
+
+/*
+ * Section for #define
+ */
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @def IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES
+ *
+ * @brief This is the maximum number of profiling samples allowed, which can be
+ * modified according to the user's discretion
+ */
+#define IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES 0xFFFF
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @def IX_PERFPROF_ACC_BUS_PMU_MAX_PECS
+ *
+ * @brief This is the maximum number of Programmable Event Counters available.
+ * This is a hardware specific and fixed value. Do not change.
+ *
+ */
+#define IX_PERFPROF_ACC_BUS_PMU_MAX_PECS 7
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @def IX_PERFPROF_ACC_XCYCLE_MAX_NUM_OF_MEASUREMENTS
+ *
+ * @brief Max number of measurement allowed. This constant is used when
+ * creating storage array for Xcycle. When run in continuous mode,
+ * Xcycle will wrap around and re-use buffer.
+ */
+#define IX_PERFPROF_ACC_XCYCLE_MAX_NUM_OF_MEASUREMENTS 600
+
+#ifdef __linux
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @def IX_PERFPROF_ACC_XSCALE_PMU_SYMBOL_ACCURACY
+ *
+ * @brief Level of accuracy required for matching the PC Address to
+ * symbol address. This is used when the XScale PMU time/event
+ * sampling functions get the PC address and search for the
+ * corresponding symbol address.
+ */
+#define IX_PERFPROF_ACC_XSCALE_PMU_SYMBOL_ACCURACY 0xffff
+
+#endif /*__linux*/
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @def IX_PERFPROF_ACC_LOG
+ *
+ * @brief Mechanism for logging a formatted message for the PerfProfAcc component
+ *
+ * @param level UINT32 [in] - trace level
+ * @param device UINT32 [in] - output device
+ * @param str char* [in] - format string, similar to printf().
+ * @param a UINT32 [in] - first argument to display
+ * @param b UINT32 [in] - second argument to display
+ * @param c UINT32 [in] - third argument to display
+ * @param d UINT32 [in] - fourth argument to display
+ * @param e UINT32 [in] - fifth argument to display
+ * @param f UINT32 [in] - sixth argument to display
+ *
+ * @return none
+ */
+#ifndef NDEBUG
+#define IX_PERFPROF_ACC_LOG(level, device, str, a, b, c, d, e, f)\
+ (ixOsalLog (level, device, str, a, b, c, d, e, f))
+#else /*do nothing*/
+#define IX_PERFPROF_ACC_LOG(level, device, str, a, b, c, d, e, f)
+#endif /*ifdef NDEBUG */
+
+/*
+ * Section for struct
+ */
+
+/**
+ * @brief contains summary of samples taken
+ *
+ * Structure contains all details of each program counter value - frequency
+ * that PC occurs
+ */
+typedef struct
+{
+ UINT32 programCounter; /**<the program counter value of the sample*/
+ UINT32 freq; /**<the frequency of the occurence of the sample*/
+} IxPerfProfAccXscalePmuSamplePcProfile;
+
+/**
+ * @brief contains results of a counter
+ *
+ * Structure contains the results of a counter, which are split into the lower
+ * and upper 32 bits of the final count
+ */
+typedef struct
+{
+ UINT32 lower32BitsEventCount; /**<lower 32bits value of the event counter*/
+ UINT32 upper32BitsEventCount; /**<upper 32bits value of the event counter*/
+} IxPerfProfAccXscalePmuEvtCnt;
+
+/**
+ * @brief contains results of counters and their overflow
+ *
+ * Structure contains all values of counters and associated overflows. The
+ * specific event and clock counters are determined by the user
+ */
+typedef struct
+{
+ UINT32 clk_value; /**<current value of clock counter*/
+ UINT32 clk_samples; /**<number of clock counter overflows*/
+ UINT32 event1_value; /**<current value of event 1 counter*/
+ UINT32 event1_samples; /**<number of event 1 counter overflows*/
+ UINT32 event2_value; /**<current value of event 2 counter*/
+ UINT32 event2_samples; /**<number of event 2 counter overflows*/
+ UINT32 event3_value; /**<current value of event 3 counter*/
+ UINT32 event3_samples; /**<number of event 3 counter overflows*/
+ UINT32 event4_value; /**<current value of event 4 counter*/
+ UINT32 event4_samples; /**<number of event 4 counter overflows*/
+} IxPerfProfAccXscalePmuResults;
+
+/**
+ *
+ * @brief Results obtained from Xcycle run
+ */
+typedef struct
+{
+ float maxIdlePercentage; /**<maximum percentage of Idle cycles*/
+ float minIdlePercentage; /**<minimum percentage of Idle cycles*/
+ float aveIdlePercentage; /**<average percentage of Idle cycles*/
+ UINT32 totalMeasurements; /**<total number of measurement made */
+} IxPerfProfAccXcycleResults;
+
+/**
+ *
+ * @brief Results obtained from running the Bus Pmu component. The results
+ * are obtained when the get functions is called.
+ *
+ */
+typedef struct
+{
+ UINT32 statsToGetLower27Bit[IX_PERFPROF_ACC_BUS_PMU_MAX_PECS]; /**<Lower 27 Bit of counter value */
+ UINT32 statsToGetUpper32Bit[IX_PERFPROF_ACC_BUS_PMU_MAX_PECS]; /**<Upper 32 Bit of counter value */
+} IxPerfProfAccBusPmuResults;
+
+/*
+ * Section for enum
+ */
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @enum IxPerfProfAccBusPmuEventCounters1
+ *
+ * @brief Type of bus pmu events supported on PEC 1.
+ *
+ * Lists all bus pmu events.
+ */
+typedef enum
+{
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_NORTH_NPEA_GRANT_SELECT = 1, /**< Select North NPEA grant on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_NORTH_NPEB_GRANT_SELECT, /**< Select North NPEB grant on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_NORTH_NPEC_GRANT_SELECT, /**< Select North NPEC grant on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_NORTH_BUS_IDLE_SELECT, /**< Select North bus idle on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_NORTH_NPEA_REQ_SELECT, /**< Select North NPEA req on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_NORTH_NPEB_REQ_SELECT, /**< Select North NPEB req on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_NORTH_NPEC_REQ_SELECT, /**< Select North NPEC req on PEC1*/
+
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_SOUTH_GSKT_GRANT_SELECT, /**< Select south gasket grant on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_SOUTH_ABB_GRANT_SELECT, /**< Select south abb grant on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_SOUTH_PCI_GRANT_SELECT, /**< Select south pci grant on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_SOUTH_APB_GRANT_SELECT, /**< Select south apb grant on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_SOUTH_GSKT_REQ_SELECT, /**< Select south gasket request on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_SOUTH_ABB_REQ_SELECT, /**< Select south abb request on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_SOUTH_PCI_REQ_SELECT, /**< Select south pci request on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_SOUTH_APB_REQ_SELECT, /**< Select south apb request on PEC1*/
+
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_SDR_0_HIT_SELECT, /**< Select sdram0 hit on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_SDR_1_HIT_SELECT, /**< Select sdram1 hit on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_SDR_2_HIT_SELECT, /**< Select sdram2 hit on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_SDR_3_HIT_SELECT, /**< Select sdram3 hit on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_SDR_4_MISS_SELECT, /**< Select sdram4 miss on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_SDR_5_MISS_SELECT, /**< Select sdram5 miss on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_SDR_6_MISS_SELECT, /**< Select sdram6 miss on PEC1*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC1_SDR_7_MISS_SELECT /**< Select sdram7 miss on PEC1*/
+} IxPerfProfAccBusPmuEventCounters1;
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @enum IxPerfProfAccBusPmuEventCounters2
+ *
+ * @brief Type of bus pmu events supported on PEC 2.
+ *
+ * Lists all bus pmu events.
+ */
+typedef enum
+{
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_NORTH_NPEA_XFER_SELECT = 24, /**< Select North NPEA transfer on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_NORTH_NPEB_XFER_SELECT, /**< Select North NPEB transfer on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_NORTH_NPEC_XFER_SELECT, /**< Select North NPEC transfer on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_NORTH_BUS_WRITE_SELECT, /**< Select North bus write on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_NORTH_NPEA_OWN_SELECT, /**< Select North NPEA own on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_NORTH_NPEB_OWN_SELECT, /**< Select North NPEB own on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_NORTH_NPEC_OWN_SELECT, /**< Select North NPEC own on PEC2*/
+
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_SOUTH_GSKT_XFER_SELECT, /**< Select South gasket transfer on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_SOUTH_ABB_XFER_SELECT, /**< Select South abb transfer on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_SOUTH_PCI_XFER_SELECT, /**< Select South pci transfer on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_SOUTH_APB_XFER_SELECT, /**< Select South apb transfer on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_SOUTH_GSKT_OWN_SELECT, /**< Select South gasket own on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_SOUTH_ABB_OWN_SELECT, /**< Select South abb own on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_SOUTH_PCI_OWN_SELECT, /**< Select South pci own on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_SOUTH_APB_OWN_SELECT, /**< Select South apb own transfer on PEC2*/
+
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_SDR_1_HIT_SELECT, /**< Select sdram1 hit on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_SDR_2_HIT_SELECT, /**< Select sdram2 hit on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_SDR_3_HIT_SELECT, /**< Select sdram3 hit on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_SDR_4_HIT_SELECT, /**< Select sdram4 hit on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_SDR_5_MISS_SELECT, /**< Select sdram5 miss on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_SDR_6_MISS_SELECT, /**< Select sdram6 miss on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_SDR_7_MISS_SELECT, /**< Select sdram7 miss on PEC2*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC2_SDR_0_MISS_SELECT /**< Select sdram0 miss on PEC2*/
+} IxPerfProfAccBusPmuEventCounters2;
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @enum IxPerfProfAccBusPmuEventCounters3
+ *
+ * @brief Type of bus pmu events supported on PEC 3.
+ *
+ * Lists all bus pmu events.
+ */
+typedef enum
+{
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_NORTH_NPEA_RETRY_SELECT = 47, /**< Select north NPEA retry on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_NORTH_NPEB_RETRY_SELECT, /**< Select north NPEB retry on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_NORTH_NPEC_RETRY_SELECT, /**< Select north NPEC retry on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_NORTH_BUS_READ_SELECT, /**< Select north bus read on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_NORTH_NPEA_WRITE_SELECT, /**< Select north NPEA write on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_NORTH_NPEB_WRITE_SELECT, /**< Select north NPEB write on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_NORTH_NPEC_WRITE_SELECT, /**< Select north NPEC wirte on PEC3*/
+
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_SOUTH_GSKT_RETRY_SELECT, /**< Select south gasket retry on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_SOUTH_ABB_RETRY_SELECT, /**< Select south abb retry on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_SOUTH_PCI_RETRY_SELECT, /**< Select south pci retry on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_SOUTH_APB_RETRY_SELECT, /**< Select south apb retry on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_SOUTH_GSKT_WRITE_SELECT, /**< Select south gasket write on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_SOUTH_ABB_WRITE_SELECT, /**< Select south abb write on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_SOUTH_PCI_WRITE_SELECT, /**< Select south pci write on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_SOUTH_APB_WRITE_SELECT, /**< Select south apb write on PEC3*/
+
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_SDR_2_HIT_SELECT, /**< Select sdram2 hit on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_SDR_3_HIT_SELECT, /**< Select sdram3 hit on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_SDR_4_HIT_SELECT, /**< Select sdram4 hit on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_SDR_5_HIT_SELECT, /**< Select sdram5 hit on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_SDR_6_MISS_SELECT, /**< Select sdram6 miss on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_SDR_7_MISS_SELECT, /**< Select sdram7 miss on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_SDR_0_MISS_SELECT, /**< Select sdram0 miss on PEC3*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC3_SDR_1_MISS_SELECT /**< Select sdram1 miss on PEC3*/
+} IxPerfProfAccBusPmuEventCounters3;
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @enum IxPerfProfAccBusPmuEventCounters4
+ *
+ * @brief Type of bus pmu events supported on PEC 4.
+ *
+ * Lists all bus pmu events.
+ */
+typedef enum
+{
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_SOUTH_PCI_SPLIT_SELECT = 70, /**< Select south pci split on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_SOUTH_EXP_SPLIT_SELECT, /**< Select south expansion split on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_SOUTH_APB_GRANT_SELECT, /**< Select south apb grant on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_SOUTH_APB_XFER_SELECT, /**< Select south apb transfer on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_SOUTH_GSKT_READ_SELECT, /**< Select south gasket read on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_SOUTH_ABB_READ_SELECT, /**< Select south abb read on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_SOUTH_PCI_READ_SELECT, /**< Select south pci read on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_SOUTH_APB_READ_SELECT, /**< Select south apb read on PEC4*/
+
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_NORTH_ABB_SPLIT_SELECT, /**< Select north abb split on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_NORTH_NPEA_REQ_SELECT, /**< Select north NPEA req on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_NORTH_NPEA_READ_SELECT, /**< Select north NPEA read on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_NORTH_NPEB_READ_SELECT, /**< Select north NPEB read on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_NORTH_NPEC_READ_SELECT, /**< Select north NPEC read on PEC4*/
+
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_SDR_3_HIT_SELECT, /**< Select sdram3 hit on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_SDR_4_HIT_SELECT, /**< Select sdram4 hit on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_SDR_5_HIT_SELECT, /**< Select sdram5 hit on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_SDR_6_HIT_SELECT, /**< Select sdram6 hit on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_SDR_7_MISS_SELECT, /**< Select sdram7 miss on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_SDR_0_MISS_SELECT, /**< Select sdram0 miss on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_SDR_1_MISS_SELECT, /**< Select sdram1 miss on PEC4*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC4_SDR_2_MISS_SELECT /**< Select sdram2 miss on PEC4*/
+} IxPerfProfAccBusPmuEventCounters4;
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @enum IxPerfProfAccBusPmuEventCounters5
+ *
+ * @brief Type of bus pmu events supported on PEC 5.
+ *
+ * Lists all bus pmu events.
+ */
+typedef enum
+{
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_SOUTH_ABB_GRANT_SELECT = 91, /**< Select south abb grant on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_SOUTH_ABB_XFER_SELECT, /**< Select south abb transfer on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_SOUTH_ABB_RETRY_SELECT, /**< Select south abb retry on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_SOUTH_EXP_SPLIT_SELECT, /**< Select south expansion split on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_SOUTH_ABB_REQ_SELECT, /**< Select south abb request on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_SOUTH_ABB_OWN_SELECT, /**< Select south abb own on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_SOUTH_BUS_IDLE_SELECT, /**< Select south bus idle on PEC5*/
+
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_NORTH_NPEB_GRANT_SELECT, /**< Select north NPEB grant on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_NORTH_NPEB_XFER_SELECT, /**< Select north NPEB transfer on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_NORTH_NPEB_RETRY_SELECT, /**< Select north NPEB retry on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_NORTH_NPEB_REQ_SELECT, /**< Select north NPEB request on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_NORTH_NPEB_OWN_SELECT, /**< Select north NPEB own on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_NORTH_NPEB_WRITE_SELECT, /**< Select north NPEB write on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_NORTH_NPEB_READ_SELECT, /**< Select north NPEB read on PEC5*/
+
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_SDR_4_HIT_SELECT, /**< Select north sdram4 hit on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_SDR_5_HIT_SELECT, /**< Select north sdram5 hit on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_SDR_6_HIT_SELECT, /**< Select north sdram6 hit on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_SDR_7_HIT_SELECT, /**< Select north sdram7 hit on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_SDR_0_MISS_SELECT, /**< Select north sdram0 miss on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_SDR_1_MISS_SELECT, /**< Select north sdram1 miss on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_SDR_2_MISS_SELECT, /**< Select north sdram2 miss on PEC5*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC5_SDR_3_MISS_SELECT /**< Select north sdram3 miss on PEC5*/
+} IxPerfProfAccBusPmuEventCounters5;
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @enum IxPerfProfAccBusPmuEventCounters6
+ *
+ * @brief Type of bus pmu events supported on PEC 6.
+ *
+ * Lists all bus pmu events.
+ */
+typedef enum
+{
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_SOUTH_PCI_GRANT_SELECT = 113, /**< Select south pci grant on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_SOUTH_PCI_XFER_SELECT, /**< Select south pci transfer on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_SOUTH_PCI_RETRY_SELECT, /**< Select south pci retry on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_SOUTH_PCI_SPLIT_SELECT, /**< Select south pci split on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_SOUTH_PCI_REQ_SELECT, /**< Select south pci request on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_SOUTH_PCI_OWN_SELECT, /**< Select south pci own on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_SOUTH_BUS_WRITE_SELECT, /**< Select south pci write on PEC6*/
+
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_NORTH_NPEC_GRANT_SELECT, /**< Select north NPEC grant on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_NORTH_NPEC_XFER_SELECT, /**< Select north NPEC transfer on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_NORTH_NPEC_RETRY_SELECT, /**< Select north NPEC retry on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_NORTH_NPEC_REQ_SELECT, /**< Select north NPEC request on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_NORTH_NPEC_OWN_SELECT, /**< Select north NPEC own on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_NORTH_NPEB_WRITE_SELECT, /**< Select north NPEB write on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_NORTH_NPEC_READ_SELECT, /**< Select north NPEC read on PEC6*/
+
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_SDR_5_HIT_SELECT, /**< Select sdram5 hit on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_SDR_6_HIT_SELECT, /**< Select sdram6 hit on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_SDR_7_HIT_SELECT, /**< Select sdram7 hit on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_SDR_0_HIT_SELECT, /**< Select sdram0 hit on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_SDR_1_MISS_SELECT, /**< Select sdram1 miss on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_SDR_2_MISS_SELECT, /**< Select sdram2 miss on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_SDR_3_MISS_SELECT, /**< Select sdram3 miss on PEC6*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC6_SDR_4_MISS_SELECT /**< Select sdram4 miss on PEC6*/
+} IxPerfProfAccBusPmuEventCounters6;
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @enum IxPerfProfAccBusPmuEventCounters7
+ *
+ * @brief Type of bus pmu events supported on PEC 7.
+ *
+ * Lists all bus pmu events.
+ */
+typedef enum
+{
+ IX_PERFPROF_ACC_BUS_PMU_PEC7_SOUTH_APB_RETRY_SELECT = 135, /**< Select south apb retry on PEC7*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC7_SOUTH_APB_REQ_SELECT, /**< Select south apb request on PEC7*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC7_SOUTH_APB_OWN_SELECT, /**< Select south apb own on PEC7*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC7_SOUTH_BUS_READ_SELECT, /**< Select south bus read on PEC7*/
+ IX_PERFPROF_ACC_BUS_PMU_PEC7_CYCLE_COUNT_SELECT /**< Select cycle count on PEC7*/
+} IxPerfProfAccBusPmuEventCounters7;
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @enum IxPerfProfAccXscalePmuEvent
+ *
+ * @brief Type of xscale pmu events supported
+ *
+ * Lists all xscale pmu events. The maximum is a default value that the user
+ * should not exceed.
+ */
+typedef enum
+{
+ IX_PERFPROF_ACC_XSCALE_PMU_EVENT_CACHE_MISS=0, /**< cache miss*/
+ IX_PERFPROF_ACC_XSCALE_PMU_EVENT_CACHE_INSTRUCTION,/**< cache instruction*/
+ IX_PERFPROF_ACC_XSCALE_PMU_EVENT_STALL, /**< event stall*/
+ IX_PERFPROF_ACC_XSCALE_PMU_EVENT_INST_TLB_MISS, /**< instruction tlb miss*/
+ IX_PERFPROF_ACC_XSCALE_PMU_EVENT_DATA_TLB_MISS, /**< data tlb miss*/
+ IX_PERFPROF_ACC_XSCALE_PMU_EVENT_BRANCH_EXEC, /**< branch executed*/
+ IX_PERFPROF_ACC_XSCALE_PMU_EVENT_BRANCH_MISPREDICT, /**<branch mispredict*/
+ IX_PERFPROF_ACC_XSCALE_PMU_EVENT_INST_EXEC, /**< instruction executed*/
+ IX_PERFPROF_ACC_XSCALE_PMU_EVENT_FULL_EVERYCYCLE, /**<
+ *Stall - data cache
+ *buffers are full.
+ *This event occurs
+ *every cycle where
+ *condition present
+ */
+ IX_PERFPROF_ACC_XSCALE_PMU_EVENT_ONCE, /**<
+ *Stall - data cache buffers are
+ *full.This event occurs once
+ *for each contiguous sequence
+ */
+ IX_PERFPROF_ACC_XSCALE_PMU_EVENT_DATA_CACHE_ACCESS, /**< data cache access*/
+ IX_PERFPROF_ACC_XSCALE_PMU_EVENT_DATA_CACHE_MISS, /**< data cache miss*/
+ IX_PERFPROF_ACC_XSCALE_PMU_EVENT_DATA_CACHE_WRITEBACK, /**<data cache
+ *writeback
+ */
+ IX_PERFPROF_ACC_XSCALE_PMU_EVENT_SW_CHANGE_PC, /**< sw change pc*/
+ IX_PERFPROF_ACC_XSCALE_PMU_EVENT_MAX /**< max value*/
+} IxPerfProfAccXscalePmuEvent;
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @enum IxPerfProfAccStatus
+ *
+ * @brief Invalid Status Definitions
+ *
+ * These status will be used by the APIs to return to the user.
+ */
+typedef enum
+{
+ IX_PERFPROF_ACC_STATUS_SUCCESS = IX_SUCCESS, /**< success*/
+ IX_PERFPROF_ACC_STATUS_FAIL = IX_FAIL, /**< fail*/
+ IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS,/**<another utility in
+ *progress
+ */
+ IX_PERFPROF_ACC_STATUS_XCYCLE_MEASUREMENT_IN_PROGRESS, /**<measurement in
+ *progress
+ */
+ IX_PERFPROF_ACC_STATUS_XCYCLE_NO_BASELINE, /**<no baseline yet*/
+ IX_PERFPROF_ACC_STATUS_XCYCLE_MEASUREMENT_REQUEST_OUT_OF_RANGE, /**<
+ * Measurement chosen
+ * is out of range
+ */
+ IX_PERFPROF_ACC_STATUS_XCYCLE_PRIORITY_SET_FAIL, /**<
+ * Cannot set
+ * task priority
+ */
+ IX_PERFPROF_ACC_STATUS_XCYCLE_THREAD_CREATE_FAIL, /**<
+ * Fail create thread
+ */
+ IX_PERFPROF_ACC_STATUS_XCYCLE_PRIORITY_RESTORE_FAIL, /**<
+ *cannot restore
+ *priority
+ */
+ IX_PERFPROF_ACC_STATUS_XCYCLE_MEASUREMENT_NOT_RUNNING, /**< xcycle not running*/
+ IX_PERFPROF_ACC_STATUS_XSCALE_PMU_NUM_INVALID, /**< invalid number
+ *entered
+ */
+ IX_PERFPROF_ACC_STATUS_XSCALE_PMU_EVENT_INVALID, /**< invalid pmu event*/
+ IX_PERFPROF_ACC_STATUS_XSCALE_PMU_START_NOT_CALLED, /**<a start process
+ *was not called
+ *before attempting
+ *a stop or results
+ *get
+ */
+ IX_PERFPROF_ACC_STATUS_BUS_PMU_MODE_ERROR, /**< invalid mode*/
+ IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC1_ERROR, /**< invalid pec1 entered*/
+ IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC2_ERROR, /**< invalid pec2 entered*/
+ IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC3_ERROR, /**< invalid pec3 entered*/
+ IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC4_ERROR, /**< invalid pec4 entered*/
+ IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC5_ERROR, /**< invalid pec5 entered*/
+ IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC6_ERROR, /**< invalid pec6 entered*/
+ IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC7_ERROR, /**< invalid pec7 entered*/
+ IX_PERFPROF_ACC_STATUS_BUS_PMU_START_NOT_CALLED, /**<a start process
+ *was not called
+ *before attempting
+ *a stop
+ */
+ IX_PERFPROF_ACC_STATUS_COMPONENT_NOT_SUPPORTED /**<Device or OS does not support component*/
+} IxPerfProfAccStatus;
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @enum IxPerfProfAccBusPmuMode
+ *
+ * @brief State selection of counters.
+ *
+ * These states will be used to determine the counters whose values are to be
+ * read.
+ */
+typedef enum
+{
+ IX_PERFPROF_ACC_BUS_PMU_MODE_HALT=0, /**< halt state*/
+ IX_PERFPROF_ACC_BUS_PMU_MODE_SOUTH, /**< south state*/
+ IX_PERFPROF_ACC_BUS_PMU_MODE_NORTH, /**< north state*/
+ IX_PERFPROF_ACC_BUS_PMU_MODE_SDRAM /**< SDRAM state*/
+} IxPerfProfAccBusPmuMode;
+
+/*
+ * Section for prototypes interface functions
+ */
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXscalePmuEventCountStart(
+ BOOL clkCntDiv,
+ UINT32 numEvents,
+ IxPerfProfAccXscalePmuEvent pmuEvent1,
+ IxPerfProfAccXscalePmuEvent pmuEvent2,
+ IxPerfProfAccXscalePmuEvent pmuEvent3,
+ IxPerfProfAccXscalePmuEvent pmuEvent4 )
+ *
+ * @brief This API will start the clock and event counting
+ *
+ * @param clkCntDiv BOOL [in] - enables/disables the clock divider. When
+ * true, the divider is enabled and the clock count will be incremented
+ * by one at each 64th processor clock cycle. When false, the divider
+ * is disabled and the clock count will be incremented at every
+ * processor clock cycle.
+ * @param numEvents UINT32 [in] - the number of PMU events that are to be
+ * monitored as specified by the user. For clock counting only, this
+ * is set to zero.
+ * @param pmuEvent1 @ref IxPerfProfAccXscalePmuEvent [in] - the specific PMU
+ * event to be monitored by counter 1
+ * @param pmuEvent2 @ref IxPerfProfAccXscalePmuEvent [in] - the specific PMU
+ * event to be monitored by counter 2
+ * @param pmuEvent3 @ref IxPerfProfAccXscalePmuEvent [in] - the specific PMU
+ * event to be monitored by counter 3
+ * @param pmuEvent4 @ref IxPerfProfAccXscalePmuEvent [in] - the specific PMU
+ * event to be monitored by counter 4
+ *
+ * This API will start the clock and xscale PMU event counting. Up to
+ * 4 events can be monitored simultaneously. This API has to be called before
+ * ixPerfProfAccXscalePmuEventCountStop can be called.
+ *
+ * @return
+ * - IX_PERFPROF_ACC_STATUS_SUCCESS if clock and events counting are
+ * started successfully
+ * - IX_PERFPROF_ACC_STATUS_FAIL if unable to start the counting
+ * - IX_PERFPROF_ACC_STATUS_XSCALE_PMU_NUM_INVALID if the number of events
+ * specified is out of the valid range
+ * - IX_PERFPROF_ACC_STATUS_XSCALE_PMU_EVENT_INVALID if the value of the PMU
+ * event specified does not exist
+ * - IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS - another utility is
+ * running
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccXscalePmuEventCountStart(
+ BOOL clkCntDiv,
+ UINT32 numEvents,
+ IxPerfProfAccXscalePmuEvent pmuEvent1,
+ IxPerfProfAccXscalePmuEvent pmuEvent2,
+ IxPerfProfAccXscalePmuEvent pmuEvent3,
+ IxPerfProfAccXscalePmuEvent pmuEvent4 );
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXscalePmuEventCountStop (
+ IxPerfProfAccXscalePmuResults *eventCountStopResults)
+ *
+ * @brief This API will stop the clock and event counting
+ *
+ * @param *eventCountStopResults @ref IxPerfProfAccXscalePmuResults [out] - pointer
+ * to struct containing results of counters and their overflow. It is the
+ * users's responsibility to allocate the memory for this pointer.
+ *
+ * This API will stop the clock and xscale PMU events that are being counted.
+ * The results of the clock and events count will be stored in the pointer
+ * allocated by the user. It can only be called once
+ * IxPerfProfAccEventCountStart has been called.
+ *
+ * @return
+ * - IX_PERFPROF_ACC_STATUS_SUCCESS if clock and events counting are
+ * stopped successfully
+ * - IX_PERFPROF_ACC_STATUS_XSCALE_PMU_START_NOT_CALLED if
+ * ixPerfProfAccXscalePmuEventCountStart is not called first.
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccXscalePmuEventCountStop(
+ IxPerfProfAccXscalePmuResults *eventCountStopResults);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXscalePmuTimeSampStart(
+ UINT32 samplingRate,
+ BOOL clkCntDiv)
+ *
+ * @brief Starts the time based sampling
+ *
+ * @param samplingRate UINT32 [in] - sampling rate is the number of
+ * clock counts before a counter overflow interrupt is generated,
+ * at which, a sample is taken; the rate specified cannot be greater
+ * than the counter size of 32bits or set to zero.
+ * @param clkCntDiv BOOL [in] - enables/disables the clock divider. When
+ * true, the divider is enabled and the clock count will be incremented
+ * by one at each 64th processor clock cycle. When false, the divider
+ * is disabled and the clock count will be incremented at every
+ * processor clock cycle.
+ *
+ * This API starts the time based sampling to determine the frequency with
+ * which lines of code are being executed. Sampling is done at the rate
+ * specified by the user. At each sample,the value of the program counter
+ * is determined. Each of these occurrences are recorded to determine the
+ * frequency with which the Xscale code is being executed. This API has to be
+ * called before ixPerfProfAccXscalePmuTimeSampStop can be called.
+ *
+ * @return
+ * - IX_PERFPROF_ACC_STATUS_SUCCESS if time based sampling is started
+ * successfully
+ * - IX_PERFPROF_ACC_STATUS_FAIL if unable to start the sampling
+ * - IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS - another utility is
+ * running
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccXscalePmuTimeSampStart(
+ UINT32 samplingRate,
+ BOOL clkCntDiv);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXscalePmuTimeSampStop(
+ IxPerfProfAccXscalePmuEvtCnt *clkCount,
+ IxPerfProfAccXscalePmuSamplePcProfile *timeProfile)
+ *
+ * @brief Stops the time based sampling
+ *
+ * @param *clkCount @ref IxPerfProfAccXscalePmuEvtCnt [out] - pointer to the
+ * struct containing the final clock count and its overflow. It is the
+ * user's responsibility to allocate the memory for this pointer.
+ * @param *timeProfile @ref IxPerfProfAccXscalePmuSamplePcProfile [out] -
+ * pointer to the array of profiles for each program counter value;
+ * the user should set the size of the array to
+ * IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES. It is the user's
+ * responsibility to allocate the memory for this pointer.
+ *
+ * This API stops the time based sampling. The results are stored in the
+ * pointers allocated by the user. It can only be called once
+ * ixPerfProfAccXscalePmuTimeSampStart has been called.
+ *
+ * @return
+ * - IX_PERFPROF_ACC_STATUS_SUCCESS if time based sampling is stopped
+ * successfully
+ * - IX_PERFPROF_ACC_STATUS_XSCALE_PMU_START_NOT_CALLED if
+ * ixPerfProfAccXscalePmuTimeSampStart not called first
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccXscalePmuTimeSampStop(
+ IxPerfProfAccXscalePmuEvtCnt *clkCount,
+ IxPerfProfAccXscalePmuSamplePcProfile *timeProfile);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXscalePmuEventSampStart(
+ UINT32 numEvents,
+ IxPerfProfAccXscalePmuEvent pmuEvent1,
+ UINT32 eventRate1,
+ IxPerfProfAccXscalePmuEvent pmuEvent2,
+ UINT32 eventRate2,
+ IxPerfProfAccXscalePmuEvent pmuEvent3,
+ UINT32 eventRate3,
+ IxPerfProfAccXscalePmuEvent pmuEvent4,
+ UINT32 eventRate4)
+ *
+ * @brief Starts the event based sampling
+ *
+ * @param numEvents UINT32 [in] - the number of PMU events that are
+ * to be monitored as specified by the user. The value should be
+ * between 1-4 events at a time.
+ * @param pmuEvent1 @ref IxPerfProfAccXscalePmuEvent [in] - the specific PMU
+ * event to be monitored by counter 1
+ * @param eventRate1 UINT32 [in] - sampling rate of counter 1. The rate is
+ * the number of events before a sample taken. If 0 is specified, the
+ * the full counter value (0xFFFFFFFF) is used. The rate must not be
+ * greater than the full counter value.
+ * @param pmuEvent2 @ref IxPerfProfAccXscalePmuEvent [in] - the specific PMU
+ * event to be monitored by counter 2
+ * @param eventRate2 UINT32 [in] - sampling rate of counter 2. The rate is
+ * the number of events before a sample taken. If 0 is specified, the
+ * full counter value (0xFFFFFFFF) is used. The rate must not be
+ * greater than the full counter value.
+ * @param pmuEvent3 @ref IxPerfProfAccXscalePmuEvent [in] - the specific PMU
+ * event to be monitored by counter 3
+ * @param eventRate3 UINT32 [in] - sampling rate of counter 3. The rate is
+ * the number of events before a sample taken. If 0 is specified, the
+ * full counter value (0xFFFFFFFF) is used. The rate must not be
+ * greater than the full counter value.
+ * @param pmuEvent4 @ref IxPerfProfAccXscalePmuEvent [in] - the specific PMU
+ * event to be monitored by counter 4
+ * @param eventRate4 UINT32 [in] - sampling rate of counter 4. The rate is
+ * the number of events before a sample taken. If 0 is specified, the
+ * full counter value (0xFFFFFFFF) is used. The rate must not be
+ * greater than the full counter value.
+ *
+ * Starts the event based sampling to determine the frequency with
+ * which events are being executed. The sampling rate is the number of events,
+ * as specified by the user, before a counter overflow interrupt is
+ * generated. A sample is taken at each counter overflow interrupt. At each
+ * sample,the value of the program counter determines the corresponding
+ * location in the code. Each of these occurrences are recorded to determine
+ * the frequency with which the Xscale code in each event is executed. This API
+ * has to be called before ixPerfProfAccXscalePmuEventSampStop can be called.
+ *
+ * @return
+ * - IX_PERFPROF_ACC_STATUS_SUCCESS if event based sampling is started
+ * successfully
+ * - IX_PERFPROF_ACC_STATUS_FAIL if unable to start the sampling
+ * - IX_PERFPROF_ACC_STATUS_XSCALE_PMU_NUM_INVALID if the number of events
+ * specified is out of the valid range
+ * - IX_PERFPROF_ACC_STATUS_XSCALE_PMU_EVENT_INVALID if the value of the
+ * PMU event specified does not exist
+ * - IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS - another utility is
+ * running
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccXscalePmuEventSampStart(
+ UINT32 numEvents,
+ IxPerfProfAccXscalePmuEvent pmuEvent1,
+ UINT32 eventRate1,
+ IxPerfProfAccXscalePmuEvent pmuEvent2,
+ UINT32 eventRate2,
+ IxPerfProfAccXscalePmuEvent pmuEvent3,
+ UINT32 eventRate3,
+ IxPerfProfAccXscalePmuEvent pmuEvent4,
+ UINT32 eventRate4);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXscalePmuEventSampStop(
+ IxPerfProfAccXscalePmuSamplePcProfile *eventProfile1,
+ IxPerfProfAccXscalePmuSamplePcProfile *eventProfile2,
+ IxPerfProfAccXscalePmuSamplePcProfile *eventProfile3,
+ IxPerfProfAccXscalePmuSamplePcProfile *eventProfile4)
+ *
+ * @brief Stops the event based sampling
+ *
+ * @param *eventProfile1 @ref IxPerfProfAccXscalePmuSamplePcProfile [out] -
+ * pointer to the array of profiles for each program counter value;
+ * the user should set the size of the array to
+ * IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES. It is the
+ * users's responsibility to allocate memory for this pointer.
+ * @param *eventProfile2 @ref IxPerfProfAccXscalePmuSamplePcProfile [out] -
+ * pointer to the array of profiles for each program counter value;
+ * the user should set the size of the array to
+ * IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES. It is the
+ * users's responsibility to allocate memory for this pointer.
+ * @param *eventProfile3 @ref IxPerfProfAccXscalePmuSamplePcProfile [out] -
+ * pointer to the array of profiles for each program counter value;
+ * the user should set the size of the array to
+ * IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES. It is the
+ * users's responsibility to allocate memory for this pointer.
+ * @param *eventProfile4 @ref IxPerfProfAccXscalePmuSamplePcProfile [out] -
+ * pointer to the array of profiles for each program counter value;
+ * the user should set the size of the array to
+ * IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES. It is the
+ * users's responsibility to allocate memory for this pointer.
+ *
+ * This API stops the event based sampling. The results are stored in the
+ * pointers allocated by the user. It can only be called once
+ * ixPerfProfAccEventSampStart has been called.
+ *
+ * @return
+ * - IX_PERFPROF_ACC_STATUS_SUCCESS if event based sampling is stopped
+ * successfully
+ * - IX_PERFPROF_ACC_STATUS_XSCALE_PMU_START_NOT_CALLED if
+ * ixPerfProfAccEventSampStart not called first.
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccXscalePmuEventSampStop(
+ IxPerfProfAccXscalePmuSamplePcProfile *eventProfile1,
+ IxPerfProfAccXscalePmuSamplePcProfile *eventProfile2,
+ IxPerfProfAccXscalePmuSamplePcProfile *eventProfile3,
+ IxPerfProfAccXscalePmuSamplePcProfile *eventProfile4);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXscalePmuResultsGet(IxPerfProfAccXscalePmuResults *results)
+ *
+ * @brief Reads the current value of the counters and their overflow
+ *
+ * @param *results @ref IxPerfProfAccXscalePmuResults [out] - pointer to the
+ results struct. It is the user's responsibility to allocate memory
+ for this pointer
+ *
+ * This API reads the value of all four event counters and the clock counter,
+ * and the associated overflows. It does not give results associated with
+ * sampling, i.e. PC and their frequencies. This API can be called at any time
+ * once a process has been started. If it is called before a process has started
+ * the user should be aware that the values it contains are default values and
+ * might be meaningless. The values of the counters are stored in the pointer
+ * allocated by the client.
+ *
+ * @return - none
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC void
+ixPerfProfAccXscalePmuResultsGet(IxPerfProfAccXscalePmuResults *results);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccBusPmuStart(
+ IxPerfProfAccBusPmuMode mode,
+ IxPerfProfAccBusPmuEventCounters1 pecEvent1,
+ IxPerfProfAccBusPmuEventCounters2 pecEvent2,
+ IxPerfProfAccBusPmuEventCounters3 pecEvent3,
+ IxPerfProfAccBusPmuEventCounters4 pecEvent4,
+ IxPerfProfAccBusPmuEventCounters5 pecEvent5,
+ IxPerfProfAccBusPmuEventCounters6 pecEvent6,
+ IxPerfProfAccBusPmuEventCounters7 pecEvent7)
+ * @brief Initializes all the counters and selects events to be monitored.
+ *
+ * Function initializes all the counters and assigns the events associated
+ * with the counters. Users send in the mode and events they want to count.
+ * This API verifies if the combination chosen is appropriate
+ * and sets all the registers accordingly. Selecting HALT mode will result
+ * in an error. User should use ixPerfProfAccBusPmuStop() to HALT.
+ *
+ *
+ * @param mode @ref IxPerfProfAccStateBusPmuMode [in] - Mode selection.
+ * @param pecEvent1 @ref IxPerfProfAccBusPmuEventCounters1 [in] - Event for PEC1.
+ * @param pecEvent2 @ref IxPerfProfAccBusPmuEventCounters2 [in] - Event for PEC2.
+ * @param pecEvent3 @ref IxPerfProfAccBusPmuEventCounters3 [in] - Event for PEC3.
+ * @param pecEvent4 @ref IxPerfProfAccBusPmuEventCounters4 [in] - Event for PEC4.
+ * @param pecEvent5 @ref IxPerfProfAccBusPmuEventCounters5 [in] - Event for PEC5.
+ * @param pecEvent6 @ref IxPerfProfAccBusPmuEventCounters6 [in] - Event for PEC6.
+ * @param pecEvent7 @ref IxPerfProfAccBusPmuEventCounters7 [in] - Event for PEC7.
+ *
+ * @return
+ * - IX_PERFPROF_ACC_STATUS_SUCCESS - Initialization executed
+ * successfully.
+ * - IX_PERFPROF_ACC_STATUS_BUS_PMU_MODE_ERROR - Error in selection of
+ * mode. Only NORTH, SOUTH and SDRAM modes are allowed.
+ * - IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC1_ERROR - Error in selection of
+ * event for PEC1
+ * - IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC2_ERROR - Error in selection of
+ * event for PEC2
+ * - IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC3_ERROR - Error in selection of
+ * event for PEC3
+ * - IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC4_ERROR - Error in selection of
+ * event for PEC4
+ * - IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC5_ERROR - Error in selection of
+ * event for PEC5
+ * - IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC6_ERROR - Error in selection of
+ * event for PEC6
+ * - IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC7_ERROR - Error in selection of
+ * event for PEC7
+ * - IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS - another utility
+ * is running
+ * - IX_PERFPROF_ACC_STATUS_FAIL - Failed to start because interrupt
+ * service routine fails to bind.
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ **/
+PUBLIC
+IxPerfProfAccStatus ixPerfProfAccBusPmuStart (
+ IxPerfProfAccBusPmuMode mode,
+ IxPerfProfAccBusPmuEventCounters1 pecEvent1,
+ IxPerfProfAccBusPmuEventCounters2 pecEvent2,
+ IxPerfProfAccBusPmuEventCounters3 pecEvent3,
+ IxPerfProfAccBusPmuEventCounters4 pecEvent4,
+ IxPerfProfAccBusPmuEventCounters5 pecEvent5,
+ IxPerfProfAccBusPmuEventCounters6 pecEvent6,
+ IxPerfProfAccBusPmuEventCounters7 pecEvent7);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccBusPmuStop(void)
+ * @brief Stops all counters.
+ *
+ * This function stops all the PECs by setting the halt bit in the ESR.
+ *
+ *
+ * @return
+ * - IX_PERFPROF_ACC_STATUS_SUCCESS - Counters successfully halted.
+ * - IX_PERFPROF_ACC_STATUS_FAIL - Counters could'nt be halted.
+ * - IX_PERFPROF_ACC_STATUS_BUS_PMU_START_NOT_CALLED - the
+ * ixPerfProfAccBusPmuStart() function is not called.
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ **/
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccBusPmuStop (void);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccBusPmuResultsGet (
+ IxPerfProfAccBusPmuResults *busPmuResults)
+ * @brief Gets values of all counters
+ *
+ * This function is responsible for getting all the counter values from the
+ * lower API and putting it into an array for the user.
+ *
+ * @param *busPmuResults @ref IxPerfProfAccBusPmuResults [out]
+ * - Pointer to a structure of arrays to store all counter values.
+ *
+ * @return none
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ **/
+PUBLIC void
+ixPerfProfAccBusPmuResultsGet (IxPerfProfAccBusPmuResults *BusPmuResults);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccBusPmuPMSRGet (
+ UINT32 *pmsrValue)
+ * @brief Get values of PMSR
+ *
+ * This API gets the Previous Master Slave Register
+ * value and returns it to the calling function. This value indicates
+ * which master or slave accessed the north, south bus or sdram last.
+ * The value returned by this function is a 32 bit value and is read
+ * from location of an offset 0x0024 of the base value.
+ *
+ * The PMSR value returned indicate the following:
+ * <pre>
+ *
+ * *************************************************************************************
+ * * Bit * Name * Description *
+ * * *
+ * *************************************************************************************
+ * * [31:18] *Reserved* *
+ * *************************************************************************************
+ * * [17:12] * PSS * Indicates which of the slaves on *
+ * * * * ARBS was previously *
+ * * * * accessed by the AHBS. *
+ * * * * [000001] Expansion Bus *
+ * * * * [000010] SDRAM Controller *
+ * * * * [000100] PCI *
+ * * * * [001000] Queue Manager *
+ * * * * [010000] AHB-APB Bridge *
+ * * * * [100000] Reserved *
+ * *************************************************************************************
+ * * [11:8] * PSN * Indicates which of the Slaves on *
+ * * * * ARBN was previously *
+ * * * * accessed the AHBN. *
+ * * * * [0001] SDRAM Controller *
+ * * * * [0010] AHB-AHB Bridge *
+ * * * * [0100] Reserved *
+ * * * * [1000] Reserved *
+ * *************************************************************************************
+ * * [7:4] * PMS * Indicates which of the Masters on *
+ * * * * ARBS was previously *
+ * * * * accessing the AHBS. *
+ * * * * [0001] Gasket *
+ * * * * [0010] AHB-AHB Bridge *
+ * * * * [0100] PCI *
+ * * * * [1000] APB *
+ * *************************************************************************************
+ * * [3:0] * PMN * Indicates which of the Masters on *
+ * * * * ARBN was previously *
+ * * * * accessing the AHBN. *
+ * * * * [0001] NPEA *
+ * * * * [0010] NPEB *
+ * * * * [0100] NPEC *
+ * * * * [1000] Reserved *
+ * *************************************************************************************
+ * </pre>
+ *
+ * @param *pmsrValue UINT32 [out] - Pointer to return PMSR value. Users need to
+ * allocate storage for psmrValue.
+ *
+ * @return none
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ **/
+PUBLIC void
+ixPerfProfAccBusPmuPMSRGet (
+UINT32 *pmsrValue);
+
+
+/**
+ * The APIs below are specifically used for Xcycle module.
+ **/
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXcycleBaselineRun (
+ UINT32 *numBaselineCycle)
+ *
+ * @brief Perform baseline for Xcycle
+ *
+ * @param *numBaselineCycle UINT32 [out] - pointer to baseline value after
+ * calibration. Calling function are responsible for
+ * allocating memory space for this pointer.
+ *
+ * Global Data :
+ * - None.
+ *
+ * This function MUST be run before the Xcycle tool can be used. This
+ * function must be run immediately when the OS boots up with no other
+ * addition programs running.
+ * Addition note : This API will measure the time needed to perform
+ * a fix amount of CPU instructions (~ 1 second worth of loops) as a
+ * highest priority task and with interrupt disabled. The time measured
+ * is known as the baseline - interpreted as the shortest time
+ * needed to complete the amount of CPU instructions. The baseline is
+ * returned as unit of time in 66Mhz clock tick.
+ *
+ * @return
+ * - IX_PERFPROF_ACC_STATUS_SUCCESS - successful run, result is returned
+ * - IX_PERFPROF_ACC_STATUS_XCYCLE_PRIORITY_SET_FAIL - failed to change
+ * task priority
+ * - IX_PERFPROF_ACC_STATUS_XCYCLE_PRIORITY_RESTORE_FAIL - failed to
+ * restore task priority
+ * - IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS - another utility
+ * is running
+ * - IX_PERFPROF_ACC_STATUS_XCYCLE_MEASUREMENT_IN_PROGRESS - Xcycle
+ * tool has already started
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccXcycleBaselineRun(
+ UINT32 *numBaselineCycle);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXcycleStart(
+ UINT32 numMeasurementsRequested);
+ *
+ * @brief Start the measurement
+ *
+ * @param numMeasurementsRequested UINT32 [in] - number of measurements
+ * to perform. Value can be 0 to
+ * IX_PERFPROF_ACC_XCYCLE_MAX_NUM_OF_MEASUREMENTS.
+ * 0 indicate continuous measurement.
+ *
+ * Global Data :
+ * - None.
+ *
+ *
+ * Start the measurements immediately.
+ * numMeasurementsRequested specifies number of measurements to run.
+ * If numMeasurementsRequested is set to 0, the measurement will
+ * be performed continuously until IxPerfProfAccXcycleStop()
+ * is called.
+ * It is estimated that 1 measurement takes approximately 1 second during
+ * low CPU utilization, therefore 128 measurement takes approximately 128 sec.
+ * When CPU utilization is high, the measurement will take longer.
+ * This function spawn a task the perform the measurement and returns.
+ * The measurement may continue even if this function returns.
+ *
+ * IMPORTANT: Under heavy CPU utilization, the task spawn by this
+ * function may starve and fail to respond to stop command. User
+ * may need to kill the task manually in this case.
+ *
+ * There are only IX_PERFPROF_ACC_XCYCLE_MAX_NUM_OF_MEASUREMENTS
+ * storage available so storing is wrapped around if measurements are
+ * more than IX_PERFPROF_ACC_XCYCLE_MAX_NUM_OF_MEASUREMENTS.
+ *
+ *
+ * @return
+ * - IX_PERFPROF_ACC_STATUS_SUCCESS - successful start, a thread is created
+ * in the background to perform measurement.
+ * - IX_PERFPROF_ACC_STATUS_XCYCLE_PRIORITY_SET_FAIL - failed to set
+ * task priority
+ * - IX_PERFPROF_ACC_STATUS_XCYCLE_THREAD_CREATE_FAIL - failed to create
+ * thread to perform measurement.
+ * - IX_PERFPROF_ACC_STATUS_XCYCLE_NO_BASELINE - baseline is not available
+ * - IX_PERFPROF_ACC_STATUS_XCYCLE_MEASUREMENT_REQUEST_OUT_OF_RANGE -
+ * value is larger than IX_PERFPROF_ACC_XCYCLE_MAX_NUM_OF_MEASUREMENTS
+ * - IX_PERFPROF_ACC_STATUS_XCYCLE_MEASUREMENT_IN_PROGRESS - Xcycle tool
+ * has already started
+ * - IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS - another utility is
+ * running
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccXcycleStart (
+ UINT32 numMeasurementsRequested);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXcycleStop(void);
+ *
+ * @brief Stop the Xcycle measurement
+ *
+ * @param None
+ *
+ * Global Data :
+ * - None.
+ *
+ * Stop Xcycle measurements immediately. If the measurements have stopped
+ * or not started, return IX_PERFPROF_STATUS_XCYCLE_MEASUREMENT_NOT_RUNNING.
+ * Note: This function does not stop measurement cold. The measurement thread
+ * may need a few seconds to complete the last measurement. User needs to use
+ * ixPerfProfAccXcycleInProgress() to determine if measurement is indeed
+ * completed.
+ *
+ * @return
+ * - IX_PERFPROF_ACC_STATUS_SUCCESS - successful measurement is stopped
+ * - IX_PERFPROF_STATUS_XCYCLE_MEASUREMENT_NOT_RUNNING - no measurement running
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccXcycleStop(void);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXcycleResultsGet(
+ IxPerfProfAccXcycleResults *xcycleResult )
+ *
+ * @brief Get the results of Xcycle measurement
+ *
+ * @param *xcycleResult @ref IxPerfProfAccXcycleResults [out] - Pointer to
+ * results of last measurements. Calling function are
+ * responsible for allocating memory space for this pointer.
+ *
+ * Global Data :
+ * - None.
+ *
+ * Retrieve the results of last measurement. User should use
+ * ixPerfProfAccXcycleInProgress() to check if measurement is completed
+ * before getting the results.
+ *
+ * @return
+ * - IX_PERFPROF_ACC_STATUS_SUCCESS - successful
+ * - IX_PERFPROF_ACC_STATUS_FAIL - result is not complete.
+ * - IX_PERFPROF_ACC_STATUS_XCYCLE_NO_BASELINE - baseline is performed
+ * - IX_PERFPROF_ACC_STATUS_XCYCLE_MEASUREMENT_IN_PROGRESS - Xcycle
+ * tool is still running
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccXcycleResultsGet (
+ IxPerfProfAccXcycleResults *xcycleResult);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXcycleInProgress (void)
+ *
+ * @brief Check if Xcycle is running
+ *
+ * @param None
+ * Global Data :
+ * - None.
+ *
+ * Check if Xcycle measuring task is running.
+ *
+ * @return
+ * - TRUE - Xcycle is running
+ * - FALSE - Xcycle is not running
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+PUBLIC BOOL
+ixPerfProfAccXcycleInProgress(void);
+
+#ifdef __linux
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXscalePmuTimeSampCreateProcFile
+ *
+ * @brief Enables proc file to call module function
+ *
+ * @param None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This function is declared globally to enable /proc directory system to call
+ * and execute the function when the registered file is called. This function is not meant to
+ * be called by the user.
+ *
+ * @return
+ * - Length of data written to file.
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+int
+ixPerfProfAccXscalePmuTimeSampCreateProcFile (char *buf, char **start, off_t offset,
+ int count, int *eof, void *data);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXscalePmuEventSampCreateProcFile
+ *
+ * @brief Enables proc file to call module function
+ *
+ * @param None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This function is declared globally to enable /proc directory system to call
+ * and execute the function when the registered file is called. This function is not meant to
+ * be called by the user.
+ *
+ * @return
+ * - Length of data written to file.
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ */
+int
+ixPerfProfAccXscalePmuEventSampCreateProcFile (char *buf, char **start, off_t offset,
+ int count, int *eof, void *data);
+
+
+#endif /* ifdef __linux */
+
+#endif /* ndef IXPERFPROFACC_H */
+
+/**
+ *@} defgroup IxPerfProfAcc
+ */
+
+
diff --git a/cpu/ixp/npe/include/IxQMgr.h b/cpu/ixp/npe/include/IxQMgr.h
new file mode 100644
index 0000000..c083a2b
--- /dev/null
+++ b/cpu/ixp/npe/include/IxQMgr.h
@@ -0,0 +1,2210 @@
+/**
+ * @file IxQMgr.h
+ *
+ * @date 30-Oct-2001
+ *
+ * @brief This file contains the public API of IxQMgr component.
+ *
+ * Some functions contained in this module are inline to achieve better
+ * data-path performance. For this to work, the function definitions are
+ * contained in this header file. The "normal" use of inline functions
+ * is to use the inline functions in the module in which they are
+ * defined. In this case these inline functions are used in external
+ * modules and therefore the use of "inline extern". What this means
+ * is as follows: if a function foo is declared as "inline extern" this
+ * definition is only used for inlining, in no case is the function
+ * compiled on its own. If the compiler cannot inline the function it
+ * becomes an external reference. Therefore in IxQMgrQAccess.c all
+ * inline functions are defined without the "inline extern" specifier
+ * and so define the external references. In all other source files
+ * including this header file, these funtions are defined as "inline
+ * extern".
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/* ------------------------------------------------------
+ Doxygen group definitions
+ ------------------------------------------------------ */
+/**
+ * @defgroup IxQMgrAPI IXP400 Queue Manager (IxQMgr) API
+ *
+ * @brief The public API for the IXP400 QMgr component.
+ *
+ * IxQMgr is a low level interface to the AHB Queue Manager
+ *
+ * @{
+ */
+
+#ifndef IXQMGR_H
+#define IXQMGR_H
+
+/*
+ * User defined include files
+ */
+
+#include "IxOsal.h"
+
+/*
+ * Define QMgr's IoMem macros, in DC mode if in LE
+ * regular if in BE. (Note: For Linux LSP gold release
+ * may need to adjust mode.
+ */
+#if defined (__BIG_ENDIAN)
+
+#define IX_QMGR_INLINE_READ_LONG IX_OSAL_READ_LONG_BE
+#define IX_QMGR_INLINE_WRITE_LONG IX_OSAL_WRITE_LONG_BE
+
+#else
+
+#define IX_QMGR_INLINE_READ_LONG IX_OSAL_READ_LONG_LE_DC
+#define IX_QMGR_INLINE_WRITE_LONG IX_OSAL_WRITE_LONG_LE_DC
+
+#endif
+
+/*
+ * #defines and macros
+ */
+
+/**
+*
+* @ingroup IxQMgrAPI
+*
+* @def IX_QMGR_INLINE
+*
+* @brief Inline definition, for inlining of Queue Access functions on API
+*
+* Please read the header information in this file for more details on the
+* use of function inlining in this component.
+*
+*/
+
+#ifndef __wince
+
+#ifdef IXQMGRQACCESS_C
+/* If IXQMGRQACCESS_C is set then the IxQmgrQAccess.c is including this file
+ and must instantiate a concrete definition for each inlineable API function
+ whether or not that function actually gets inlined. */
+# ifdef NO_INLINE_APIS
+# undef NO_INLINE_APIS
+# endif
+# define IX_QMGR_INLINE /* Empty Define */
+#else
+# ifndef NO_INLINE_APIS
+# define IX_QMGR_INLINE IX_OSAL_INLINE_EXTERN
+# else
+# define IX_QMGR_INLINE /* Empty Define */
+# endif
+#endif
+
+#else /* ndef __wince */
+
+# ifndef NO_INLINE_APIS
+# define NO_INLINE_APIS
+# endif
+# define IX_QMGR_INLINE
+
+#endif
+
+
+/**
+*
+* @ingroup IxQMgrAPI
+*
+* @def IX_QMGR_MAX_NUM_QUEUES
+*
+* @brief Number of queues supported by the AQM.
+*
+* This constant is used to indicate the number of AQM queues
+*
+*/
+#define IX_QMGR_MAX_NUM_QUEUES 64
+
+/**
+*
+* @ingroup IxQMgrAPI
+*
+* @def IX_QMGR_MIN_QID
+*
+* @brief Minimum queue identifier.
+*
+* This constant is used to indicate the smallest queue identifier
+*
+*/
+#define IX_QMGR_MIN_QID IX_QMGR_QUEUE_0
+
+/**
+*
+* @ingroup IxQMgrAPI
+*
+* @def IX_QMGR_MAX_QID
+*
+* @brief Maximum queue identifier.
+*
+* This constant is used to indicate the largest queue identifier
+*
+*/
+#define IX_QMGR_MAX_QID IX_QMGR_QUEUE_63
+
+/**
+*
+* @ingroup IxQMgrAPI
+*
+* @def IX_QMGR_MIN_QUEUPP_QID
+*
+* @brief Minimum queue identifier for reduced functionality queues.
+*
+* This constant is used to indicate Minimum queue identifier for reduced
+* functionality queues
+*
+*/
+#define IX_QMGR_MIN_QUEUPP_QID 32
+
+/**
+*
+* @ingroup IxQMgrAPI
+*
+* @def IX_QMGR_MAX_QNAME_LEN
+*
+* @brief Maximum queue name length.
+*
+* This constant is used to indicate the maximum null terminated string length
+* (excluding '\0') for a queue name
+*
+*/
+#define IX_QMGR_MAX_QNAME_LEN 16
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_WARNING
+ *
+ * @brief Warning return code.
+ *
+ * Execution complete, but there is a special case to handle
+ *
+ */
+#define IX_QMGR_WARNING 2
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_PARAMETER_ERROR
+ *
+ * @brief Parameter error return code (NULL pointer etc..).
+ *
+ * parameter error out of range/invalid
+ *
+ */
+#define IX_QMGR_PARAMETER_ERROR 3
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_INVALID_Q_ENTRY_SIZE
+ *
+ * @brief Invalid entry size return code.
+ *
+ * Invalid queue entry size for a queue read/write
+ *
+ */
+#define IX_QMGR_INVALID_Q_ENTRY_SIZE 4
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_INVALID_Q_ID
+ *
+ * @brief Invalid queue identifier return code.
+ *
+ * Invalid queue id, not in range 0-63
+ *
+ */
+#define IX_QMGR_INVALID_Q_ID 5
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_INVALID_CB_ID
+ *
+ * @brief Invalid callback identifier return code.
+ *
+ * Invalid callback id
+ */
+#define IX_QMGR_INVALID_CB_ID 6
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_CB_ALREADY_SET
+ *
+ * @brief Callback set error return code.
+ *
+ * The specified callback has already been for this queue
+ *
+ */
+#define IX_QMGR_CB_ALREADY_SET 7
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_NO_AVAILABLE_SRAM
+ *
+ * @brief Sram consumed return code.
+ *
+ * All AQM Sram is consumed by queue configuration
+ *
+ */
+#define IX_QMGR_NO_AVAILABLE_SRAM 8
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_INVALID_INT_SOURCE_ID
+ *
+ * @brief Invalid queue interrupt source identifier return code.
+ *
+ * Invalid queue interrupt source given for notification enable
+ */
+#define IX_QMGR_INVALID_INT_SOURCE_ID 9
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_INVALID_QSIZE
+ *
+ * @brief Invalid queue size error code.
+ *
+ * Invalid queue size not one of 16,32, 64, 128
+ *
+ *
+ */
+#define IX_QMGR_INVALID_QSIZE 10
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_INVALID_Q_WM
+ *
+ * @brief Invalid queue watermark return code.
+ *
+ * Invalid queue watermark given for watermark set
+ */
+#define IX_QMGR_INVALID_Q_WM 11
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_Q_NOT_CONFIGURED
+ *
+ * @brief Queue not configured return code.
+ *
+ * Returned to the client when a function has been called on an unconfigured
+ * queue
+ *
+ */
+#define IX_QMGR_Q_NOT_CONFIGURED 12
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_Q_ALREADY_CONFIGURED
+ *
+ * @brief Queue already configured return code.
+ *
+ * Returned to client to indicate that a queue has already been configured
+ */
+#define IX_QMGR_Q_ALREADY_CONFIGURED 13
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_Q_UNDERFLOW
+ *
+ * @brief Underflow return code.
+ *
+ * Underflow on a queue read has occurred
+ *
+ */
+#define IX_QMGR_Q_UNDERFLOW 14
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_Q_OVERFLOW
+ *
+ * @brief Overflow return code.
+ *
+ * Overflow on a queue write has occurred
+ *
+ */
+#define IX_QMGR_Q_OVERFLOW 15
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_Q_INVALID_PRIORITY
+ *
+ * @brief Invalid priority return code.
+ *
+ * Invalid priority, not one of 0,1,2
+ */
+#define IX_QMGR_Q_INVALID_PRIORITY 16
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS
+ *
+ * @brief Entry index out of bounds return code.
+ *
+ * Entry index is greater than number of entries in queue.
+ */
+#define IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS 17
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def ixQMgrDispatcherLoopRun
+ *
+ * @brief Map old function name ixQMgrDispatcherLoopRun ()
+ * to @ref ixQMgrDispatcherLoopRunA0 ().
+ *
+ */
+#define ixQMgrDispatcherLoopRun ixQMgrDispatcherLoopRunA0
+
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_QUEUE
+ *
+ * @brief Definition of AQM queue numbers
+ *
+ */
+#define IX_QMGR_QUEUE_0 (0) /**< Queue Number 0 */
+#define IX_QMGR_QUEUE_1 (1) /**< Queue Number 1 */
+#define IX_QMGR_QUEUE_2 (2) /**< Queue Number 2 */
+#define IX_QMGR_QUEUE_3 (3) /**< Queue Number 3 */
+#define IX_QMGR_QUEUE_4 (4) /**< Queue Number 4 */
+#define IX_QMGR_QUEUE_5 (5) /**< Queue Number 5 */
+#define IX_QMGR_QUEUE_6 (6) /**< Queue Number 6 */
+#define IX_QMGR_QUEUE_7 (7) /**< Queue Number 7 */
+#define IX_QMGR_QUEUE_8 (8) /**< Queue Number 8 */
+#define IX_QMGR_QUEUE_9 (9) /**< Queue Number 9 */
+#define IX_QMGR_QUEUE_10 (10) /**< Queue Number 10 */
+#define IX_QMGR_QUEUE_11 (11) /**< Queue Number 11 */
+#define IX_QMGR_QUEUE_12 (12) /**< Queue Number 12 */
+#define IX_QMGR_QUEUE_13 (13) /**< Queue Number 13 */
+#define IX_QMGR_QUEUE_14 (14) /**< Queue Number 14 */
+#define IX_QMGR_QUEUE_15 (15) /**< Queue Number 15 */
+#define IX_QMGR_QUEUE_16 (16) /**< Queue Number 16 */
+#define IX_QMGR_QUEUE_17 (17) /**< Queue Number 17 */
+#define IX_QMGR_QUEUE_18 (18) /**< Queue Number 18 */
+#define IX_QMGR_QUEUE_19 (19) /**< Queue Number 19 */
+#define IX_QMGR_QUEUE_20 (20) /**< Queue Number 20 */
+#define IX_QMGR_QUEUE_21 (21) /**< Queue Number 21 */
+#define IX_QMGR_QUEUE_22 (22) /**< Queue Number 22 */
+#define IX_QMGR_QUEUE_23 (23) /**< Queue Number 23 */
+#define IX_QMGR_QUEUE_24 (24) /**< Queue Number 24 */
+#define IX_QMGR_QUEUE_25 (25) /**< Queue Number 25 */
+#define IX_QMGR_QUEUE_26 (26) /**< Queue Number 26 */
+#define IX_QMGR_QUEUE_27 (27) /**< Queue Number 27 */
+#define IX_QMGR_QUEUE_28 (28) /**< Queue Number 28 */
+#define IX_QMGR_QUEUE_29 (29) /**< Queue Number 29 */
+#define IX_QMGR_QUEUE_30 (30) /**< Queue Number 30 */
+#define IX_QMGR_QUEUE_31 (31) /**< Queue Number 31 */
+#define IX_QMGR_QUEUE_32 (32) /**< Queue Number 32 */
+#define IX_QMGR_QUEUE_33 (33) /**< Queue Number 33 */
+#define IX_QMGR_QUEUE_34 (34) /**< Queue Number 34 */
+#define IX_QMGR_QUEUE_35 (35) /**< Queue Number 35 */
+#define IX_QMGR_QUEUE_36 (36) /**< Queue Number 36 */
+#define IX_QMGR_QUEUE_37 (37) /**< Queue Number 37 */
+#define IX_QMGR_QUEUE_38 (38) /**< Queue Number 38 */
+#define IX_QMGR_QUEUE_39 (39) /**< Queue Number 39 */
+#define IX_QMGR_QUEUE_40 (40) /**< Queue Number 40 */
+#define IX_QMGR_QUEUE_41 (41) /**< Queue Number 41 */
+#define IX_QMGR_QUEUE_42 (42) /**< Queue Number 42 */
+#define IX_QMGR_QUEUE_43 (43) /**< Queue Number 43 */
+#define IX_QMGR_QUEUE_44 (44) /**< Queue Number 44 */
+#define IX_QMGR_QUEUE_45 (45) /**< Queue Number 45 */
+#define IX_QMGR_QUEUE_46 (46) /**< Queue Number 46 */
+#define IX_QMGR_QUEUE_47 (47) /**< Queue Number 47 */
+#define IX_QMGR_QUEUE_48 (48) /**< Queue Number 48 */
+#define IX_QMGR_QUEUE_49 (49) /**< Queue Number 49 */
+#define IX_QMGR_QUEUE_50 (50) /**< Queue Number 50 */
+#define IX_QMGR_QUEUE_51 (51) /**< Queue Number 51 */
+#define IX_QMGR_QUEUE_52 (52) /**< Queue Number 52 */
+#define IX_QMGR_QUEUE_53 (53) /**< Queue Number 53 */
+#define IX_QMGR_QUEUE_54 (54) /**< Queue Number 54 */
+#define IX_QMGR_QUEUE_55 (55) /**< Queue Number 55 */
+#define IX_QMGR_QUEUE_56 (56) /**< Queue Number 56 */
+#define IX_QMGR_QUEUE_57 (57) /**< Queue Number 57 */
+#define IX_QMGR_QUEUE_58 (58) /**< Queue Number 58 */
+#define IX_QMGR_QUEUE_59 (59) /**< Queue Number 59 */
+#define IX_QMGR_QUEUE_60 (60) /**< Queue Number 60 */
+#define IX_QMGR_QUEUE_61 (61) /**< Queue Number 61 */
+#define IX_QMGR_QUEUE_62 (62) /**< Queue Number 62 */
+#define IX_QMGR_QUEUE_63 (63) /**< Queue Number 63 */
+#define IX_QMGR_QUEUE_INVALID (64) /**< AQM Queue Number Delimiter */
+
+
+/*
+ * Typedefs
+ */
+
+/**
+ * @typedef IxQMgrQId
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @brief Used in the API to identify the AQM queues.
+ *
+ */
+typedef int IxQMgrQId;
+
+/**
+ * @typedef IxQMgrQStatus
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @brief Queue status.
+ *
+ * A queues status is defined by its relative fullness or relative emptiness.
+ * Each of the queues 0-31 have Nearly Empty, Nearly Full, Empty, Full,
+ * Underflow and Overflow status flags. Queues 32-63 have just Nearly Empty and
+ * Full status flags.
+ * The flags bit positions are outlined below:
+ *
+ * OF - bit-5<br>
+ * UF - bit-4<br>
+ * F - bit-3<br>
+ * NF - bit-2<br>
+ * NE - bit-1<br>
+ * E - bit-0<br>
+ *
+ */
+typedef UINT32 IxQMgrQStatus;
+
+/**
+ * @enum IxQMgrQStatusMask
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @brief Queue status mask.
+ *
+ * Masks for extracting the individual status flags from the IxQMgrStatus
+ * word.
+ *
+ */
+typedef enum
+{
+ IX_QMGR_Q_STATUS_E_BIT_MASK = 0x1,
+ IX_QMGR_Q_STATUS_NE_BIT_MASK = 0x2,
+ IX_QMGR_Q_STATUS_NF_BIT_MASK = 0x4,
+ IX_QMGR_Q_STATUS_F_BIT_MASK = 0x8,
+ IX_QMGR_Q_STATUS_UF_BIT_MASK = 0x10,
+ IX_QMGR_Q_STATUS_OF_BIT_MASK = 0x20
+} IxQMgrQStatusMask;
+
+/**
+ * @enum IxQMgrSourceId
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @brief Queue interrupt source select.
+ *
+ * This enum defines the different source conditions on a queue that result in
+ * an interupt being fired by the AQM. Interrupt source is configurable for
+ * queues 0-31 only. The interrupt source for queues 32-63 is hardwired to the
+ * NE(Nearly Empty) status flag.
+ *
+ */
+typedef enum
+{
+ IX_QMGR_Q_SOURCE_ID_E = 0, /**< Queue Empty due to last read */
+ IX_QMGR_Q_SOURCE_ID_NE, /**< Queue Nearly Empty due to last read */
+ IX_QMGR_Q_SOURCE_ID_NF, /**< Queue Nearly Full due to last write */
+ IX_QMGR_Q_SOURCE_ID_F, /**< Queue Full due to last write */
+ IX_QMGR_Q_SOURCE_ID_NOT_E, /**< Queue Not Empty due to last write */
+ IX_QMGR_Q_SOURCE_ID_NOT_NE, /**< Queue Not Nearly Empty due to last write */
+ IX_QMGR_Q_SOURCE_ID_NOT_NF, /**< Queue Not Nearly Full due to last read */
+ IX_QMGR_Q_SOURCE_ID_NOT_F /**< Queue Not Full due to last read */
+} IxQMgrSourceId;
+
+/**
+ * @enum IxQMgrQEntrySizeInWords
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @brief QMgr queue entry sizes.
+ *
+ * The entry size of a queue specifies the size of a queues entry in words.
+ *
+ */
+typedef enum
+{
+ IX_QMGR_Q_ENTRY_SIZE1 = 1, /**< 1 word entry */
+ IX_QMGR_Q_ENTRY_SIZE2 = 2, /**< 2 word entry */
+ IX_QMGR_Q_ENTRY_SIZE4 = 4 /**< 4 word entry */
+} IxQMgrQEntrySizeInWords;
+
+/**
+ * @enum IxQMgrQSizeInWords
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @brief QMgr queue sizes.
+ *
+ * These values define the allowed queue sizes for AQM queue. The sizes are
+ * specified in words.
+ *
+ */
+typedef enum
+{
+ IX_QMGR_Q_SIZE16 = 16, /**< 16 word buffer */
+ IX_QMGR_Q_SIZE32 = 32, /**< 32 word buffer */
+ IX_QMGR_Q_SIZE64 = 64, /**< 64 word buffer */
+ IX_QMGR_Q_SIZE128 = 128, /**< 128 word buffer */
+ IX_QMGR_Q_SIZE_INVALID = 129 /**< Insure that this is greater than largest
+ * queue size supported by the hardware
+ */
+} IxQMgrQSizeInWords;
+
+/**
+ * @enum IxQMgrWMLevel
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @brief QMgr watermark levels.
+ *
+ * These values define the valid watermark levels(in ENTRIES) for queues. Each
+ * queue 0-63 have configurable Nearly full and Nearly empty watermarks. For
+ * queues 32-63 the Nearly full watermark has NO EFFECT.
+ * If the Nearly full watermark is set to IX_QMGR_Q_WM_LEVEL16 this means that
+ * the nearly full flag will be set by the hardware when there are >= 16 empty
+ * entries in the specified queue.
+ * If the Nearly empty watermark is set to IX_QMGR_Q_WM_LEVEL16 this means that
+ * the Nearly empty flag will be set by the hardware when there are <= 16 full
+ * entries in the specified queue.
+ */
+typedef enum
+{
+ IX_QMGR_Q_WM_LEVEL0 = 0, /**< 0 entry watermark */
+ IX_QMGR_Q_WM_LEVEL1 = 1, /**< 1 entry watermark */
+ IX_QMGR_Q_WM_LEVEL2 = 2, /**< 2 entry watermark */
+ IX_QMGR_Q_WM_LEVEL4 = 4, /**< 4 entry watermark */
+ IX_QMGR_Q_WM_LEVEL8 = 8, /**< 8 entry watermark */
+ IX_QMGR_Q_WM_LEVEL16 = 16, /**< 16 entry watermark */
+ IX_QMGR_Q_WM_LEVEL32 = 32, /**< 32 entry watermark */
+ IX_QMGR_Q_WM_LEVEL64 = 64 /**< 64 entry watermark */
+} IxQMgrWMLevel;
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @enum IxQMgrDispatchGroup
+ *
+ * @brief QMgr dispatch group select identifiers.
+ *
+ * This enum defines the groups over which the dispatcher will process when
+ * called. One of the enum values must be used as a input to
+ * @a ixQMgrDispatcherLoopRunA0, @a ixQMgrDispatcherLoopRunB0
+ * or @a ixQMgrDispatcherLoopRunB0LLP.
+ *
+ */
+typedef enum
+{
+ IX_QMGR_QUELOW_GROUP = 0, /**< Queues 0-31 */
+ IX_QMGR_QUEUPP_GROUP /**< Queues 32-63 */
+} IxQMgrDispatchGroup;
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @enum IxQMgrPriority
+ *
+ * @brief Dispatcher priority levels.
+ *
+ * This enum defines the different queue dispatch priority levels.
+ * The lowest priority number (0) is the highest priority level.
+ *
+ */
+typedef enum
+{
+ IX_QMGR_Q_PRIORITY_0 = 0, /**< Priority level 0 */
+ IX_QMGR_Q_PRIORITY_1, /**< Priority level 1 */
+ IX_QMGR_Q_PRIORITY_2, /**< Priority level 2 */
+ IX_QMGR_Q_PRIORITY_INVALID /**< Invalid Priority level */
+} IxQMgrPriority;
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @enum IxQMgrType
+ *
+ * @brief Callback types as used with livelock prevention
+ *
+ * This enum defines the different callback types.
+ * These types are only used when Livelock prevention is enabled.
+ * The default is IX_QMGR_TYPE_REALTIME_OTHER.
+ *
+ */
+
+typedef enum
+{
+ IX_QMGR_TYPE_REALTIME_OTHER = 0, /**< Real time callbacks-always allowed run*/
+ IX_QMGR_TYPE_REALTIME_PERIODIC, /**< Periodic callbacks-always allowed run */
+ IX_QMGR_TYPE_REALTIME_SPORADIC /**< Sporadic callbacks-only run if no
+ periodic callbacks are in progress */
+} IxQMgrType;
+
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @typedef IxQMgrCallbackId
+ *
+ * @brief Uniquely identifies a callback function.
+ *
+ * A unique callback identifier associated with each callback
+ * registered by clients.
+ *
+ */
+typedef unsigned IxQMgrCallbackId;
+
+/**
+ * @typedef IxQMgrCallback
+ *
+ * @brief QMgr notification callback type.
+ *
+ * This defines the interface to all client callback functions.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier
+ * @param cbId @ref IxQMgrCallbackId [in] - the callback identifier
+ */
+typedef void (*IxQMgrCallback)(IxQMgrQId qId,
+ IxQMgrCallbackId cbId);
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @typedef IxQMgrDispatcherFuncPtr
+ *
+ * @brief QMgr Dispatcher Loop function pointer.
+ *
+ * This defines the interface for QMgr Dispather functions.
+ *
+ * @param group @ref IxQMgrDispatchGroup [in] - the group of the
+ * queue of which the dispatcher will run
+ */
+typedef void (*IxQMgrDispatcherFuncPtr)(IxQMgrDispatchGroup group);
+
+/*
+ * Function Prototypes
+ */
+
+/* ------------------------------------------------------------
+ Initialisation related functions
+ ---------------------------------------------------------- */
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrInit (void)
+ *
+ * @brief Initialise the QMgr.
+ *
+ * This function must be called before and other QMgr function. It
+ * sets up internal data structures.
+ *
+ * @return @li IX_SUCCESS, the IxQMgr successfully initialised
+ * @return @li IX_FAIL, failed to initialize the Qmgr
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrInit (void);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrUnload (void)
+ *
+ * @brief Uninitialise the QMgr.
+ *
+ * This function will perform the tasks required to unload the QMgr component
+ * cleanly. This includes unmapping kernel memory.
+ * This should be called before a soft reboot or unloading of a kernel module.
+ *
+ * @pre It should only be called if @ref ixQMgrInit has already been called.
+ *
+ * @post No QMgr functions should be called until ixQMgrInit is called again.
+ *
+ * @return @li IX_SUCCESS, the IxQMgr successfully uninitialised
+ * @return @li IX_FAIL, failed to uninitialize the Qmgr
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrUnload (void);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrShow (void)
+ *
+ * @brief Describe queue configuration and statistics for active queues.
+ *
+ * This function shows active queues, their configurations and statistics.
+ *
+ * @return @li void
+ *
+ */
+PUBLIC void
+ixQMgrShow (void);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQShow (IxQMgrQId qId)
+ *
+ * @brief Display aqueue configuration and statistics for a queue.
+ *
+ * This function shows queue configuration and statistics for a queue.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier.
+ *
+ * @return @li IX_SUCCESS, success
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrQShow (IxQMgrQId qId);
+
+
+/* ------------------------------------------------------------
+ Configuration related functions
+ ---------------------------------------------------------- */
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQConfig (char *qName,
+ IxQMgrQId qId,
+ IxQMgrQSizeInWords qSizeInWords,
+ IxQMgrQEntrySizeInWords qEntrySizeInWords)
+ *
+ * @brief Configure an AQM queue.
+ *
+ * This function is called by a client to setup a queue. The size and entrySize
+ * qId and qName(NULL pointer) are checked for valid values. This function must
+ * be called for each queue, before any queue accesses are made and after
+ * ixQMgrInit() has been called. qName is assumed to be a '\0' terminated array
+ * of 16 charachters or less.
+ *
+ * @param *qName char [in] - is the name provided by the client and is associated
+ * with a QId by the QMgr.
+ * @param qId @ref IxQMgrQId [in] - the qId of this queue
+ * @param qSizeInWords @ref IxQMgrQSize [in] - the size of the queue can be one of 16,32
+ * 64, 128 words.
+ * @param qEntrySizeInWords @ref IxQMgrQEntrySizeInWords [in] - the size of a queue entry
+ * can be one of 1,2,4 words.
+ *
+ * @return @li IX_SUCCESS, a specified queue has been successfully configured.
+ * @return @li IX_FAIL, IxQMgr has not been initialised.
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid parameter(s).
+ * @return @li IX_QMGR_INVALID_QSIZE, invalid queue size
+ * @return @li IX_QMGR_INVALID_Q_ID, invalid queue id
+ * @return @li IX_QMGR_INVALID_Q_ENTRY_SIZE, invalid queue entry size
+ * @return @li IX_QMGR_Q_ALREADY_CONFIGURED, queue already configured
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrQConfig (char *qName,
+ IxQMgrQId qId,
+ IxQMgrQSizeInWords qSizeInWords,
+ IxQMgrQEntrySizeInWords qEntrySizeInWords);
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQSizeInEntriesGet (IxQMgrQId qId,
+ unsigned *qSizeInEntries)
+ *
+ * @brief Return the size of a queue in entries.
+ *
+ * This function returns the the size of the queue in entriese.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier
+ * @param *qSizeInEntries @ref IxQMgrQSize [out] - queue size in entries
+ *
+ * @return @li IX_SUCCESS, successfully retrieved the number of full entrie
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid parameter(s).
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrQSizeInEntriesGet (IxQMgrQId qId,
+ unsigned *qSizeInEntries);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrWatermarkSet (IxQMgrQId qId,
+ IxQMgrWMLevel ne,
+ IxQMgrWMLevel nf)
+ *
+ * @brief Set the Nearly Empty and Nearly Full Watermarks fo a queue.
+ *
+ * This function is called by a client to set the watermarks NE and NF for the
+ * queue specified by qId.
+ * The queue must be empty at the time this function is called, it is the clients
+ * responsibility to ensure that the queue is empty.
+ * This function will read the status of the queue before the watermarks are set
+ * and again after the watermarks are set. If the status register has changed,
+ * due to a queue access by an NPE for example, a warning is returned.
+ * Queues 32-63 only support the NE flag, therefore the value of nf will be ignored
+ * for these queues.
+ *
+ * @param qId @ref IxQMgrQId [in] - the QId of the queue.
+ * @param ne @ref IxQMgrWMLevel [in] - the NE(Nearly Empty) watermark for this
+ * queue. Valid values are 0,1,2,4,8,16,32 and
+ * 64 entries.
+ * @param nf @ref IxQMgrWMLevel [in] - the NF(Nearly Full) watermark for this queue.
+ * Valid values are 0,1,2,4,8,16,32 and 64
+ * entries.
+ *
+ * @return @li IX_SUCCESS, watermarks have been set for the queu
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId
+ * @return @li IX_QMGR_INVALID_Q_WM, invalid watermark
+ * @return @li IX_QMGR_WARNING, the status register may not be constistent
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrWatermarkSet (IxQMgrQId qId,
+ IxQMgrWMLevel ne,
+ IxQMgrWMLevel nf);
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrAvailableSramAddressGet (UINT32 *address,
+ unsigned *sizeOfFreeSram)
+ *
+ * @brief Return the address of available AQM SRAM.
+ *
+ * This function returns the starting address in AQM SRAM not used by the
+ * current queue configuration and should only be called after all queues
+ * have been configured.
+ * Calling this function before all queues have been configured will will return
+ * the currently available SRAM. A call to configure another queue will use some
+ * of the available SRAM.
+ * The amount of SRAM available is specified in sizeOfFreeSram. The address is the
+ * address of the bottom of available SRAM. Available SRAM extends from address
+ * from address to address + sizeOfFreeSram.
+ *
+ * @param **address UINT32 [out] - the address of the available SRAM, NULL if
+ * none available.
+ * @param *sizeOfFreeSram unsigned [out]- the size in words of available SRAM
+ *
+ * @return @li IX_SUCCESS, there is available SRAM and is pointed to by address
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid parameter(s)
+ * @return @li IX_QMGR_NO_AVAILABLE_SRAM, all AQM SRAM is consumed by the queue
+ * configuration.
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrAvailableSramAddressGet (UINT32 *address,
+ unsigned *sizeOfFreeSram);
+
+
+/* ------------------------------------------------------------
+ Queue access related functions
+ ---------------------------------------------------------- */
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQReadWithChecks (IxQMgrQId qId,
+ UINT32 *entry)
+ *
+ * @brief Read an entry from a queue.
+ *
+ * This function reads an entire entry from a queue returning it in entry. The
+ * queue configuration word is read to determine what entry size this queue is
+ * configured for and then the number of words specified by the entry size is
+ * read. entry must be a pointer to a previously allocated array of sufficient
+ * size to hold an entry.
+ *
+ * @note - IX_QMGR_Q_UNDERFLOW is only returned for queues 0-31 as queues 32-63
+ * do not have an underflow status maintained.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier.
+ * @param *entry UINT32 [out] - pointer to the entry word(s).
+ *
+ * @return @li IX_SUCCESS, entry was successfully read.
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid paramter(s).
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId
+ * @return @li IX_QMGR_Q_UNDERFLOW, attempt to read from an empty queue
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrQReadWithChecks (IxQMgrQId qId,
+ UINT32 *entry);
+
+
+
+/**
+ * @brief Internal structure to facilitate inlining functions in IxQMgr.h
+ */
+typedef struct
+{
+ /* fields related to write functions */
+ UINT32 qOflowStatBitMask; /**< overflow status mask */
+ UINT32 qWriteCount; /**< queue write count */
+
+ /* fields related to read and write functions */
+ volatile UINT32 *qAccRegAddr; /**< access register */
+ volatile UINT32 *qUOStatRegAddr; /**< status register */
+ volatile UINT32 *qConfigRegAddr; /**< config register */
+ UINT32 qEntrySizeInWords; /**< queue entry size in words */
+ UINT32 qSizeInEntries; /**< queue size in entries */
+
+ /* fields related to read functions */
+ UINT32 qUflowStatBitMask; /**< underflow status mask */
+ UINT32 qReadCount; /**< queue read count */
+} IxQMgrQInlinedReadWriteInfo;
+
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQReadMWordsMinus1 (IxQMgrQId qId,
+ UINT32 *entry)
+ *
+ * @brief This function reads the remaining of the q entry
+ * for queues configured with many words.
+ * (the first word of the entry is already read
+ * in the inlined function and the entry pointer already
+ * incremented
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier.
+ * @param *entry UINT32 [out] - pointer to the entry word(s).
+ *
+ * @return @li IX_SUCCESS, entry was successfully read.
+ * @return @li IX_QMGR_Q_UNDERFLOW, attempt to read from an empty queue
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrQReadMWordsMinus1 (IxQMgrQId qId,
+ UINT32 *entry);
+
+
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQRead (IxQMgrQId qId,
+ UINT32 *entry)
+ *
+ * @brief Fast read of an entry from a queue.
+ *
+ * This function is a heavily streamlined version of ixQMgrQReadWithChecks(),
+ * but performs essentially the same task. It reads an entire entry from a
+ * queue, returning it in entry which must be a pointer to a previously
+ * allocated array of sufficient size to hold an entry.
+ *
+ * @note - This function is inlined, to reduce unnecessary function call
+ * overhead. It does not perform any parameter checks, or update any statistics.
+ * Also, it does not check that the queue specified by qId has been configured.
+ * or is in range. It simply reads an entry from the queue, and checks for
+ * underflow.
+ *
+ * @note - IX_QMGR_Q_UNDERFLOW is only returned for queues 0-31 as queues 32-63
+ * do not have an underflow status maintained.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier.
+ * @param *entry UINT32 [out] - pointer to the entry word(s).
+ *
+ * @return @li IX_SUCCESS, entry was successfully read.
+ * @return @li IX_QMGR_Q_UNDERFLOW, attempt to read from an empty queue
+ *
+ */
+#ifdef NO_INLINE_APIS
+PUBLIC IX_STATUS
+ixQMgrQRead (IxQMgrQId qId,
+ UINT32 *entryPtr);
+#else
+extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
+extern IX_STATUS ixQMgrQReadMWordsMinus1 (IxQMgrQId qId, UINT32 *entryPtr);
+
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQRead (IxQMgrQId qId,
+ UINT32 *entryPtr);
+#endif
+
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQRead (IxQMgrQId qId,
+ UINT32 *entryPtr)
+#ifdef NO_INLINE_APIS
+ ;
+#else
+{
+ IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+ UINT32 entry, entrySize;
+
+ /* get a new entry */
+ entrySize = infoPtr->qEntrySizeInWords;
+ entry = IX_QMGR_INLINE_READ_LONG(infoPtr->qAccRegAddr);
+
+ if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
+ {
+ *entryPtr = entry;
+ /* process the remaining part of the entry */
+ return ixQMgrQReadMWordsMinus1(qId, entryPtr);
+ }
+
+ /* underflow is available for lower queues only */
+ if (qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ /* the counter of queue entries is decremented. In happy
+ * day scenario there are many entries in the queue
+ * and the counter does not reach zero.
+ */
+ if (infoPtr->qReadCount-- == 0)
+ {
+ /* There is maybe no entry in the queue
+ * qReadCount is now negative, but will be corrected before
+ * the function returns.
+ */
+ UINT32 qPtrs; /* queue internal pointers */
+
+ /* when a queue is empty, the hw guarantees to return
+ * a null value. If the value is not null, the queue is
+ * not empty.
+ */
+ if (entry == 0)
+ {
+ /* get the queue status */
+ UINT32 status = IX_QMGR_INLINE_READ_LONG(infoPtr->qUOStatRegAddr);
+
+ /* check the underflow status */
+ if (status & infoPtr->qUflowStatBitMask)
+ {
+ /* the queue is empty
+ * clear the underflow status bit if it was set
+ */
+ IX_QMGR_INLINE_WRITE_LONG(infoPtr->qUOStatRegAddr,
+ status & ~infoPtr->qUflowStatBitMask);
+ *entryPtr = 0;
+ infoPtr->qReadCount = 0;
+ return IX_QMGR_Q_UNDERFLOW;
+ }
+ }
+ /* store the result */
+ *entryPtr = entry;
+
+ /* No underflow occured : someone is filling the queue
+ * or the queue contains null entries.
+ * The current counter needs to be
+ * updated from the current number of entries in the queue
+ */
+
+ /* get snapshot of queue pointers */
+ qPtrs = IX_QMGR_INLINE_READ_LONG(infoPtr->qConfigRegAddr);
+
+ /* Mod subtraction of pointers to get number of words in Q. */
+ qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f;
+
+ if (qPtrs == 0)
+ {
+ /* no entry in the queue */
+ infoPtr->qReadCount = 0;
+ }
+ else
+ {
+ /* convert the number of words inside the queue
+ * to a number of entries
+ */
+ infoPtr->qReadCount = qPtrs & (infoPtr->qSizeInEntries - 1);
+ }
+ return IX_SUCCESS;
+ }
+ }
+ *entryPtr = entry;
+ return IX_SUCCESS;
+}
+#endif
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQBurstRead (IxQMgrQId qId,
+ UINT32 numEntries,
+ UINT32 *entries)
+ *
+ * @brief Read a number of entries from an AQM queue.
+ *
+ * This function will burst read a number of entries from the specified queue.
+ * The entry size of queue is auto-detected. The function will attempt to
+ * read as many entries as specified by the numEntries parameter and will
+ * return an UNDERFLOW if any one of the individual entry reads fail.
+ *
+ * @warning
+ * IX_QMGR_Q_UNDERFLOW is only returned for queues 0-31 as queues 32-63
+ * do not have an underflow status maintained, hence there is a potential for
+ * silent failure here. This function must be used with caution.
+ *
+ * @note
+ * This function is intended for fast draining of queues, so to make it
+ * as efficient as possible, it has the following features:
+ * - This function is inlined, to reduce unnecessary function call overhead.
+ * - It does not perform any parameter checks, or update any statistics.
+ * - It does not check that the queue specified by qId has been configured.
+ * - It does not check that the queue has the number of full entries that
+ * have been specified to be read. It will read until it finds a NULL entry or
+ * until the number of specified entries have been read. It always checks for
+ * underflow after all the reads have been performed.
+ * Therefore, the client should ensure before calling this function that there
+ * are enough entries in the queue to read. ixQMgrQNumEntriesGet() will
+ * provide the number of full entries in a queue.
+ * ixQMgrQRead() or ixQMgrQReadWithChecks(), which only reads
+ * a single queue entry per call, should be used instead if the user requires
+ * checks for UNDERFLOW after each entry read.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier.
+ * @param numEntries unsigned [in] - the number of entries to read.
+ * This number should be greater than 0
+ * @param *entries UINT32 [out] - the word(s) read.
+ *
+ * @return @li IX_SUCCESS, entries were successfully read.
+ * @return @li IX_QMGR_Q_UNDERFLOW, attempt to read from an empty queue
+ *
+ */
+#ifdef NO_INLINE_APIS
+PUBLIC IX_STATUS
+ixQMgrQBurstRead (IxQMgrQId qId,
+ UINT32 numEntries,
+ UINT32 *entries);
+#else
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQBurstRead (IxQMgrQId qId,
+ UINT32 numEntries,
+ UINT32 *entries);
+#endif /* endif NO_INLINE_APIS */
+
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQBurstRead (IxQMgrQId qId,
+ UINT32 numEntries,
+ UINT32 *entries)
+#ifdef NO_INLINE_APIS
+;
+#else
+{
+ IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+ UINT32 nullCheckEntry;
+
+ if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
+ {
+ volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
+
+ /* the code is optimized to take care of data dependencies:
+ * Durig a read, there are a few cycles needed to get the
+ * read complete. During these cycles, it is poossible to
+ * do some CPU, e.g. increment pointers and decrement
+ * counters.
+ */
+
+ /* fetch a queue entry */
+ nullCheckEntry = IX_QMGR_INLINE_READ_LONG(infoPtr->qAccRegAddr);
+
+ /* iterate the specified number of queue entries */
+ while (--numEntries)
+ {
+ /* check the result of the previous read */
+ if (nullCheckEntry == 0)
+ {
+ /* if we read a NULL entry, stop. We have underflowed */
+ break;
+ }
+ else
+ {
+ /* write the entry */
+ *entries = nullCheckEntry;
+ /* fetch next entry */
+ nullCheckEntry = IX_QMGR_INLINE_READ_LONG(qAccRegAddr);
+ /* increment the write address */
+ entries++;
+ }
+ }
+ /* write the pre-fetched entry */
+ *entries = nullCheckEntry;
+ }
+ else
+ {
+ IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
+ /* read the specified number of queue entries */
+ nullCheckEntry = 0;
+ while (numEntries--)
+ {
+ UINT32 i;
+
+ for (i = 0; i < (UINT32)entrySizeInWords; i++)
+ {
+ *entries = IX_QMGR_INLINE_READ_LONG(infoPtr->qAccRegAddr + i);
+ nullCheckEntry |= *entries++;
+ }
+
+ /* if we read a NULL entry, stop. We have underflowed */
+ if (nullCheckEntry == 0)
+ {
+ break;
+ }
+ nullCheckEntry = 0;
+ }
+ }
+
+ /* reset the current read count : next access to the read function
+ * will force a underflow status check
+ */
+ infoPtr->qReadCount = 0;
+
+ /* Check if underflow occurred on the read */
+ if (nullCheckEntry == 0 && qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ /* get the queue status */
+ UINT32 status = IX_QMGR_INLINE_READ_LONG(infoPtr->qUOStatRegAddr);
+
+ if (status & infoPtr->qUflowStatBitMask)
+ {
+ /* clear the underflow status bit if it was set */
+ IX_QMGR_INLINE_WRITE_LONG(infoPtr->qUOStatRegAddr,
+ status & ~infoPtr->qUflowStatBitMask);
+ return IX_QMGR_Q_UNDERFLOW;
+ }
+ }
+
+ return IX_SUCCESS;
+}
+#endif
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQPeek (IxQMgrQId qId,
+ unsigned int entryIndex,
+ UINT32 *entry)
+ *
+ * @brief Read an entry from a queue without moving the read pointer.
+ *
+ * This function inspects an entry in a queue. The entry is inspected directly
+ * in AQM SRAM and is not read from queue access registers. The entry is NOT removed
+ * from the queue and the read/write pointers are unchanged.
+ * N.B: The queue should not be accessed when this function is called.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier.
+ * @param entryIndex unsigned int [in] - index of entry in queue in the range
+ * [0].......[current number of entries in queue].
+ * @param *entry UINT32 [out] - pointer to the entry word(s).
+ *
+ * @return @li IX_SUCCESS, entry was successfully inspected.
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid paramter(s).
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId.
+ * @return @li IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS, an entry does not exist at
+ * specified index.
+ * @return @li IX_FAIL, failed to inpected the queue entry.
+ */
+PUBLIC IX_STATUS
+ixQMgrQPeek (IxQMgrQId qId,
+ unsigned int entryIndex,
+ UINT32 *entry);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQWriteWithChecks (IxQMgrQId qId,
+ UINT32 *entry)
+ *
+ * @brief Write an entry to an AQM queue.
+ *
+ * This function will write the entry size number of words pointed to by entry to
+ * the queue specified by qId. The queue configuration word is read to
+ * determine the entry size of queue and the corresponding number of words is
+ * then written to the queue.
+ *
+ * @note - IX_QMGR_Q_OVERFLOW is only returned for queues 0-31 as queues 32-63
+ * do not have an overflow status maintained.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier.
+ * @param *entry UINT32 [in] - the word(s) to write.
+ *
+ * @return @li IX_SUCCESS, value was successfully written.
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid paramter(s).
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId
+ * @return @li IX_QMGR_Q_OVERFLOW, attempt to write to a full queue
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrQWriteWithChecks (IxQMgrQId qId,
+ UINT32 *entry);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQWrite (IxQMgrQId qId,
+ UINT32 *entry)
+ *
+ * @brief Fast write of an entry to a queue.
+ *
+ * This function is a heavily streamlined version of ixQMgrQWriteWithChecks(),
+ * but performs essentially the same task. It will write the entry size number
+ * of words pointed to by entry to the queue specified by qId.
+ *
+ * @note - This function is inlined, to reduce unnecessary function call
+ * overhead. It does not perform any parameter checks, or update any
+ * statistics. Also, it does not check that the queue specified by qId has
+ * been configured. It simply writes an entry to the queue, and checks for
+ * overflow.
+ *
+ * @note - IX_QMGR_Q_OVERFLOW is only returned for queues 0-31 as queues 32-63
+ * do not have an overflow status maintained.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier.
+ * @param *entry UINT32 [in] - pointer to the entry word(s).
+ *
+ * @return @li IX_SUCCESS, entry was successfully read.
+ * @return @li IX_QMGR_Q_OVERFLOW, attempt to write to a full queue
+ *
+ */
+#ifdef NO_INLINE_APIS
+PUBLIC IX_STATUS
+ixQMgrQWrite (IxQMgrQId qId,
+ UINT32 *entry);
+#else
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQWrite (IxQMgrQId qId,
+ UINT32 *entry);
+#endif /* NO_INLINE_APIS */
+
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQWrite (IxQMgrQId qId,
+ UINT32 *entry)
+#ifdef NO_INLINE_APIS
+ ;
+#else
+{
+ IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+ UINT32 entrySize;
+
+ /* write the entry */
+ IX_QMGR_INLINE_WRITE_LONG(infoPtr->qAccRegAddr, *entry);
+ entrySize = infoPtr->qEntrySizeInWords;
+
+ if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
+ {
+ /* process the remaining part of the entry */
+ volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
+ while (--entrySize)
+ {
+ ++entry;
+ IX_QMGR_INLINE_WRITE_LONG(++qAccRegAddr, *entry);
+ }
+ entrySize = infoPtr->qEntrySizeInWords;
+ }
+
+ /* overflow is available for lower queues only */
+ if (qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ UINT32 qSize = infoPtr->qSizeInEntries;
+ /* increment the current number of entries in the queue
+ * and check for overflow
+ */
+ if (infoPtr->qWriteCount++ == qSize)
+ {
+ /* the queue may have overflow */
+ UINT32 qPtrs; /* queue internal pointers */
+
+ /* get the queue status */
+ UINT32 status = IX_QMGR_INLINE_READ_LONG(infoPtr->qUOStatRegAddr);
+
+ /* read the status twice because the status may
+ * not be immediately ready after the write operation
+ */
+ if ((status & infoPtr->qOflowStatBitMask) ||
+ ((status = IX_QMGR_INLINE_READ_LONG(infoPtr->qUOStatRegAddr))
+ & infoPtr->qOflowStatBitMask))
+ {
+ /* the queue is full, clear the overflow status
+ * bit if it was set
+ */
+ IX_QMGR_INLINE_WRITE_LONG(infoPtr->qUOStatRegAddr,
+ status & ~infoPtr->qOflowStatBitMask);
+ infoPtr->qWriteCount = infoPtr->qSizeInEntries;
+ return IX_QMGR_Q_OVERFLOW;
+ }
+ /* No overflow occured : someone is draining the queue
+ * and the current counter needs to be
+ * updated from the current number of entries in the queue
+ */
+
+ /* get q pointer snapshot */
+ qPtrs = IX_QMGR_INLINE_READ_LONG(infoPtr->qConfigRegAddr);
+
+ /* Mod subtraction of pointers to get number of words in Q. */
+ qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f;
+
+ if (qPtrs == 0)
+ {
+ /* the queue may be full at the time of the
+ * snapshot. Next access will check
+ * the overflow status again.
+ */
+ infoPtr->qWriteCount = qSize;
+ }
+ else
+ {
+ /* convert the number of words to a number of entries */
+ if (entrySize == IX_QMGR_Q_ENTRY_SIZE1)
+ {
+ infoPtr->qWriteCount = qPtrs & (qSize - 1);
+ }
+ else
+ {
+ infoPtr->qWriteCount = (qPtrs / entrySize) & (qSize - 1);
+ }
+ }
+ }
+ }
+ return IX_SUCCESS;
+}
+#endif
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQBurstWrite (IxQMgrQId qId,
+ unsigned numEntries,
+ UINT32 *entries)
+ *
+ * @brief Write a number of entries to an AQM queue.
+ *
+ * This function will burst write a number of entries to the specified queue.
+ * The entry size of queue is auto-detected. The function will attempt to
+ * write as many entries as specified by the numEntries parameter and will
+ * return an OVERFLOW if any one of the individual entry writes fail.
+ *
+ * @warning
+ * IX_QMGR_Q_OVERFLOW is only returned for queues 0-31 as queues 32-63
+ * do not have an overflow status maintained, hence there is a potential for
+ * silent failure here. This function must be used with caution.
+ *
+ * @note
+ * This function is intended for fast population of queues, so to make it
+ * as efficient as possible, it has the following features:
+ * - This function is inlined, to reduce unnecessary function call overhead.
+ * - It does not perform any parameter checks, or update any statistics.
+ * - It does not check that the queue specified by qId has been configured.
+ * - It does not check that the queue has enough free space to hold the entries
+ * before writing, and only checks for overflow after all writes have been
+ * performed. Therefore, the client should ensure before calling this function
+ * that there is enough free space in the queue to hold the number of entries
+ * to be written. ixQMgrQWrite() or ixQMgrQWriteWithChecks(), which only writes
+ * a single queue entry per call, should be used instead if the user requires
+ * checks for OVERFLOW after each entry written.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier.
+ * @param numEntries unsigned [in] - the number of entries to write.
+ * @param *entries UINT32 [in] - the word(s) to write.
+ *
+ * @return @li IX_SUCCESS, value was successfully written.
+ * @return @li IX_QMGR_Q_OVERFLOW, attempt to write to a full queue
+ *
+ */
+#ifdef NO_INLINE_APIS
+PUBLIC IX_STATUS
+ixQMgrQBurstWrite (IxQMgrQId qId,
+ unsigned numEntries,
+ UINT32 *entries);
+#else
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQBurstWrite (IxQMgrQId qId,
+ unsigned numEntries,
+ UINT32 *entries);
+#endif /* NO_INLINE_APIS */
+
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQBurstWrite (IxQMgrQId qId,
+ unsigned numEntries,
+ UINT32 *entries)
+#ifdef NO_INLINE_APIS
+;
+#else
+{
+ IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+ UINT32 status;
+
+ /* update the current write count */
+ infoPtr->qWriteCount += numEntries;
+
+ if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
+ {
+ volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
+ while (numEntries--)
+ {
+ IX_QMGR_INLINE_WRITE_LONG(qAccRegAddr, *entries);
+ entries++;
+ }
+ }
+ else
+ {
+ IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
+ UINT32 i;
+
+ /* write each queue entry */
+ while (numEntries--)
+ {
+ /* write the queueEntrySize number of words for each entry */
+ for (i = 0; i < (UINT32)entrySizeInWords; i++)
+ {
+ IX_QMGR_INLINE_WRITE_LONG((infoPtr->qAccRegAddr + i), *entries);
+ entries++;
+ }
+ }
+ }
+
+ /* check if the write count overflows */
+ if (infoPtr->qWriteCount > infoPtr->qSizeInEntries)
+ {
+ /* reset the current write count */
+ infoPtr->qWriteCount = infoPtr->qSizeInEntries;
+ }
+
+ /* Check if overflow occurred on the write operation */
+ if (qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ /* get the queue status */
+ status = IX_QMGR_INLINE_READ_LONG(infoPtr->qUOStatRegAddr);
+
+ /* read the status twice because the status may
+ * not be ready at the time of the write
+ */
+ if ((status & infoPtr->qOflowStatBitMask) ||
+ ((status = IX_QMGR_INLINE_READ_LONG(infoPtr->qUOStatRegAddr))
+ & infoPtr->qOflowStatBitMask))
+ {
+ /* clear the underflow status bit if it was set */
+ IX_QMGR_INLINE_WRITE_LONG(infoPtr->qUOStatRegAddr,
+ status & ~infoPtr->qOflowStatBitMask);
+ return IX_QMGR_Q_OVERFLOW;
+ }
+ }
+
+ return IX_SUCCESS;
+}
+#endif
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQPoke (IxQMgrQId qId,
+ unsigned int entryIndex,
+ UINT32 *entry)
+ *
+ * @brief Write an entry to a queue without moving the write pointer.
+ *
+ * This function modifies an entry in a queue. The entry is modified directly
+ * in AQM SRAM and not using the queue access registers. The entry is NOT added to the
+ * queue and the read/write pointers are unchanged.
+ * N.B: The queue should not be accessed when this function is called.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier.
+ * @param entryIndex unsigned int [in] - index of entry in queue in the range
+ * [0].......[current number of entries in queue].
+ * @param *entry UINT32 [in] - pointer to the entry word(s).
+ *
+ * @return @li IX_SUCCESS, entry was successfully modified.
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid paramter(s).
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId.
+ * @return @li IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS, an entry does not exist at
+ * specified index.
+ * @return @li IX_FAIL, failed to modify the queue entry.
+ */
+PUBLIC IX_STATUS
+ixQMgrQPoke (IxQMgrQId qId,
+ unsigned int entryIndex,
+ UINT32 *entry);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQNumEntriesGet (IxQMgrQId qId,
+ unsigned *numEntries)
+ *
+ * @brief Get a snapshot of the number of entries in a queue.
+ *
+ * This function gets the number of entries in a queue.
+ *
+ * @param qId @ref IxQMgrQId [in] qId - the queue idenfifier
+ * @param *numEntries unsigned [out] - the number of entries in a queue
+ *
+ * @return @li IX_SUCCESS, got the number of entries for the queue
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid paramter(s).
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, the specified qId has not been configured
+ * @return @li IX_QMGR_WARNING, could not determine num entries at this time
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrQNumEntriesGet (IxQMgrQId qId,
+ unsigned *numEntries);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQStatusGetWithChecks (IxQMgrQId qId,
+ IxQMgrQStatus *qStatus)
+ *
+ * @brief Get a queues status.
+ *
+ * This function reads the specified queues status. A queues status is defined
+ * by its status flags. For queues 0-31 these flags are E,NE,NF,F. For
+ * queues 32-63 these flags are NE and F.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier.
+ * @param &qStatus @ref IxQMgrQStatus [out] - the status of the specified queue.
+ *
+ * @return @li IX_SUCCESS, queue status was successfully read.
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, the specified qId has not been configured
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid paramter.
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrQStatusGetWithChecks (IxQMgrQId qId,
+ IxQMgrQStatus *qStatus);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQStatusGet (IxQMgrQId qId,
+ IxQMgrQStatus *qStatus)
+ *
+ * @brief Fast get of a queue's status.
+ *
+ * This function is a streamlined version of ixQMgrQStatusGetWithChecks(), but
+ * performs essentially the same task. It reads the specified queue's status.
+ * A queues status is defined by its status flags. For queues 0-31 these flags
+ * are E,NE,NF,F. For queues 32-63 these flags are NE and F.
+ *
+ * @note - This function is inlined, to reduce unnecessary function call
+ * overhead. It does not perform any parameter checks, or update any
+ * statistics. Also, it does not check that the queue specified by qId has
+ * been configured. It simply reads the specified queue's status.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier.
+ * @param *qStatus @ref IxQMgrQStatus [out] - the status of the specified queue.
+ *
+ * @return @li void.
+ *
+ */
+
+#ifdef NO_INLINE_APIS
+PUBLIC IX_STATUS
+ixQMgrQStatusGet (IxQMgrQId qId,
+ IxQMgrQStatus *qStatus);
+#else
+extern UINT32 ixQMgrAqmIfQueLowStatRegAddr[];
+extern UINT32 ixQMgrAqmIfQueLowStatBitsOffset[];
+extern UINT32 ixQMgrAqmIfQueLowStatBitsMask;
+extern UINT32 ixQMgrAqmIfQueUppStat0RegAddr;
+extern UINT32 ixQMgrAqmIfQueUppStat1RegAddr;
+extern UINT32 ixQMgrAqmIfQueUppStat0BitMask[];
+extern UINT32 ixQMgrAqmIfQueUppStat1BitMask[];
+
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQStatusGet (IxQMgrQId qId,
+ IxQMgrQStatus *qStatus);
+#endif /* endif NO_INLINE_APIS */
+
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQStatusGet (IxQMgrQId qId,
+ IxQMgrQStatus *qStatus)
+#ifdef NO_INLINE_APIS
+ ;
+#else
+{
+ /* read the status of a queue in the range 0-31 */
+ if (qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ volatile UINT32 *lowStatRegAddr = (UINT32*)ixQMgrAqmIfQueLowStatRegAddr[qId];
+
+ UINT32 lowStatBitsOffset = ixQMgrAqmIfQueLowStatBitsOffset[qId];
+ UINT32 lowStatBitsMask = ixQMgrAqmIfQueLowStatBitsMask;
+
+ /* read the status register for this queue */
+ *qStatus = IX_QMGR_INLINE_READ_LONG(lowStatRegAddr);
+
+ /* mask out the status bits relevant only to this queue */
+ *qStatus = (*qStatus >> lowStatBitsOffset) & lowStatBitsMask;
+
+ }
+ else /* read status of a queue in the range 32-63 */
+ {
+
+ volatile UINT32 *qNearEmptyStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat0RegAddr;
+ volatile UINT32 *qFullStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat1RegAddr;
+ int maskIndex = qId - IX_QMGR_MIN_QUEUPP_QID;
+ UINT32 qNearEmptyStatBitMask = ixQMgrAqmIfQueUppStat0BitMask[maskIndex];
+ UINT32 qFullStatBitMask = ixQMgrAqmIfQueUppStat1BitMask[maskIndex];
+
+ /* Reset the status bits */
+ *qStatus = 0;
+
+ /* Check if the queue is nearly empty */
+ if (IX_QMGR_INLINE_READ_LONG(qNearEmptyStatRegAddr) & qNearEmptyStatBitMask)
+ {
+ *qStatus |= IX_QMGR_Q_STATUS_NE_BIT_MASK;
+ }
+
+ /* Check if the queue is full */
+ if (IX_QMGR_INLINE_READ_LONG(qFullStatRegAddr) & qFullStatBitMask)
+ {
+ *qStatus |= IX_QMGR_Q_STATUS_F_BIT_MASK;
+ }
+ }
+ return IX_SUCCESS;
+}
+#endif
+
+/* ------------------------------------------------------------
+ Queue dispatch related functions
+ ---------------------------------------------------------- */
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrDispatcherPrioritySet (IxQMgrQId qId,
+ IxQMgrPriority priority)
+ *
+ * @brief Set the dispatch priority of a queue.
+ *
+ * This function is called to set the dispatch priority of queue. The effect of
+ * this function is to add a priority change request to a queue. This queue is
+ * serviced by @a ixQMgrDispatcherLoopRunA0, @a ixQMgrDispatcherLoopRunB0 or
+ * @a ixQMgrDispatcherLoopRunB0LLP.
+ *
+ * This function is re-entrant. and can be used from an interrupt context
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier
+ * @param priority @ref IxQMgrPriority [in] - the new queue dispatch priority
+ *
+ * @return @li IX_SUCCESS, priority change request is queued
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, the specified qId has not been configured
+ * @return @li IX_QMGR_Q_INVALID_PRIORITY, specified priority is invalid
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrDispatcherPrioritySet (IxQMgrQId qId,
+ IxQMgrPriority priority);
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrNotificationEnable (IxQMgrQId qId,
+ IxQMgrSourceId sourceId)
+ *
+ * @brief Enable notification on a queue for a specified queue source flag.
+ *
+ * This function is called by a client of the QMgr to enable notifications on a
+ * specified condition.
+ * If the condition for the notification is set after the client has called this
+ * function but before the function has enabled the interrupt source, then the
+ * notification will not occur.
+ * For queues 32-63 the notification source is fixed to the NE(Nearly Empty) flag
+ * and cannot be changed so the sourceId parameter is ignored for these queues.
+ * The status register is read before the notofication is enabled and is read again
+ * after the notification has been enabled, if they differ then the warning status
+ * is returned.
+ *
+ * This function is re-entrant. and can be used from an interrupt context
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier
+ * @param sourceId @ref IxQMgrSourceId [in] - the interrupt src condition identifier
+ *
+ * @return @li IX_SUCCESS, the interrupt has been enabled for the specified source
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, the specified qId has not been configured
+ * @return @li IX_QMGR_INVALID_INT_SOURCE_ID, interrupt source invalid for this queue
+ * @return @li IX_QMGR_WARNING, the status register may not be constistent
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrNotificationEnable (IxQMgrQId qId,
+ IxQMgrSourceId sourceId);
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrNotificationDisable (IxQMgrQId qId)
+ *
+ * @brief Disable notifications on a queue.
+ *
+ * This function is called to disable notifications on a specified queue.
+ *
+ * This function is re-entrant. and can be used from an interrupt context
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier
+ *
+ * @return @li IX_SUCCESS, the interrupt has been disabled
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, the specified qId has not been configured
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrNotificationDisable (IxQMgrQId qId);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrDispatcherLoopRunA0 (IxQMgrDispatchGroup group)
+ *
+ * @brief Run the callback dispatcher.
+ *
+ * This function runs the dispatcher for a group of queues.
+ * Callbacks are made for interrupts that have occurred on queues within
+ * the group that have registered callbacks. The order in which queues are
+ * serviced depends on the queue priorities set by the client.
+ * This function may be called from interrupt or task context.
+ * For optimisations that were introduced in IXP42X B0 and supported IXP46X
+ * the @a ixQMgrDispatcherLoopRunB0, or @a ixQMgrDispatcherLoopRunB0LLP
+ * should be used.
+ *
+ * This function is not re-entrant.
+ *
+ * @param group @ref IxQMgrDispatchGroup [in] - the group of queues over which the
+ * dispatcher will run
+ *
+ * @return @li void
+ *
+ * @note This function may be called from interrupt or task context.
+ * However, for optimal performance the choice of context depends also on the
+ * operating system used.
+ *
+ */
+PUBLIC void
+ixQMgrDispatcherLoopRunA0 (IxQMgrDispatchGroup group);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrDispatcherLoopRunB0 (IxQMgrDispatchGroup group)
+ *
+ * @brief Run the callback dispatcher.
+ *
+ * The enhanced version of @a ixQMgrDispatcherLoopRunA0 that is optimised for
+ * features introduced in IXP42X B0 silicon and supported on IXP46X.
+ * This is the default dispatcher for IXP42X B0 and IXP46X silicon.
+ * The function runs the dispatcher for a group of queues.
+ * Callbacks are made for interrupts that have occurred on queues within
+ * the group that have registered callbacks. The order in which queues are
+ * serviced depends on the queue priorities set by the client.
+ * This function may be called from interrupt or task context.
+ *
+ * This function is not re-entrant.
+ *
+ * @param group @ref IxQMgrDispatchGroup [in] - the group of queues over which the
+ * dispatcher will run
+ *
+ * @return @li void
+ *
+ *
+ * @note This function may be called from interrupt or task context.
+ * However, for optimal performance the choice of context depends also on the
+ * operating system used.
+ *
+ */
+PUBLIC void
+ixQMgrDispatcherLoopRunB0 (IxQMgrDispatchGroup group);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrDispatcherLoopRunB0LLP (IxQMgrDispatchGroup group)
+ *
+ * @brief Run the callback dispatcher.
+ *
+ * This is a version of the optimised dispatcher for IXP42X B0 and IXP46X,
+ * @a ixQMgrDispatcherLoopRunB0, with added support for livelock prevention.
+ * This dispatcher will only be used for the IXP42X B0 or IXP46X silicon if
+ * feature control indicates that IX_FEATURECTRL_ORIGB0_DISPATCHER is set to
+ * IX_FEATURE_CTRL_SWCONFIG_DISABLED. Otherwise the @a ixQMgrDispatcherLoopRunB0
+ * dispatcher will be used (Default).
+ *
+ * When this dispatcher notifies for a queue that is type
+ * IX_QMGR_TYPE_REALTIME_PERIODIC, notifications for queues that are set
+ * as type IX_QMGR_REALTIME_SPORADIC are not processed and disabled.
+ * This helps prevent any tasks resulting from the notification of the
+ * IX_QMGR_TYPE_REALTIME_PERIODIC type queue to being subject to livelock.
+ * The function runs the dispatcher for a group of queues.
+ * Callbacks are made for interrupts that have occurred on queues within
+ * the group that have registered callbacks. The order in which queues are
+ * serviced depends on their type along with the queue priorities set by the
+ * client. This function may be called from interrupt or task context.
+ *
+ * This function is not re-entrant.
+ *
+ * @param group @ref IxQMgrDispatchGroup [in] - the group of queues over which
+ * the dispatcher will run
+ *
+ * @return @li void
+ *
+ * @note This function may be called from interrupt or task context.
+ * However, for optimal performance the choice of context depends also on the
+ * operating system used.
+ *
+ */
+PUBLIC void
+ixQMgrDispatcherLoopRunB0LLP (IxQMgrDispatchGroup group);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrNotificationCallbackSet (IxQMgrQId qId,
+ IxQMgrCallback callback,
+ IxQMgrCallbackId callbackId)
+ *
+ * @brief Set the notification callback for a queue.
+ *
+ * This function sets the callback for the specified queue. This callback will
+ * be called by the dispatcher, and may be called in the context of a interrupt
+ * If callback has a value of NULL the previously registered callback, if one
+ * exists will be unregistered.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue idenfifier
+ * @param callback @ref IxQMgrCallback [in] - the callback registered for this queue
+ * @param callbackId @ref IxQMgrCallbackId [in] - the callback identifier
+ *
+ * @return @li IX_SUCCESS, the callback for the specified queue has been set
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, the specified qId has not been configured
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrNotificationCallbackSet (IxQMgrQId qId,
+ IxQMgrCallback callback,
+ IxQMgrCallbackId callbackId);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrDispatcherLoopGet (IxQMgrDispatcherFuncPtr *qDispatcherFuncPtr)
+ *
+ * @brief Get QMgr DispatcherLoopRun for respective silicon device
+ *
+ * This function gets a function pointer to ixQMgrDispatcherLoopRunA0() for IXP42X A0
+ * Silicon. If the IXP42X B0 or 46X Silicon, the default is the ixQMgrDispatcherLoopRunB0()
+ * function, however if live lock prevention is enabled a function pointer to
+ * ixQMgrDispatcherLoopRunB0LLP() is given.
+ *
+ * @param *qDispatchFuncPtr @ref IxQMgrDispatcherFuncPtr [out] -
+ * the function pointer of QMgr Dispatcher
+ *
+ */
+PUBLIC void
+ixQMgrDispatcherLoopGet (IxQMgrDispatcherFuncPtr *qDispatcherFuncPtr);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrStickyInterruptRegEnable(void)
+ *
+ * @brief Enable AQM's sticky interrupt register behaviour only available
+ * on B0 Silicon.
+ *
+ * When AQM's sticky interrupt register is enabled, interrupt register bit will
+ * only be cleared when a '1' is written to interrupt register bit and the
+ * interrupting condition is satisfied, i.e.queue condition does not exist.
+ *
+ * @note This function must be called before any queue is enabled.
+ * Calling this function after queue is enabled will cause
+ * undefined results.
+ *
+ * @return none
+ *
+ */
+PUBLIC void
+ixQMgrStickyInterruptRegEnable(void);
+
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrCallbackTypeSet(IxQMgrQId qId,
+ IxQMgrType type)
+ *
+ * @brief Set the Callback Type of a queue.
+ *
+ * This function is only used for live lock prevention.
+ * This function allows the callback type of a queue to be set. The default for
+ * all queues is IX_QMGR_TYPE_REALTIME_OTHER. Setting the type to
+ * IX_QMGR_TYPE_REALTIME_SPORADIC means that this queue will have it's
+ * notifications disabled while there is a task associated with a
+ * queue of type IX_QMGR_TYPE_REALTIME_PERIODIC running. As live lock
+ * prevention operates on lower queues, this function should
+ * be called for lower queues only.
+ * This function is not re-entrant.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier
+ * @param type @ref IxQMgrType [in] - the type of callback
+ *
+ * @return @li IX_SUCCESS, successfully set callback type for the queue entry
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid parameter(s).
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrCallbackTypeSet(IxQMgrQId qId,
+ IxQMgrType type);
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrCallbackTypeGet(IxQMgrQId qId,
+ IxQMgrType *type)
+ *
+ * @brief Get the Callback Type of a queue.
+ *
+ * This function allows the callback type of a queue to be got. As live lock
+ * prevention operates on lower queues, this function should
+ * be called for lower queues only.
+ * This function is re-entrant.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier
+ * @param *type @ref IxQMgrType [out] - the type of callback
+ *
+ * @return @li IX_SUCCESS, successfully set callback type for the queue entry
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid parameter(s)
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrCallbackTypeGet(IxQMgrQId qId,
+ IxQMgrType *type);
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrPeriodicDone(void)
+ *
+ * @brief Indicate that the Periodic task is completed for LLP
+ *
+ * This function is used as part of live lock prevention.
+ * A periodic task is a task that results from a queue that
+ * is set as type IX_QMGR_TYPE_REALTIME_PERIODIC. This function
+ * should be called to indicate to the dispatcher that the
+ * the periodic task is completed. This ensures that the notifications
+ * for queues set as type sporadic queues are re-enabled.
+ * This function is re-entrant.
+ *
+ */
+PUBLIC void
+ixQMgrPeriodicDone(void);
+
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrLLPShow(int resetStats)
+ *
+ * @brief Print out the live lock prevention statistics when in debug mode.
+ *
+ * This function prints out statistics related to the livelock. These
+ * statistics are only collected in debug mode.
+ * This function is not re-entrant.
+ *
+ * @param resetStats @ref int [in] - if set the the stats are reset.
+ *
+ */
+PUBLIC void
+ixQMgrLLPShow(int resetStats);
+
+
+#endif /* IXQMGR_H */
+
+/**
+ * @} defgroup IxQMgrAPI
+ */
+
+
diff --git a/cpu/ixp/npe/include/IxQMgrAqmIf_p.h b/cpu/ixp/npe/include/IxQMgrAqmIf_p.h
new file mode 100644
index 0000000..7f5733c
--- /dev/null
+++ b/cpu/ixp/npe/include/IxQMgrAqmIf_p.h
@@ -0,0 +1,927 @@
+/**
+ * @file IxQMgrAqmIf_p.h
+ *
+ * @author Intel Corporation
+ * @date 30-Oct-2001
+ *
+ * @brief The IxQMgrAqmIf sub-component provides a number of inline
+ * functions for performing I/O on the AQM.
+ *
+ * Because some functions contained in this module are inline and are
+ * used in other modules (within the QMgr component) the definitions are
+ * contained in this header file. The "normal" use of inline functions
+ * is to use the inline functions in the module in which they are
+ * defined. In this case these inline functions are used in external
+ * modules and therefore the use of "inline extern". What this means
+ * is as follows: if a function foo is declared as "inline extern"this
+ * definition is only used for inlining, in no case is the function
+ * compiled on its own. If the compiler cannot inline the function it
+ * becomes an external reference. Therefore in IxQMgrAqmIf.c all
+ * inline functions are defined without the "inline extern" specifier
+ * and so define the external references. In all other modules these
+ * funtions are defined as "inline extern".
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+#ifndef IXQMGRAQMIF_P_H
+#define IXQMGRAQMIF_P_H
+
+#include "IxOsalTypes.h"
+
+/*
+ * inline definition
+ */
+
+#ifdef IX_OSAL_INLINE_ALL
+/* If IX_OSAL_INLINE_ALL is set then each inlineable API functions will be defined as
+ inline functions */
+#define IX_QMGR_AQMIF_INLINE IX_OSAL_INLINE_EXTERN
+#else
+#ifdef IXQMGRAQMIF_C
+#ifndef IX_QMGR_AQMIF_INLINE
+#define IX_QMGR_AQMIF_INLINE
+#endif
+#else
+#ifndef IX_QMGR_AQMIF_INLINE
+#define IX_QMGR_AQMIF_INLINE IX_OSAL_INLINE_EXTERN
+#endif
+#endif /* IXQMGRAQMIF_C */
+#endif /* IX_OSAL_INLINE */
+
+
+/*
+ * User defined include files.
+ */
+#include "IxQMgr.h"
+#include "IxQMgrLog_p.h"
+#include "IxQMgrQCfg_p.h"
+
+/* Because this file contains inline functions which will be compiled into
+ * other components, we need to ensure that the IX_COMPONENT_NAME define
+ * is set to ix_qmgr while this code is being compiled. This will ensure
+ * that the correct implementation is provided for the memory access macros
+ * IX_OSAL_READ_LONG and IX_OSAL_WRITE_LONG which are used in this file.
+ * This must be done before including "IxOsalMemAccess.h"
+ */
+#define IX_QMGR_AQMIF_SAVED_COMPONENT_NAME IX_COMPONENT_NAME
+#undef IX_COMPONENT_NAME
+#define IX_COMPONENT_NAME ix_qmgr
+#include "IxOsal.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/* Number of bytes per word */
+#define IX_QMGR_NUM_BYTES_PER_WORD 4
+
+/* Underflow bit mask */
+#define IX_QMGR_UNDERFLOW_BIT_OFFSET 0x0
+
+/* Overflow bit mask */
+#define IX_QMGR_OVERFLOW_BIT_OFFSET 0x1
+
+/* Queue access register, queue 0 */
+#define IX_QMGR_QUEACC0_OFFSET 0x0000
+
+/* Size of queue access register in words */
+#define IX_QMGR_QUEACC_SIZE 0x4/*words*/
+
+/* Queue status register, queues 0-7 */
+#define IX_QMGR_QUELOWSTAT0_OFFSET (IX_QMGR_QUEACC0_OFFSET +\
+(IX_QMGR_MAX_NUM_QUEUES * IX_QMGR_QUEACC_SIZE * IX_QMGR_NUM_BYTES_PER_WORD))
+
+/* Queue status register, queues 8-15 */
+#define IX_QMGR_QUELOWSTAT1_OFFSET (IX_QMGR_QUELOWSTAT0_OFFSET +\
+ IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue status register, queues 16-23 */
+#define IX_QMGR_QUELOWSTAT2_OFFSET (IX_QMGR_QUELOWSTAT1_OFFSET +\
+ IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue status register, queues 24-31 */
+#define IX_QMGR_QUELOWSTAT3_OFFSET (IX_QMGR_QUELOWSTAT2_OFFSET +\
+ IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue status register Q status bits mask */
+#define IX_QMGR_QUELOWSTAT_QUE_STS_BITS_MASK 0xF
+
+/* Size of queue 0-31 status register */
+#define IX_QMGR_QUELOWSTAT_SIZE 0x4 /*words*/
+
+/* The number of queues' status specified per word */
+#define IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD 0x8
+
+/* Queue UF/OF status register queues 0-15 */
+#define IX_QMGR_QUEUOSTAT0_OFFSET (IX_QMGR_QUELOWSTAT3_OFFSET +\
+ IX_QMGR_NUM_BYTES_PER_WORD)
+/* Queue UF/OF status register queues 16-31 */
+#define IX_QMGR_QUEUOSTAT1_OFFSET (IX_QMGR_QUEUOSTAT0_OFFSET +\
+ IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* The number of queues' underflow/overflow status specified per word */
+#define IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD 0x10
+
+/* Queue NE status register, queues 32-63 */
+#define IX_QMGR_QUEUPPSTAT0_OFFSET (IX_QMGR_QUEUOSTAT1_OFFSET +\
+ IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue F status register, queues 32-63 */
+#define IX_QMGR_QUEUPPSTAT1_OFFSET (IX_QMGR_QUEUPPSTAT0_OFFSET +\
+ IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Size of queue 32-63 status register */
+#define IX_QMGR_QUEUPPSTAT_SIZE 0x2 /*words*/
+
+/* The number of queues' status specified per word */
+#define IX_QMGR_QUEUPPSTAT_NUM_QUE_PER_WORD 0x20
+
+/* Queue INT source select register, queues 0-7 */
+#define IX_QMGR_INT0SRCSELREG0_OFFSET (IX_QMGR_QUEUPPSTAT1_OFFSET +\
+ IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue INT source select register, queues 8-15 */
+#define IX_QMGR_INT0SRCSELREG1_OFFSET (IX_QMGR_INT0SRCSELREG0_OFFSET+\
+ IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue INT source select register, queues 16-23 */
+#define IX_QMGR_INT0SRCSELREG2_OFFSET (IX_QMGR_INT0SRCSELREG1_OFFSET+\
+ IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue INT source select register, queues 24-31 */
+#define IX_QMGR_INT0SRCSELREG3_OFFSET (IX_QMGR_INT0SRCSELREG2_OFFSET+\
+ IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Size of interrupt source select reegister */
+#define IX_QMGR_INT0SRCSELREG_SIZE 0x4 /*words*/
+
+/* The number of queues' interrupt source select specified per word*/
+#define IX_QMGR_INTSRC_NUM_QUE_PER_WORD 0x8
+
+/* Queue INT enable register, queues 0-31 */
+#define IX_QMGR_QUEIEREG0_OFFSET (IX_QMGR_INT0SRCSELREG3_OFFSET +\
+ IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue INT enable register, queues 32-63 */
+#define IX_QMGR_QUEIEREG1_OFFSET (IX_QMGR_QUEIEREG0_OFFSET +\
+ IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue INT register, queues 0-31 */
+#define IX_QMGR_QINTREG0_OFFSET (IX_QMGR_QUEIEREG1_OFFSET +\
+ IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue INT register, queues 32-63 */
+#define IX_QMGR_QINTREG1_OFFSET (IX_QMGR_QINTREG0_OFFSET +\
+ IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Size of interrupt register */
+#define IX_QMGR_QINTREG_SIZE 0x2 /*words*/
+
+/* Number of queues' status specified per word */
+#define IX_QMGR_QINTREG_NUM_QUE_PER_WORD 0x20
+
+/* Number of bits per queue interrupt status */
+#define IX_QMGR_QINTREG_BITS_PER_QUEUE 0x1
+#define IX_QMGR_QINTREG_BIT_OFFSET 0x1
+
+/* Size of address space not used by AQM */
+#define IX_QMGR_AQM_UNUSED_ADDRESS_SPACE_SIZE_IN_BYTES 0x1bC0
+
+/* Queue config register, queue 0 */
+#define IX_QMGR_QUECONFIG_BASE_OFFSET (IX_QMGR_QINTREG1_OFFSET +\
+ IX_QMGR_NUM_BYTES_PER_WORD +\
+ IX_QMGR_AQM_UNUSED_ADDRESS_SPACE_SIZE_IN_BYTES)
+
+/* Total size of configuration words */
+#define IX_QMGR_QUECONFIG_SIZE 0x100
+
+/* Start of SRAM queue buffer space */
+#define IX_QMGR_QUEBUFFER_SPACE_OFFSET (IX_QMGR_QUECONFIG_BASE_OFFSET +\
+ IX_QMGR_MAX_NUM_QUEUES * IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Total bits in a word */
+#define BITS_PER_WORD 32
+
+/* Size of queue buffer space */
+#define IX_QMGR_QUE_BUFFER_SPACE_SIZE 0x1F00
+
+/*
+ * This macro will return the address of the access register for the
+ * queue specified by qId
+ */
+#define IX_QMGR_Q_ACCESS_ADDR_GET(qId)\
+ (((qId) * (IX_QMGR_QUEACC_SIZE * IX_QMGR_NUM_BYTES_PER_WORD))\
+ + IX_QMGR_QUEACC0_OFFSET)
+
+/*
+ * Bit location of bit-3 of INT0SRCSELREG0 register to enabled
+ * sticky interrupt register.
+ */
+#define IX_QMGR_INT0SRCSELREG0_BIT3 3
+
+/*
+ * Variable declerations global to this file. Externs are followed by
+ * statics.
+ */
+extern UINT32 aqmBaseAddress;
+
+/*
+ * Function declarations.
+ */
+void
+ixQMgrAqmIfInit (void);
+
+void
+ixQMgrAqmIfUninit (void);
+
+unsigned
+ixQMgrAqmIfLog2 (unsigned number);
+
+void
+ixQMgrAqmIfQRegisterBitsWrite (IxQMgrQId qId,
+ UINT32 registerBaseAddrOffset,
+ unsigned queuesPerRegWord,
+ UINT32 value);
+
+void
+ixQMgrAqmIfQStatusCheckValsCalc (IxQMgrQId qId,
+ IxQMgrSourceId srcSel,
+ unsigned int *statusWordOffset,
+ UINT32 *checkValue,
+ UINT32 *mask);
+/*
+ * The Xscale software allways deals with logical addresses and so the
+ * base address of the AQM memory space is not a hardcoded value. This
+ * function must be called before any other function in this component.
+ * NO CHECKING is performed to ensure that the base address has been
+ * set.
+ */
+void
+ixQMgrAqmIfBaseAddressSet (UINT32 address);
+
+/*
+ * Get the base address of the AQM memory space.
+ */
+void
+ixQMgrAqmIfBaseAddressGet (UINT32 *address);
+
+/*
+ * Get the sram base address
+ */
+void
+ixQMgrAqmIfSramBaseAddressGet (UINT32 *address);
+
+/*
+ * Read a queue status
+ */
+void
+ixQMgrAqmIfQueStatRead (IxQMgrQId qId,
+ IxQMgrQStatus* status);
+
+
+/*
+ * Set INT0SRCSELREG0 Bit3
+ */
+void ixQMgrAqmIfIntSrcSelReg0Bit3Set (void);
+
+
+/*
+ * Set the interrupt source
+ */
+void
+ixQMgrAqmIfIntSrcSelWrite (IxQMgrQId qId,
+ IxQMgrSourceId sourceId);
+
+/*
+ * Enable interruptson a queue
+ */
+void
+ixQMgrAqmIfQInterruptEnable (IxQMgrQId qId);
+
+/*
+ * Disable interrupt on a quee
+ */
+void
+ixQMgrAqmIfQInterruptDisable (IxQMgrQId qId);
+
+/*
+ * Write the config register of the specified queue
+ */
+void
+ixQMgrAqmIfQueCfgWrite (IxQMgrQId qId,
+ IxQMgrQSizeInWords qSizeInWords,
+ IxQMgrQEntrySizeInWords entrySizeInWords,
+ UINT32 freeSRAMAddress);
+
+/*
+ * read fields from the config of the specified queue.
+ */
+void
+ixQMgrAqmIfQueCfgRead (IxQMgrQId qId,
+ unsigned int numEntries,
+ UINT32 *baseAddress,
+ unsigned int *ne,
+ unsigned int *nf,
+ UINT32 *readPtr,
+ UINT32 *writePtr);
+
+/*
+ * Set the ne and nf watermark level on a queue.
+ */
+void
+ixQMgrAqmIfWatermarkSet (IxQMgrQId qId,
+ unsigned ne,
+ unsigned nf);
+
+/* Inspect an entry without moving the read pointer */
+IX_STATUS
+ixQMgrAqmIfQPeek (IxQMgrQId qId,
+ unsigned int entryIndex,
+ unsigned int *entry);
+
+/* Modify an entry without moving the write pointer */
+IX_STATUS
+ixQMgrAqmIfQPoke (IxQMgrQId qId,
+ unsigned int entryIndex,
+ unsigned int *entry);
+
+/*
+ * Function prototype for inline functions. For description refers to
+ * the functions defintion below.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfWordWrite (VUINT32 *address,
+ UINT32 word);
+
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfWordRead (VUINT32 *address,
+ UINT32 *word);
+
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQPop (IxQMgrQId qId,
+ IxQMgrQEntrySizeInWords numWords,
+ UINT32 *entry);
+
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQPush (IxQMgrQId qId,
+ IxQMgrQEntrySizeInWords numWords,
+ UINT32 *entry);
+
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQStatusRegsRead (IxQMgrDispatchGroup group,
+ UINT32 *qStatusWords);
+
+IX_QMGR_AQMIF_INLINE BOOL
+ixQMgrAqmIfQStatusCheck (UINT32 *oldQStatusWords,
+ UINT32 *newQStatusWords,
+ unsigned int statusWordOffset,
+ UINT32 checkValue,
+ UINT32 mask);
+
+IX_QMGR_AQMIF_INLINE BOOL
+ixQMgrAqmIfRegisterBitCheck (IxQMgrQId qId,
+ UINT32 registerBaseAddrOffset,
+ unsigned queuesPerRegWord,
+ unsigned relativeBitOffset,
+ BOOL reset);
+
+IX_QMGR_AQMIF_INLINE BOOL
+ixQMgrAqmIfUnderflowCheck (IxQMgrQId qId);
+
+IX_QMGR_AQMIF_INLINE BOOL
+ixQMgrAqmIfOverflowCheck (IxQMgrQId qId);
+
+IX_QMGR_AQMIF_INLINE UINT32
+ixQMgrAqmIfQRegisterBitsRead (IxQMgrQId qId,
+ UINT32 registerBaseAddrOffset,
+ unsigned queuesPerRegWord);
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQInterruptRegWrite (IxQMgrDispatchGroup group,
+ UINT32 reg);
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQInterruptRegRead (IxQMgrDispatchGroup group,
+ UINT32 *regVal);
+
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQueLowStatRead (IxQMgrQId qId,
+ IxQMgrQStatus *status);
+
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQueUppStatRead (IxQMgrQId qId,
+ IxQMgrQStatus *status);
+
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQueStatRead (IxQMgrQId qId,
+ IxQMgrQStatus *qStatus);
+
+IX_QMGR_AQMIF_INLINE unsigned
+ixQMgrAqmIfPow2NumDivide (unsigned numerator,
+ unsigned denominator);
+
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQInterruptEnableRegRead (IxQMgrDispatchGroup group,
+ UINT32 *regVal);
+/*
+ * Inline functions
+ */
+
+/*
+ * This inline function is used by other QMgr components to write one
+ * word to the specified address.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfWordWrite (VUINT32 *address,
+ UINT32 word)
+{
+ IX_OSAL_WRITE_LONG(address, word);
+}
+
+/*
+ * This inline function is used by other QMgr components to read a
+ * word from the specified address.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfWordRead (VUINT32 *address,
+ UINT32 *word)
+{
+ *word = IX_OSAL_READ_LONG(address);
+}
+
+
+/*
+ * This inline function is used by other QMgr components to pop an
+ * entry off the specified queue.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQPop (IxQMgrQId qId,
+ IxQMgrQEntrySizeInWords numWords,
+ UINT32 *entry)
+{
+ volatile UINT32 *accRegAddr;
+
+ accRegAddr = (UINT32*)(aqmBaseAddress +
+ IX_QMGR_Q_ACCESS_ADDR_GET(qId));
+
+ switch (numWords)
+ {
+ case IX_QMGR_Q_ENTRY_SIZE1:
+ ixQMgrAqmIfWordRead (accRegAddr, entry);
+ break;
+ case IX_QMGR_Q_ENTRY_SIZE2:
+ ixQMgrAqmIfWordRead (accRegAddr++, entry++);
+ ixQMgrAqmIfWordRead (accRegAddr, entry);
+ break;
+ case IX_QMGR_Q_ENTRY_SIZE4:
+ ixQMgrAqmIfWordRead (accRegAddr++, entry++);
+ ixQMgrAqmIfWordRead (accRegAddr++, entry++);
+ ixQMgrAqmIfWordRead (accRegAddr++, entry++);
+ ixQMgrAqmIfWordRead (accRegAddr, entry);
+ break;
+ default:
+ IX_QMGR_LOG_ERROR0("Invalid Q Entry size passed to ixQMgrAqmIfQPop");
+ break;
+ }
+}
+
+/*
+ * This inline function is used by other QMgr components to push an
+ * entry to the specified queue.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQPush (IxQMgrQId qId,
+ IxQMgrQEntrySizeInWords numWords,
+ UINT32 *entry)
+{
+ volatile UINT32 *accRegAddr;
+
+ accRegAddr = (UINT32*)(aqmBaseAddress +
+ IX_QMGR_Q_ACCESS_ADDR_GET(qId));
+
+ switch (numWords)
+ {
+ case IX_QMGR_Q_ENTRY_SIZE1:
+ ixQMgrAqmIfWordWrite (accRegAddr, *entry);
+ break;
+ case IX_QMGR_Q_ENTRY_SIZE2:
+ ixQMgrAqmIfWordWrite (accRegAddr++, *entry++);
+ ixQMgrAqmIfWordWrite (accRegAddr, *entry);
+ break;
+ case IX_QMGR_Q_ENTRY_SIZE4:
+ ixQMgrAqmIfWordWrite (accRegAddr++, *entry++);
+ ixQMgrAqmIfWordWrite (accRegAddr++, *entry++);
+ ixQMgrAqmIfWordWrite (accRegAddr++, *entry++);
+ ixQMgrAqmIfWordWrite (accRegAddr, *entry);
+ break;
+ default:
+ IX_QMGR_LOG_ERROR0("Invalid Q Entry size passed to ixQMgrAqmIfQPush");
+ break;
+ }
+}
+
+/*
+ * The AQM interrupt registers contains a bit for each AQM queue
+ * specifying the queue (s) that cause an interrupt to fire. This
+ * function is called by IxQMGrDispatcher component.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQStatusRegsRead (IxQMgrDispatchGroup group,
+ UINT32 *qStatusWords)
+{
+ volatile UINT32 *regAddress = NULL;
+
+ if (group == IX_QMGR_QUELOW_GROUP)
+ {
+ regAddress = (UINT32*)(aqmBaseAddress +
+ IX_QMGR_QUELOWSTAT0_OFFSET);
+
+ ixQMgrAqmIfWordRead (regAddress++, qStatusWords++);
+ ixQMgrAqmIfWordRead (regAddress++, qStatusWords++);
+ ixQMgrAqmIfWordRead (regAddress++, qStatusWords++);
+ ixQMgrAqmIfWordRead (regAddress, qStatusWords);
+ }
+ else /* We have the upper queues */
+ {
+ /* Only need to read the Nearly Empty status register for
+ * queues 32-63 as for therse queues the interrtupt source
+ * condition is fixed to Nearly Empty
+ */
+ regAddress = (UINT32*)(aqmBaseAddress +
+ IX_QMGR_QUEUPPSTAT0_OFFSET);
+ ixQMgrAqmIfWordRead (regAddress, qStatusWords);
+ }
+}
+
+
+/*
+ * This function check if the status for a queue has changed between
+ * 2 snapshots and if it has, that the status matches a particular
+ * value after masking.
+ */
+IX_QMGR_AQMIF_INLINE BOOL
+ixQMgrAqmIfQStatusCheck (UINT32 *oldQStatusWords,
+ UINT32 *newQStatusWords,
+ unsigned int statusWordOffset,
+ UINT32 checkValue,
+ UINT32 mask)
+{
+ if (((oldQStatusWords[statusWordOffset] & mask) !=
+ (newQStatusWords[statusWordOffset] & mask)) &&
+ ((newQStatusWords[statusWordOffset] & mask) == checkValue))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+ * The AQM interrupt register contains a bit for each AQM queue
+ * specifying the queue (s) that cause an interrupt to fire. This
+ * function is called by IxQMgrDispatcher component.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQInterruptRegRead (IxQMgrDispatchGroup group,
+ UINT32 *regVal)
+{
+ volatile UINT32 *regAddress;
+
+ if (group == IX_QMGR_QUELOW_GROUP)
+ {
+ regAddress = (UINT32*)(aqmBaseAddress +
+ IX_QMGR_QINTREG0_OFFSET);
+ }
+ else
+ {
+ regAddress = (UINT32*)(aqmBaseAddress +
+ IX_QMGR_QINTREG1_OFFSET);
+ }
+
+ ixQMgrAqmIfWordRead (regAddress, regVal);
+}
+
+/*
+ * The AQM interrupt enable register contains a bit for each AQM queue.
+ * This function reads the interrupt enable register. This
+ * function is called by IxQMgrDispatcher component.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQInterruptEnableRegRead (IxQMgrDispatchGroup group,
+ UINT32 *regVal)
+{
+ volatile UINT32 *regAddress;
+
+ if (group == IX_QMGR_QUELOW_GROUP)
+ {
+ regAddress = (UINT32*)(aqmBaseAddress +
+ IX_QMGR_QUEIEREG0_OFFSET);
+ }
+ else
+ {
+ regAddress = (UINT32*)(aqmBaseAddress +
+ IX_QMGR_QUEIEREG1_OFFSET);
+ }
+
+ ixQMgrAqmIfWordRead (regAddress, regVal);
+}
+
+
+/*
+ * This inline function will read the status bit of a queue
+ * specified by qId. If reset is TRUE the bit is cleared.
+ */
+IX_QMGR_AQMIF_INLINE BOOL
+ixQMgrAqmIfRegisterBitCheck (IxQMgrQId qId,
+ UINT32 registerBaseAddrOffset,
+ unsigned queuesPerRegWord,
+ unsigned relativeBitOffset,
+ BOOL reset)
+{
+ UINT32 actualBitOffset;
+ volatile UINT32 *registerAddress;
+ UINT32 registerWord;
+
+ /*
+ * Calculate the registerAddress
+ * multiple queues split accross registers
+ */
+ registerAddress = (UINT32*)(aqmBaseAddress +
+ registerBaseAddrOffset +
+ ((qId / queuesPerRegWord) *
+ IX_QMGR_NUM_BYTES_PER_WORD));
+
+ /*
+ * Get the status word
+ */
+ ixQMgrAqmIfWordRead (registerAddress, &registerWord);
+
+ /*
+ * Calculate the actualBitOffset
+ * status for multiple queues stored in one register
+ */
+ actualBitOffset = (relativeBitOffset + 1) <<
+ ((qId & (queuesPerRegWord - 1)) * (BITS_PER_WORD / queuesPerRegWord));
+
+ /* Check if the status bit is set */
+ if (registerWord & actualBitOffset)
+ {
+ /* Clear the bit if reset */
+ if (reset)
+ {
+ ixQMgrAqmIfWordWrite (registerAddress, registerWord & (~actualBitOffset));
+ }
+ return TRUE;
+ }
+
+ /* Bit not set */
+ return FALSE;
+}
+
+
+/*
+ * @ingroup IxQmgrAqmIfAPI
+ *
+ * @brief Read the underflow status of a queue
+ *
+ * This inline function will read the underflow status of a queue
+ * specified by qId.
+ *
+ */
+IX_QMGR_AQMIF_INLINE BOOL
+ixQMgrAqmIfUnderflowCheck (IxQMgrQId qId)
+{
+ if (qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ return (ixQMgrAqmIfRegisterBitCheck (qId,
+ IX_QMGR_QUEUOSTAT0_OFFSET,
+ IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD,
+ IX_QMGR_UNDERFLOW_BIT_OFFSET,
+ TRUE/*reset*/));
+ }
+ else
+ {
+ /* Qs 32-63 have no underflow status */
+ return FALSE;
+ }
+}
+
+/*
+ * This inline function will read the overflow status of a queue
+ * specified by qId.
+ */
+IX_QMGR_AQMIF_INLINE BOOL
+ixQMgrAqmIfOverflowCheck (IxQMgrQId qId)
+{
+ if (qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ return (ixQMgrAqmIfRegisterBitCheck (qId,
+ IX_QMGR_QUEUOSTAT0_OFFSET,
+ IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD,
+ IX_QMGR_OVERFLOW_BIT_OFFSET,
+ TRUE/*reset*/));
+ }
+ else
+ {
+ /* Qs 32-63 have no overflow status */
+ return FALSE;
+ }
+}
+
+/*
+ * This inline function will read the status bits of a queue
+ * specified by qId.
+ */
+IX_QMGR_AQMIF_INLINE UINT32
+ixQMgrAqmIfQRegisterBitsRead (IxQMgrQId qId,
+ UINT32 registerBaseAddrOffset,
+ unsigned queuesPerRegWord)
+{
+ volatile UINT32 *registerAddress;
+ UINT32 registerWord;
+ UINT32 statusBitsMask;
+ UINT32 bitsPerQueue;
+
+ bitsPerQueue = BITS_PER_WORD / queuesPerRegWord;
+
+ /*
+ * Calculate the registerAddress
+ * multiple queues split accross registers
+ */
+ registerAddress = (UINT32*)(aqmBaseAddress +
+ registerBaseAddrOffset +
+ ((qId / queuesPerRegWord) *
+ IX_QMGR_NUM_BYTES_PER_WORD));
+ /*
+ * Read the status word
+ */
+ ixQMgrAqmIfWordRead (registerAddress, &registerWord);
+
+
+ /*
+ * Calculate the mask for the status bits for this queue.
+ */
+ statusBitsMask = ((1 << bitsPerQueue) - 1);
+
+ /*
+ * Shift the status word so it is right justified
+ */
+ registerWord >>= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue);
+
+ /*
+ * Mask out all bar the status bits for this queue
+ */
+ return (registerWord &= statusBitsMask);
+}
+
+/*
+ * This function is called by IxQMgrDispatcher to set the contents of
+ * the AQM interrupt register.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQInterruptRegWrite (IxQMgrDispatchGroup group,
+ UINT32 reg)
+{
+ volatile UINT32 *address;
+
+ if (group == IX_QMGR_QUELOW_GROUP)
+ {
+ address = (UINT32*)(aqmBaseAddress +
+ IX_QMGR_QINTREG0_OFFSET);
+ }
+ else
+ {
+ address = (UINT32*)(aqmBaseAddress +
+ IX_QMGR_QINTREG1_OFFSET);
+ }
+
+ ixQMgrAqmIfWordWrite (address, reg);
+}
+
+/*
+ * Read the status of a queue in the range 0-31.
+ *
+ * This function is used by other QMgr components to read the
+ * status of the queue specified by qId.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQueLowStatRead (IxQMgrQId qId,
+ IxQMgrQStatus *status)
+{
+ /* Read the general status bits */
+ *status = ixQMgrAqmIfQRegisterBitsRead (qId,
+ IX_QMGR_QUELOWSTAT0_OFFSET,
+ IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD);
+}
+
+/*
+ * This function will read the status of the queue specified
+ * by qId.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQueUppStatRead (IxQMgrQId qId,
+ IxQMgrQStatus *status)
+{
+ /* Reset the status bits */
+ *status = 0;
+
+ /*
+ * Check if the queue is nearly empty,
+ * N.b. QUPP stat register contains status for regs 32-63 at each
+ * bit position so subtract 32 to get bit offset
+ */
+ if (ixQMgrAqmIfRegisterBitCheck ((qId - IX_QMGR_MIN_QUEUPP_QID),
+ IX_QMGR_QUEUPPSTAT0_OFFSET,
+ IX_QMGR_QUEUPPSTAT_NUM_QUE_PER_WORD,
+ 0/*relativeBitOffset*/,
+ FALSE/*!reset*/))
+ {
+ *status |= IX_QMGR_Q_STATUS_NE_BIT_MASK;
+ }
+
+ /*
+ * Check if the queue is full,
+ * N.b. QUPP stat register contains status for regs 32-63 at each
+ * bit position so subtract 32 to get bit offset
+ */
+ if (ixQMgrAqmIfRegisterBitCheck ((qId - IX_QMGR_MIN_QUEUPP_QID),
+ IX_QMGR_QUEUPPSTAT1_OFFSET,
+ IX_QMGR_QUEUPPSTAT_NUM_QUE_PER_WORD,
+ 0/*relativeBitOffset*/,
+ FALSE/*!reset*/))
+ {
+ *status |= IX_QMGR_Q_STATUS_F_BIT_MASK;
+ }
+}
+
+/*
+ * This function is used by other QMgr components to read the
+ * status of the queue specified by qId.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQueStatRead (IxQMgrQId qId,
+ IxQMgrQStatus *qStatus)
+{
+ if (qId < IX_QMGR_MIN_QUEUPP_QID)
+ {
+ ixQMgrAqmIfQueLowStatRead (qId, qStatus);
+ }
+ else
+ {
+ ixQMgrAqmIfQueUppStatRead (qId, qStatus);
+ }
+}
+
+
+/*
+ * This function performs a mod division
+ */
+IX_QMGR_AQMIF_INLINE unsigned
+ixQMgrAqmIfPow2NumDivide (unsigned numerator,
+ unsigned denominator)
+{
+ /* Number is evenly divisable by 2 */
+ return (numerator >> ixQMgrAqmIfLog2 (denominator));
+}
+
+/* Restore IX_COMPONENT_NAME */
+#undef IX_COMPONENT_NAME
+#define IX_COMPONENT_NAME IX_QMGR_AQMIF_SAVED_COMPONENT_NAME
+
+#endif/*IXQMGRAQMIF_P_H*/
diff --git a/cpu/ixp/npe/include/IxQMgrDefines_p.h b/cpu/ixp/npe/include/IxQMgrDefines_p.h
new file mode 100644
index 0000000..0183596
--- /dev/null
+++ b/cpu/ixp/npe/include/IxQMgrDefines_p.h
@@ -0,0 +1,55 @@
+/**
+ * @file IxQMgrDefines_p.h
+ *
+ * @author Intel Corporation
+ * @date 19-Jul-2002
+ *
+ * @brief IxQMgr Defines and tuneable constants
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+#ifndef IXQMGRDEFINES_P_H
+#define IXQMGRDEFINES_P_H
+
+#define IX_QMGR_PARM_CHECKS_ENABLED 1
+#define IX_QMGR_STATS_UPDATE_ENABLED 1
+
+#endif /* IXQMGRDEFINES_P_H */
diff --git a/cpu/ixp/npe/include/IxQMgrDispatcher_p.h b/cpu/ixp/npe/include/IxQMgrDispatcher_p.h
new file mode 100644
index 0000000..71a3f85
--- /dev/null
+++ b/cpu/ixp/npe/include/IxQMgrDispatcher_p.h
@@ -0,0 +1,106 @@
+/**
+ * @file IxQMgrDispatcher_p.h
+ *
+ * @author Intel Corporation
+ * @date 07-Feb-2002
+ *
+ * @brief This file contains the internal functions for dispatcher
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+#ifndef IXQMGRDISPATCHER_P_H
+#define IXQMGRDISPATCHER_P_H
+
+/*
+ * User defined include files
+ */
+#include "IxQMgr.h"
+
+/*
+ * This structure defines the statistic data for a queue
+ */
+typedef struct
+{
+ unsigned callbackCnt; /* Call count of callback */
+ unsigned priorityChangeCnt; /* Priority change count */
+ unsigned intNoCallbackCnt; /* Interrupt fired but no callback set count */
+ unsigned intLostCallbackCnt; /* Interrupt lost and detected ; SCR541 */
+ BOOL notificationEnabled; /* Interrupt enabled for this queue */
+ IxQMgrSourceId srcSel; /* interrupt source */
+ unsigned enableCount; /* num times notif enabled by LLP */
+ unsigned disableCount; /* num of times notif disabled by LLP */
+} IxQMgrDispatcherQStats;
+
+/*
+ * This structure defines statistic data for the disatcher
+ */
+typedef struct
+ {
+ unsigned loopRunCnt; /* ixQMgrDispatcherLoopRun count */
+
+ IxQMgrDispatcherQStats queueStats[IX_QMGR_MAX_NUM_QUEUES];
+
+} IxQMgrDispatcherStats;
+
+/*
+ * Initialise the dispatcher component
+ */
+void
+ixQMgrDispatcherInit (void);
+
+/*
+ * Get the dispatcher statistics
+ */
+IxQMgrDispatcherStats*
+ixQMgrDispatcherStatsGet (void);
+
+/**
+ * Retrieve the number of leading zero bits starting from the MSB
+ * This function is implemented as an (extremely fast) asm routine
+ * for XSCALE processor (see clz instruction) and as a (slower) C
+ * function for other systems.
+ */
+unsigned int
+ixQMgrCountLeadingZeros(unsigned int value);
+
+#endif/*IXQMGRDISPATCHER_P_H*/
+
+
diff --git a/cpu/ixp/npe/include/IxQMgrLog_p.h b/cpu/ixp/npe/include/IxQMgrLog_p.h
new file mode 100644
index 0000000..6b685b8
--- /dev/null
+++ b/cpu/ixp/npe/include/IxQMgrLog_p.h
@@ -0,0 +1,124 @@
+/**
+ * @file IxQMgrLog_p.h
+ *
+ * @author Intel Corporation
+ * @date 07-Feb-2002
+ *
+ * @brief This file contains the internal functions for config
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+#ifndef IXQMGRLOG_P_H
+#define IXQMGRLOG_P_H
+
+/*
+ * User defined header files
+ */
+#include "IxOsal.h"
+
+/*
+ * Macros
+ */
+
+#define IX_QMGR_LOG0(string) do\
+{\
+ ixOsalLog(IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, string, 0, 0, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG1(string, arg1) do\
+{\
+ ixOsalLog(IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, string, (int)arg1, 0, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG2(string, arg1, arg2) do\
+{\
+ ixOsalLog(IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, string, (int)arg1, (int)arg2, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG3(string, arg1, arg2, arg3) do\
+{\
+ ixOsalLog(IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, string, (int)arg1, (int)arg2, (int)arg3, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG6(string, arg1, arg2, arg3, arg4, arg5, arg6) do\
+{\
+ ixOsalLog(IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, string, (int)arg1, (int)arg2, (int)arg3, (int)arg4, (int)arg5, (int)arg6); \
+}while(0);
+
+#define IX_QMGR_LOG_WARNING0(string) do\
+{\
+ ixOsalLog(IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, string, 0, 0, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG_WARNING1(string, arg1) do\
+{\
+ ixOsalLog(IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, string, (int)arg1, 0, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG_WARNING2(string, arg1, arg2) do\
+{\
+ ixOsalLog(IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, string, (int)arg1, (int)arg2, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG_ERROR0(string) do\
+{\
+ ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, string, 0, 0, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG_ERROR1(string, arg1) do\
+{\
+ ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, string, (int)arg1, 0, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG_ERROR2(string, arg1, arg2) do\
+{\
+ ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, string, (int)arg1, (int)arg2, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG_ERROR3(string, arg1, arg2, arg3) do\
+{\
+ ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, string, (int)arg1, (int)arg2, (int)arg3, 0, 0, 0);\
+}while(0);
+#endif /* IX_QMGRLOG_P_H */
+
+
+
+
diff --git a/cpu/ixp/npe/include/IxQMgrQAccess_p.h b/cpu/ixp/npe/include/IxQMgrQAccess_p.h
new file mode 100644
index 0000000..8612670
--- /dev/null
+++ b/cpu/ixp/npe/include/IxQMgrQAccess_p.h
@@ -0,0 +1,96 @@
+/**
+ * @file IxQMgrQAccess_p.h
+ *
+ * @author Intel Corporation
+ * @date 30-Oct-2001
+ *
+ * @brief QAccess private header file
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+#ifndef IXQMGRQACCESS_P_H
+#define IXQMGRQACCESS_P_H
+
+/*
+ * User defined header files
+ */
+#include "IxQMgr.h"
+
+/*
+ * Global variables declarations.
+ */
+extern volatile UINT32 * ixQMgrAqmIfQueAccRegAddr[];
+
+/*
+ * Initialise the Queue Access component
+ */
+void
+ixQMgrQAccessInit (void);
+
+/*
+ * read the remainder of a multi-word queue entry
+ * (the first word is already read)
+ */
+IX_STATUS
+ixQMgrQReadMWordsMinus1 (IxQMgrQId qId,
+ UINT32 *entry);
+
+/*
+ * Fast access : pop a q entry from a single word queue
+ */
+extern __inline__ UINT32 ixQMgrQAccessPop(IxQMgrQId qId);
+
+extern __inline__ UINT32 ixQMgrQAccessPop(IxQMgrQId qId)
+{
+ return *(ixQMgrAqmIfQueAccRegAddr[qId]);
+}
+
+/*
+ * Fast access : push a q entry in a single word queue
+ */
+extern __inline__ void ixQMgrQAccessPush(IxQMgrQId qId, UINT32 entry);
+
+extern __inline__ void ixQMgrQAccessPush(IxQMgrQId qId, UINT32 entry)
+{
+ *(ixQMgrAqmIfQueAccRegAddr[qId]) = entry;
+}
+
+#endif/*IXQMGRQACCESS_P_H*/
diff --git a/cpu/ixp/npe/include/IxQMgrQCfg_p.h b/cpu/ixp/npe/include/IxQMgrQCfg_p.h
new file mode 100644
index 0000000..c9dae1e
--- /dev/null
+++ b/cpu/ixp/npe/include/IxQMgrQCfg_p.h
@@ -0,0 +1,122 @@
+/**
+ * @file IxQMgrQCfg_p.h
+ *
+ * @author Intel Corporation
+ * @date 07-Feb-2002
+ *
+ * @brief This file contains the internal functions for config
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+#ifndef IXQMGRQCFG_P_H
+#define IXQMGRQCFG_P_H
+
+/*
+ * User defined header files
+ */
+#include "IxQMgr.h"
+
+/*
+ * Typedefs
+ */
+typedef struct
+{
+ unsigned wmSetCnt;
+
+ struct
+ {
+ char *qName;
+ BOOL isConfigured;
+ unsigned int qSizeInWords;
+ unsigned int qEntrySizeInWords;
+ unsigned int ne;
+ unsigned int nf;
+ unsigned int numEntries;
+ UINT32 baseAddress;
+ UINT32 readPtr;
+ UINT32 writePtr;
+ } qStats[IX_QMGR_MAX_NUM_QUEUES];
+
+} IxQMgrQCfgStats;
+
+/*
+ * Initialize the QCfg subcomponent
+ */
+void
+ixQMgrQCfgInit (void);
+
+/*
+ * Uninitialize the QCfg subcomponent
+ */
+void
+ixQMgrQCfgUninit (void);
+
+/*
+ * Get the Q size in words
+ */
+IxQMgrQSizeInWords
+ixQMgrQSizeInWordsGet (IxQMgrQId qId);
+
+/*
+ * Get the Q entry size in words
+ */
+IxQMgrQEntrySizeInWords
+ixQMgrQEntrySizeInWordsGet (IxQMgrQId qId);
+
+/*
+ * Get the generic cfg stats
+ */
+IxQMgrQCfgStats*
+ixQMgrQCfgStatsGet (void);
+
+/*
+ * Get queue specific stats
+ */
+IxQMgrQCfgStats*
+ixQMgrQCfgQStatsGet (IxQMgrQId qId);
+
+/*
+ * Check is the queue configured
+ */
+BOOL
+ixQMgrQIsConfigured(IxQMgrQId qId);
+
+#endif /* IX_QMGRQCFG_P_H */
diff --git a/cpu/ixp/npe/include/IxQueueAssignments.h b/cpu/ixp/npe/include/IxQueueAssignments.h
new file mode 100644
index 0000000..0c1543f
--- /dev/null
+++ b/cpu/ixp/npe/include/IxQueueAssignments.h
@@ -0,0 +1,516 @@
+/**
+ * @file IxQueueAssignments.h
+ *
+ * @author Intel Corporation
+ * @date 29-Oct-2004
+ *
+ * @brief Central definition for queue assignments
+ *
+ * Design Notes:
+ * This file contains queue assignments used by Ethernet (EthAcc),
+ * HSS (HssAcc), ATM (atmdAcc) and DMA (dmaAcc) access libraries.
+ *
+ * Note: Ethernet QoS traffic class definitions are managed separately
+ * by EthDB in IxEthDBQoS.h.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxQueueAssignments_H
+#define IxQueueAssignments_H
+
+#include "IxQMgr.h"
+
+/***************************************************************************
+ * Queue assignments for ATM
+ ***************************************************************************/
+
+/**
+ * @brief Global compiler switch to select between 3 possible NPE Modes
+ * Define this macro to enable MPHY mode
+ *
+ * Default(No Switch) = MultiPHY Utopia2
+ * IX_UTOPIAMODE = 1 for single Phy Utopia1
+ * IX_MPHYSINGLEPORT = 1 for single Phy Utopia2
+ */
+#define IX_NPE_MPHYMULTIPORT 1
+#if IX_UTOPIAMODE == 1
+#undef IX_NPE_MPHYMULTIPORT
+#endif
+#if IX_MPHYSINGLEPORT == 1
+#undef IX_NPE_MPHYMULTIPORT
+#endif
+
+/**
+ * @def IX_NPE_A_TXDONE_QUEUE_HIGHWATERMARK
+ *
+ * @brief The NPE reserves the High Watermark for its operation. But it must be set by the Xscale
+ */
+#define IX_NPE_A_TXDONE_QUEUE_HIGHWATERMARK 2
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_TX_DONE
+ *
+ * @brief Queue ID for ATM Transmit Done queue
+ */
+#define IX_NPE_A_QMQ_ATM_TX_DONE IX_QMGR_QUEUE_1
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_TX0
+ *
+ * @brief Queue ID for ATM transmit Queue in a single phy configuration
+ */
+#define IX_NPE_A_QMQ_ATM_TX0 IX_QMGR_QUEUE_2
+
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_TXID_MIN
+ *
+ * @brief Queue Manager Queue ID for ATM transmit Queue with minimum number of queue
+ *
+ */
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_TXID_MAX
+ *
+ * @brief Queue Manager Queue ID for ATM transmit Queue with maximum number of queue
+ *
+ */
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_RX_HI
+ *
+ * @brief Queue Manager Queue ID for ATM Receive high Queue
+ *
+ */
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_RX_LO
+ *
+ * @brief Queue Manager Queue ID for ATM Receive low Queue
+ */
+
+#ifdef IX_NPE_MPHYMULTIPORT
+/**
+ * @def IX_NPE_A_QMQ_ATM_TX1
+ *
+ * @brief Queue ID for ATM transmit Queue Multiphy from 1 to 11
+ */
+#define IX_NPE_A_QMQ_ATM_TX1 IX_NPE_A_QMQ_ATM_TX0+1
+#define IX_NPE_A_QMQ_ATM_TX2 IX_NPE_A_QMQ_ATM_TX1+1
+#define IX_NPE_A_QMQ_ATM_TX3 IX_NPE_A_QMQ_ATM_TX2+1
+#define IX_NPE_A_QMQ_ATM_TX4 IX_NPE_A_QMQ_ATM_TX3+1
+#define IX_NPE_A_QMQ_ATM_TX5 IX_NPE_A_QMQ_ATM_TX4+1
+#define IX_NPE_A_QMQ_ATM_TX6 IX_NPE_A_QMQ_ATM_TX5+1
+#define IX_NPE_A_QMQ_ATM_TX7 IX_NPE_A_QMQ_ATM_TX6+1
+#define IX_NPE_A_QMQ_ATM_TX8 IX_NPE_A_QMQ_ATM_TX7+1
+#define IX_NPE_A_QMQ_ATM_TX9 IX_NPE_A_QMQ_ATM_TX8+1
+#define IX_NPE_A_QMQ_ATM_TX10 IX_NPE_A_QMQ_ATM_TX9+1
+#define IX_NPE_A_QMQ_ATM_TX11 IX_NPE_A_QMQ_ATM_TX10+1
+#define IX_NPE_A_QMQ_ATM_TXID_MIN IX_NPE_A_QMQ_ATM_TX0
+#define IX_NPE_A_QMQ_ATM_TXID_MAX IX_NPE_A_QMQ_ATM_TX11
+#define IX_NPE_A_QMQ_ATM_RX_HI IX_QMGR_QUEUE_21
+#define IX_NPE_A_QMQ_ATM_RX_LO IX_QMGR_QUEUE_22
+#else
+#define IX_NPE_A_QMQ_ATM_TXID_MIN IX_NPE_A_QMQ_ATM_TX0
+#define IX_NPE_A_QMQ_ATM_TXID_MAX IX_NPE_A_QMQ_ATM_TX0
+#define IX_NPE_A_QMQ_ATM_RX_HI IX_QMGR_QUEUE_10
+#define IX_NPE_A_QMQ_ATM_RX_LO IX_QMGR_QUEUE_11
+#endif /* MPHY */
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_FREE_VC0
+ *
+ * @brief Hardware QMgr Queue ID for ATM Free VC Queue.
+ *
+ * There are 32 Hardware QMgr Queue ID; from IX_NPE_A_QMQ_ATM_FREE_VC1 to
+ * IX_NPE_A_QMQ_ATM_FREE_VC30
+ */
+#define IX_NPE_A_QMQ_ATM_FREE_VC0 IX_QMGR_QUEUE_32
+#define IX_NPE_A_QMQ_ATM_FREE_VC1 IX_NPE_A_QMQ_ATM_FREE_VC0+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC2 IX_NPE_A_QMQ_ATM_FREE_VC1+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC3 IX_NPE_A_QMQ_ATM_FREE_VC2+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC4 IX_NPE_A_QMQ_ATM_FREE_VC3+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC5 IX_NPE_A_QMQ_ATM_FREE_VC4+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC6 IX_NPE_A_QMQ_ATM_FREE_VC5+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC7 IX_NPE_A_QMQ_ATM_FREE_VC6+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC8 IX_NPE_A_QMQ_ATM_FREE_VC7+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC9 IX_NPE_A_QMQ_ATM_FREE_VC8+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC10 IX_NPE_A_QMQ_ATM_FREE_VC9+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC11 IX_NPE_A_QMQ_ATM_FREE_VC10+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC12 IX_NPE_A_QMQ_ATM_FREE_VC11+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC13 IX_NPE_A_QMQ_ATM_FREE_VC12+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC14 IX_NPE_A_QMQ_ATM_FREE_VC13+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC15 IX_NPE_A_QMQ_ATM_FREE_VC14+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC16 IX_NPE_A_QMQ_ATM_FREE_VC15+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC17 IX_NPE_A_QMQ_ATM_FREE_VC16+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC18 IX_NPE_A_QMQ_ATM_FREE_VC17+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC19 IX_NPE_A_QMQ_ATM_FREE_VC18+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC20 IX_NPE_A_QMQ_ATM_FREE_VC19+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC21 IX_NPE_A_QMQ_ATM_FREE_VC20+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC22 IX_NPE_A_QMQ_ATM_FREE_VC21+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC23 IX_NPE_A_QMQ_ATM_FREE_VC22+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC24 IX_NPE_A_QMQ_ATM_FREE_VC23+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC25 IX_NPE_A_QMQ_ATM_FREE_VC24+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC26 IX_NPE_A_QMQ_ATM_FREE_VC25+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC27 IX_NPE_A_QMQ_ATM_FREE_VC26+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC28 IX_NPE_A_QMQ_ATM_FREE_VC27+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC29 IX_NPE_A_QMQ_ATM_FREE_VC28+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC30 IX_NPE_A_QMQ_ATM_FREE_VC29+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC31 IX_NPE_A_QMQ_ATM_FREE_VC30+1
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_RXFREE_MIN
+ *
+ * @brief The minimum queue ID for FreeVC queue
+ */
+#define IX_NPE_A_QMQ_ATM_RXFREE_MIN IX_NPE_A_QMQ_ATM_FREE_VC0
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_RXFREE_MAX
+ *
+ * @brief The maximum queue ID for FreeVC queue
+ */
+#define IX_NPE_A_QMQ_ATM_RXFREE_MAX IX_NPE_A_QMQ_ATM_FREE_VC31
+
+/**
+ * @def IX_NPE_A_QMQ_OAM_FREE_VC
+ * @brief OAM Rx Free queue ID
+ */
+#ifdef IX_NPE_MPHYMULTIPORT
+#define IX_NPE_A_QMQ_OAM_FREE_VC IX_QMGR_QUEUE_14
+#else
+#define IX_NPE_A_QMQ_OAM_FREE_VC IX_QMGR_QUEUE_3
+#endif /* MPHY */
+
+/****************************************************************************
+ * Queue assignments for HSS
+ ****************************************************************************/
+
+/**** HSS Port 0 ****/
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_CHL_RX_TRIG
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Channelized Receive trigger
+ */
+#define IX_NPE_A_QMQ_HSS0_CHL_RX_TRIG IX_QMGR_QUEUE_12
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_RX
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Receive
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_RX IX_QMGR_QUEUE_13
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_TX0
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Transmit queue 0
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_TX0 IX_QMGR_QUEUE_14
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_TX1
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Transmit queue 1
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_TX1 IX_QMGR_QUEUE_15
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_TX2
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Transmit queue 2
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_TX2 IX_QMGR_QUEUE_16
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_TX3
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Transmit queue 3
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_TX3 IX_QMGR_QUEUE_17
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_RX_FREE0
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Receive Free queue 0
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_RX_FREE0 IX_QMGR_QUEUE_18
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_RX_FREE1
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Receive Free queue 1
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_RX_FREE1 IX_QMGR_QUEUE_19
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_RX_FREE2
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Receive Free queue 2
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_RX_FREE2 IX_QMGR_QUEUE_20
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_RX_FREE3
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Receive Free queue 3
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_RX_FREE3 IX_QMGR_QUEUE_21
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_TX_DONE
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Transmit Done queue
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_TX_DONE IX_QMGR_QUEUE_22
+
+/**** HSS Port 1 ****/
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_CHL_RX_TRIG
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Channelized Receive trigger
+ */
+#define IX_NPE_A_QMQ_HSS1_CHL_RX_TRIG IX_QMGR_QUEUE_10
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_RX
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Receive
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_RX IX_QMGR_QUEUE_0
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_TX0
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Transmit queue 0
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_TX0 IX_QMGR_QUEUE_5
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_TX1
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Transmit queue 1
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_TX1 IX_QMGR_QUEUE_6
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_TX2
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Transmit queue 2
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_TX2 IX_QMGR_QUEUE_7
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_TX3
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Transmit queue 3
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_TX3 IX_QMGR_QUEUE_8
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_RX_FREE0
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Receive Free queue 0
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_RX_FREE0 IX_QMGR_QUEUE_1
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_RX_FREE1
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Receive Free queue 1
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_RX_FREE1 IX_QMGR_QUEUE_2
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_RX_FREE2
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Receive Free queue 2
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_RX_FREE2 IX_QMGR_QUEUE_3
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_RX_FREE3
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Receive Free queue 3
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_RX_FREE3 IX_QMGR_QUEUE_4
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_TX_DONE
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Transmit Done queue
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_TX_DONE IX_QMGR_QUEUE_9
+
+/*****************************************************************************************
+ * Queue assignments for DMA
+ *****************************************************************************************/
+
+#define IX_DMA_NPE_A_REQUEST_QID IX_QMGR_QUEUE_19 /**< Queue Id for NPE A DMA Request */
+#define IX_DMA_NPE_A_DONE_QID IX_QMGR_QUEUE_20 /**< Queue Id for NPE A DMA Done */
+#define IX_DMA_NPE_B_REQUEST_QID IX_QMGR_QUEUE_24 /**< Queue Id for NPE B DMA Request */
+#define IX_DMA_NPE_B_DONE_QID IX_QMGR_QUEUE_26 /**< Queue Id for NPE B DMA Done */
+#define IX_DMA_NPE_C_REQUEST_QID IX_QMGR_QUEUE_25 /**< Queue Id for NPE C DMA Request */
+#define IX_DMA_NPE_C_DONE_QID IX_QMGR_QUEUE_27 /**< Queue Id for NPE C DMA Done */
+
+
+/*****************************************************************************************
+ * Queue assignments for Ethernet
+ *
+ * Note: Rx queue definitions, which include QoS traffic class definitions
+ * are managed by EthDB and declared in IxEthDBQoS.h
+ *****************************************************************************************/
+
+/**
+*
+* @def IX_ETH_ACC_RX_FRAME_ETH_Q
+*
+* @brief Eth0/Eth1 NPE Frame Recieve Q.
+*
+* @note THIS IS NOT USED - the Rx queues are read from EthDB QoS configuration
+*
+*/
+#define IX_ETH_ACC_RX_FRAME_ETH_Q (IX_QMGR_QUEUE_4)
+
+/**
+*
+* @def IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q
+*
+* @brief Supply Rx Buffers Ethernet Q for NPEB - Eth 0 - Port 1
+*
+*/
+#define IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q (IX_QMGR_QUEUE_27)
+
+/**
+*
+* @def IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q
+*
+* @brief Supply Rx Buffers Ethernet Q for NPEC - Eth 1 - Port 2
+*
+*/
+#define IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q (IX_QMGR_QUEUE_28)
+
+/**
+*
+* @def IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q
+*
+* @brief Supply Rx Buffers Ethernet Q for NPEA - Eth 2 - Port 3
+*
+*/
+#define IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q (IX_QMGR_QUEUE_26)
+
+
+/**
+*
+* @def IX_ETH_ACC_TX_FRAME_ENET0_Q
+*
+* @brief Submit frame Q for NPEB Eth 0 - Port 1
+*
+*/
+#define IX_ETH_ACC_TX_FRAME_ENET0_Q (IX_QMGR_QUEUE_24)
+
+
+/**
+*
+* @def IX_ETH_ACC_TX_FRAME_ENET1_Q
+*
+* @brief Submit frame Q for NPEC Eth 1 - Port 2
+*
+*/
+#define IX_ETH_ACC_TX_FRAME_ENET1_Q (IX_QMGR_QUEUE_25)
+
+/**
+*
+* @def IX_ETH_ACC_TX_FRAME_ENET2_Q
+*
+* @brief Submit frame Q for NPEA Eth 2 - Port 3
+*
+*/
+#define IX_ETH_ACC_TX_FRAME_ENET2_Q (IX_QMGR_QUEUE_23)
+
+/**
+*
+* @def IX_ETH_ACC_TX_FRAME_DONE_ETH_Q
+*
+* @brief Transmit complete Q for NPE Eth 0/1, Port 1&2
+*
+*/
+#define IX_ETH_ACC_TX_FRAME_DONE_ETH_Q (IX_QMGR_QUEUE_31)
+
+/*****************************************************************************************
+ * Queue assignments for Crypto
+ *****************************************************************************************/
+
+/** Crypto Service Request Queue */
+#define IX_CRYPTO_ACC_CRYPTO_REQ_Q (IX_QMGR_QUEUE_29)
+
+/** Crypto Service Done Queue */
+#define IX_CRYPTO_ACC_CRYPTO_DONE_Q (IX_QMGR_QUEUE_30)
+
+/** Crypto Req Q CB tag */
+#define IX_CRYPTO_ACC_CRYPTO_REQ_Q_CB_TAG (0)
+
+/** Crypto Done Q CB tag */
+#define IX_CRYPTO_ACC_CRYPTO_DONE_Q_CB_TAG (1)
+
+/** WEP Service Request Queue */
+#define IX_CRYPTO_ACC_WEP_REQ_Q (IX_QMGR_QUEUE_21)
+
+/** WEP Service Done Queue */
+#define IX_CRYPTO_ACC_WEP_DONE_Q (IX_QMGR_QUEUE_22)
+
+/** WEP Req Q CB tag */
+#define IX_CRYPTO_ACC_WEP_REQ_Q_CB_TAG (2)
+
+/** WEP Done Q CB tag */
+#define IX_CRYPTO_ACC_WEP_DONE_Q_CB_TAG (3)
+
+/** Number of queues allocate to crypto hardware accelerator services */
+#define IX_CRYPTO_ACC_NUM_OF_CRYPTO_Q (2)
+
+/** Number of queues allocate to WEP NPE services */
+#define IX_CRYPTO_ACC_NUM_OF_WEP_NPE_Q (2)
+
+/** Number of queues allocate to CryptoAcc component */
+#define IX_CRYPTO_ACC_NUM_OF_Q (IX_CRYPTO_ACC_NUM_OF_CRYPTO_Q + IX_CRYPTO_ACC_NUM_OF_WEP_NPE_Q)
+
+#endif /* IxQueueAssignments_H */
diff --git a/cpu/ixp/npe/include/IxSspAcc.h b/cpu/ixp/npe/include/IxSspAcc.h
new file mode 100644
index 0000000..35e7abf
--- /dev/null
+++ b/cpu/ixp/npe/include/IxSspAcc.h
@@ -0,0 +1,1271 @@
+/**
+ * @file IxSspAcc.h
+ *
+ * @brief Header file for the IXP400 SSP Serial Port Access (IxSspAcc)
+ *
+ * @version $Revision: 0.1 $
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxSspAcc IXP400 SSP Serial Port Access (IxSspAcc) API
+ *
+ * @brief IXP400 SSP Serial Port Access Public API
+ *
+ * @{
+ */
+#ifndef IXSSPACC_H
+#define IXSSPACC_H
+
+#ifdef __ixp46X
+
+#include "IxOsal.h"
+
+/*
+ * Section for enum
+ */
+/**
+ * @ingroup IxSspAcc
+ *
+ * @enum IxSspAccDataSize
+ *
+ * @brief The data sizes in bits that are supported by the protocol
+ */
+typedef enum
+{
+ DATA_SIZE_TOO_SMALL = 0x2,
+ DATA_SIZE_4 = 0x3,
+ DATA_SIZE_5,
+ DATA_SIZE_6,
+ DATA_SIZE_7,
+ DATA_SIZE_8,
+ DATA_SIZE_9,
+ DATA_SIZE_10,
+ DATA_SIZE_11,
+ DATA_SIZE_12,
+ DATA_SIZE_13,
+ DATA_SIZE_14,
+ DATA_SIZE_15,
+ DATA_SIZE_16,
+ DATA_SIZE_TOO_BIG
+} IxSspAccDataSize;
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @enum IxSspAccPortStatus
+ *
+ * @brief The status of the SSP port to be set to enable/disable
+ */
+typedef enum
+{
+ SSP_PORT_DISABLE = 0x0,
+ SSP_PORT_ENABLE,
+ INVALID_SSP_PORT_STATUS
+} IxSspAccPortStatus;
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @enum IxSspAccFrameFormat
+ *
+ * @brief The frame format that is to be used - SPI, SSP, or Microwire
+ */
+typedef enum
+{
+ SPI_FORMAT = 0x0,
+ SSP_FORMAT,
+ MICROWIRE_FORMAT,
+ INVALID_FORMAT
+} IxSspAccFrameFormat;
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @enum IxSspAccClkSource
+ *
+ * @brief The source to produce the SSP serial clock
+ */
+typedef enum
+{
+ ON_CHIP_CLK = 0x0,
+ EXTERNAL_CLK,
+ INVALID_CLK_SOURCE
+} IxSspAccClkSource;
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @enum IxSspAccSpiSclkPhase
+ *
+ * @brief The SPI SCLK Phase:
+ * 0 - SCLK is inactive one cycle at the start of a frame and 1/2 cycle at the
+ * end of a frame.
+ * 1 - SCLK is inactive 1/2 cycle at the start of a frame and one cycle at the
+ * end of a frame.
+ */
+typedef enum
+{
+ START_ONE_END_HALF = 0x0,
+ START_HALF_END_ONE,
+ INVALID_SPI_PHASE
+} IxSspAccSpiSclkPhase;
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @enum IxSspAccSpiSclkPolarity
+ *
+ * @brief The SPI SCLK Polarity can be set to either low or high.
+ */
+typedef enum
+{
+ SPI_POLARITY_LOW = 0x0,
+ SPI_POLARITY_HIGH,
+ INVALID_SPI_POLARITY
+} IxSspAccSpiSclkPolarity;
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @enum IxSspAccMicrowireCtlWord
+ *
+ * @brief The Microwire control word can be either 8 or 16 bit.
+ */
+typedef enum
+{
+ MICROWIRE_8_BIT = 0x0,
+ MICROWIRE_16_BIT,
+ INVALID_MICROWIRE_CTL_WORD
+} IxSspAccMicrowireCtlWord;
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @enum IxSspAccFifoThreshold
+ *
+ * @brief The threshold in frames (each frame is defined by IxSspAccDataSize)
+ * that can be set for the FIFO to trigger a threshold exceed when
+ * checking with the ExceedThresholdCheck functions or an interrupt
+ * when it is enabled.
+ */
+typedef enum
+{
+ FIFO_TSHLD_1 = 0x0,
+ FIFO_TSHLD_2,
+ FIFO_TSHLD_3,
+ FIFO_TSHLD_4,
+ FIFO_TSHLD_5,
+ FIFO_TSHLD_6,
+ FIFO_TSHLD_7,
+ FIFO_TSHLD_8,
+ FIFO_TSHLD_9,
+ FIFO_TSHLD_10,
+ FIFO_TSHLD_11,
+ FIFO_TSHLD_12,
+ FIFO_TSHLD_13,
+ FIFO_TSHLD_14,
+ FIFO_TSHLD_15,
+ FIFO_TSHLD_16,
+ INVALID_FIFO_TSHLD
+} IxSspAccFifoThreshold;
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @enum IX_SSP_STATUS
+ *
+ * @brief The statuses that can be returned in a SSP Serial Port Access
+ */
+typedef enum
+{
+ IX_SSP_SUCCESS = IX_SUCCESS, /**< Success status */
+ IX_SSP_FAIL, /**< Fail status */
+ IX_SSP_RX_FIFO_OVERRUN_HANDLER_MISSING, /**<
+ Rx FIFO Overrun handler is NULL. */
+ IX_SSP_RX_FIFO_HANDLER_MISSING, /**<
+ Rx FIFO threshold hit or above handler is NULL
+ */
+ IX_SSP_TX_FIFO_HANDLER_MISSING, /**<
+ Tx FIFO threshold hit or below handler is NULL
+ */
+ IX_SSP_FIFO_NOT_EMPTY_FOR_SETTING_CTL_CMD, /**<
+ Tx FIFO not empty and therefore microwire
+ control command size setting is not allowed. */
+ IX_SSP_INVALID_FRAME_FORMAT_ENUM_VALUE, /**<
+ frame format selected is invalid. */
+ IX_SSP_INVALID_DATA_SIZE_ENUM_VALUE, /**<
+ data size selected is invalid. */
+ IX_SSP_INVALID_CLOCK_SOURCE_ENUM_VALUE, /**<
+ source clock selected is invalid. */
+ IX_SSP_INVALID_TX_FIFO_THRESHOLD_ENUM_VALUE, /**<
+ Tx FIFO threshold selected is invalid. */
+ IX_SSP_INVALID_RX_FIFO_THRESHOLD_ENUM_VALUE, /**<
+ Rx FIFO threshold selected is invalid. */
+ IX_SSP_INVALID_SPI_PHASE_ENUM_VALUE, /**<
+ SPI phase selected is invalid. */
+ IX_SSP_INVALID_SPI_POLARITY_ENUM_VALUE, /**<
+ SPI polarity selected is invalid. */
+ IX_SSP_INVALID_MICROWIRE_CTL_CMD_ENUM_VALUE, /**<
+ Microwire control command selected is invalid
+ */
+ IX_SSP_INT_UNBIND_FAIL, /**< Interrupt unbind fail to unbind SSP
+ interrupt */
+ IX_SSP_INT_BIND_FAIL, /**< Interrupt bind fail during init */
+ IX_SSP_RX_FIFO_NOT_EMPTY, /**<
+ Rx FIFO not empty while trying to change data
+ size. */
+ IX_SSP_TX_FIFO_NOT_EMPTY, /**<
+ Rx FIFO not empty while trying to change data
+ size or microwire control command size. */
+ IX_SSP_POLL_MODE_BLOCKING, /**<
+ poll mode selected blocks interrupt mode from
+ being selected. */
+ IX_SSP_TX_FIFO_HIT_BELOW_THRESHOLD, /**<
+ Tx FIFO level hit or below threshold. */
+ IX_SSP_TX_FIFO_EXCEED_THRESHOLD, /**<
+ Tx FIFO level exceeded threshold. */
+ IX_SSP_RX_FIFO_HIT_ABOVE_THRESHOLD, /**<
+ Rx FIFO level hit or exceeded threshold. */
+ IX_SSP_RX_FIFO_BELOW_THRESHOLD, /**<
+ Rx FIFO level below threshold. */
+ IX_SSP_BUSY, /**< SSP is busy. */
+ IX_SSP_IDLE, /**< SSP is idle. */
+ IX_SSP_OVERRUN_OCCURRED, /**<
+ SSP has experienced an overrun. */
+ IX_SSP_NO_OVERRUN, /**<
+ SSP did not experience an overrun. */
+ IX_SSP_NOT_SUPORTED, /**< hardware does not support SSP */
+ IX_SSP_NOT_INIT, /**< SSP Access not intialized */
+ IX_SSP_NULL_POINTER /**< parameter passed in is NULL */
+} IX_SSP_STATUS;
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @brief SSP Rx FIFO Overrun handler
+ *
+ * This function is called for the client to handle Rx FIFO Overrun that occurs
+ * in the SSP hardware
+ */
+typedef void (*RxFIFOOverrunHandler)(void);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @brief SSP Rx FIFO Threshold hit or above handler
+ *
+ * This function is called for the client to handle Rx FIFO threshold hit or
+ * or above that occurs in the SSP hardware
+ */
+typedef void (*RxFIFOThresholdHandler)(void);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @brief SSP Tx FIFO Threshold hit or below handler
+ *
+ * This function is called for the client to handle Tx FIFO threshold hit or
+ * or below that occurs in the SSP hardware
+ */
+typedef void (*TxFIFOThresholdHandler)(void);
+
+
+/*
+ * Section for struct
+ */
+/**
+ * @ingroup IxSspAcc
+ *
+ * @brief contains all the variables required to initialize the SSP serial port
+ * hardware.
+ *
+ * Structure to be filled and used for calling initialization
+ */
+typedef struct
+{
+ IxSspAccFrameFormat FrameFormatSelected;/**<Select between SPI, SSP and
+ Microwire. */
+ IxSspAccDataSize DataSizeSelected; /**<Select between 4 and 16. */
+ IxSspAccClkSource ClkSourceSelected; /**<Select clock source to be
+ on-chip or external. */
+ IxSspAccFifoThreshold TxFIFOThresholdSelected;
+ /**<Select Tx FIFO threshold
+ between 1 to 16. */
+ IxSspAccFifoThreshold RxFIFOThresholdSelected;
+ /**<Select Rx FIFO threshold
+ between 1 to 16. */
+ BOOL RxFIFOIntrEnable; /**<Enable/disable Rx FIFO
+ threshold interrupt. Disabling
+ this interrupt will require
+ the use of the polling function
+ RxFIFOExceedThresholdCheck. */
+ BOOL TxFIFOIntrEnable; /**<Enable/disable Tx FIFO
+ threshold interrupt. Disabling
+ this interrupt will require
+ the use of the polling function
+ TxFIFOExceedThresholdCheck. */
+ RxFIFOThresholdHandler RxFIFOThsldHdlr; /**<Pointer to function to handle
+ a Rx FIFO interrupt. */
+ TxFIFOThresholdHandler TxFIFOThsldHdlr; /**<Pointer to function to handle
+ a Tx FIFO interrupt. */
+ RxFIFOOverrunHandler RxFIFOOverrunHdlr; /**<Pointer to function to handle
+ a Rx FIFO overrun interrupt. */
+ BOOL LoopbackEnable; /**<Select operation mode to be
+ normal or loopback mode. */
+ IxSspAccSpiSclkPhase SpiSclkPhaseSelected;
+ /**<Select SPI SCLK phase to start
+ with one inactive cycle and end
+ with 1/2 inactive cycle or
+ start with 1/2 inactive cycle
+ and end with one inactive
+ cycle. (Only used in
+ SPI format). */
+ IxSspAccSpiSclkPolarity SpiSclkPolaritySelected;
+ /**<Select SPI SCLK idle state
+ to be low or high. (Only used in
+ SPI format). */
+ IxSspAccMicrowireCtlWord MicrowireCtlWordSelected;
+ /**<Select Microwire control
+ format to be 8 or 16-bit. (Only
+ used in Microwire format). */
+ UINT8 SerialClkRateSelected; /**<Select between 0 (1.8432Mbps)
+ and 255 (7.2Kbps). The
+ formula used is Bit rate =
+ 3.6864x10^6 /
+ (2 x (SerialClkRateSelect + 1))
+ */
+} IxSspInitVars;
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @brief contains counters of the SSP statistics
+ *
+ * Structure contains all values of counters and associated overflows.
+ */
+typedef struct
+{
+ UINT32 ixSspRcvCounter; /**<Total frames received. */
+ UINT32 ixSspXmitCounter; /**<Total frames transmitted. */
+ UINT32 ixSspOverflowCounter;/**<Total occurrences of overflow. */
+} IxSspAccStatsCounters;
+
+
+/*
+ * Section for prototypes interface functions
+ */
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccInit (
+ IxSspInitVars *initVarsSelected);
+ *
+ * @brief Initializes the SSP Access module.
+ *
+ * @param "IxSspAccInitVars [in] *initVarsSelected" - struct containing required
+ * variables for initialization
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will initialize the SSP Serial Port hardware to the user specified
+ * configuration. Then it will enable the SSP Serial Port.
+ * *NOTE*: Once interrupt or polling mode is selected, the mode cannot be
+ * changed via the interrupt enable/disable function but the init needs to be
+ * called again to change it.
+ *
+ * @return
+ * - IX_SSP_SUCCESS - Successfully initialize and enable the SSP
+ * serial port.
+ * - IX_SSP_RX_FIFO_HANDLER_MISSING - interrupt mode is selected but RX FIFO
+ * handler pointer is NULL
+ * - IX_SSP_TX_FIFO_HANDLER_MISSING - interrupt mode is selected but TX FIFO
+ * handler pointer is NULL
+ * - IX_SSP_RX_FIFO_OVERRUN_HANDLER_MISSING - interrupt mode is selected but
+ * RX FIFO Overrun handler pointer is NULL
+ * - IX_SSP_RX_FIFO_NOT_EMPTY - Rx FIFO not empty, data size change is not
+ * allowed.
+ * - IX_SSP_TX_FIFO_NOT_EMPTY - Tx FIFO not empty, data size change is not
+ * allowed.
+ * - IX_SSP_INVALID_FRAME_FORMAT_ENUM_VALUE - frame format selected is invalid
+ * - IX_SSP_INVALID_DATA_SIZE_ENUM_VALUE - data size selected is invalid
+ * - IX_SSP_INVALID_CLOCK_SOURCE_ENUM_VALUE - clock source selected is invalid
+ * - IX_SSP_INVALID_TX_FIFO_THRESHOLD_ENUM_VALUE - Tx FIFO threshold level
+ * selected is invalid
+ * - IX_SSP_INVALID_RX_FIFO_THRESHOLD_ENUM_VALUE - Rx FIFO threshold level
+ * selected is invalid
+ * - IX_SSP_INVALID_SPI_PHASE_ENUM_VALUE - SPI phase selected is invalid
+ * - IX_SSP_INVALID_SPI_POLARITY_ENUM_VALUE - SPI polarity selected is invalid
+ * - IX_SSP_INVALID_MICROWIRE_CTL_CMD_ENUM_VALUE - microwire control command
+ * size is invalid
+ * - IX_SSP_INT_UNBIND_FAIL - interrupt handler failed to unbind SSP interrupt
+ * - IX_SSP_INT_BIND_FAIL - interrupt handler failed to bind to SSP interrupt
+ * hardware trigger
+ * - IX_SSP_NOT_SUPORTED - hardware does not support SSP
+ * - IX_SSP_NULL_POINTER - parameter passed in is NULL
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccInit (IxSspInitVars *initVarsSelected);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccUninit (
+ void)
+ *
+ * @brief Un-initializes the SSP Serial Port Access component
+ *
+ * @param - None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will disable the SSP Serial Port hardware. The client can call the
+ * init function again if they wish to enable the SSP.
+ *
+ * @return
+ * - IX_SSP_SUCCESS - successfully uninit SSP component
+ * - IX_SSP_INT_UNBIND_FAIL - interrupt handler failed to unbind SSP interrupt
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccUninit (void);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccFIFODataSubmit (
+ UINT16 *data,
+ UINT32 amtOfData)
+ *
+ * @brief Inserts data into the SSP Serial Port's FIFO
+ *
+ * @param "UINT16 [in] *data" - pointer to the location to transmit the data
+ * from
+ * "UINT32 [in] amtOfData" - number of data to be transmitted.
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will insert the amount of data specified by "amtOfData" from buffer
+ * pointed to by "data" into the FIFO to be transmitted by the hardware.
+ *
+ * @return
+ * - IX_SSP_SUCCESS - Data inserted successfully into FIFO
+ * - IX_SSP_FAIL - FIFO insufficient space
+ * - IX_SSP_NULL_POINTER - data pointer passed by client is NULL
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccFIFODataSubmit (
+ UINT16* data,
+ UINT32 amtOfData);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccFIFODataReceive (
+ UINT16 *data,
+ UINT32 amtOfData)
+ *
+ * @brief Extract data from the SSP Serial Port's FIFO
+ *
+ * @param "UINT16 [in] *data" - pointer to the location to receive the data into
+ * "UINT32 [in] amtOfData" - number of data to be received.
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will extract the amount of data specified by "amtOfData" from the
+ * FIFO already received by the hardware into the buffer pointed to by "data".
+ *
+ * @return
+ * - IX_SSP_SUCCESS - Data extracted successfully from FIFO
+ * - IX_SSP_FAIL - FIFO has no data
+ * - IX_SSP_NULL_POINTER - data pointer passed by client is NULL
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccFIFODataReceive (
+ UINT16* data,
+ UINT32 amtOfData);
+
+
+/**
+ * Polling Functions
+ */
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccTxFIFOHitOrBelowThresholdCheck (
+ void)
+ *
+ * @brief Check if the Tx FIFO threshold has been hit or fallen below.
+ *
+ * @param - None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will return whether the Tx FIFO threshold has been exceeded or not
+ *
+ * @return
+ * - IX_SSP_TX_FIFO_HIT_BELOW_THRESHOLD - Tx FIFO level hit or below threshold .
+ * - IX_SSP_TX_FIFO_EXCEED_THRESHOLD - Tx FIFO level exceeded threshold.
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccTxFIFOHitOrBelowThresholdCheck (
+ void);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccRxFIFOHitOrAboveThresholdCheck (
+ void)
+ *
+ * @brief Check if the Rx FIFO threshold has been hit or exceeded.
+ *
+ * @param - None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will return whether the Rx FIFO level is below threshold or not
+ *
+ * @return
+ * - IX_SSP_RX_FIFO_HIT_ABOVE_THRESHOLD - Rx FIFO level hit or exceeded threshold
+ * - IX_SSP_RX_FIFO_BELOW_THRESHOLD - Rx FIFO level below threshold
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccRxFIFOHitOrAboveThresholdCheck (
+ void);
+
+
+/**
+ * Configuration functions
+ *
+ * NOTE: These configurations are not required to be called once init is called
+ * unless configurations need to be changed on the fly.
+ */
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccSSPPortStatusSet (
+ IxSspAccPortStatus portStatusSelected)
+ *
+ * @brief Enables/disables the SSP Serial Port hardware.
+ *
+ * @param "IxSspAccPortStatus [in] portStatusSelected" - Set the SSP port to
+ * enable or disable
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will enable/disable the SSP Serial Port hardware.
+ * NOTE: This function is called by init to enable the SSP after setting up the
+ * configurations and by uninit to disable the SSP.
+ *
+ * @return
+ * - IX_SSP_SUCCESS - Port status set with valid enum value
+ * - IX_SSP_FAIL - invalid enum value
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccSSPPortStatusSet (
+ IxSspAccPortStatus portStatusSelected);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccFrameFormatSelect (
+ IxSspAccFrameFormat frameFormatSelected)
+ *
+ * @brief Sets the frame format for the SSP Serial Port hardware
+ *
+ * @param "IxSspAccFrameFormat [in] frameFormatSelected" - The frame format of
+ * SPI, SSP or Microwire can be selected as the format
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will set the format for the transfers via user input.
+ * *NOTE*: The SSP hardware will be disabled to clear the FIFOs. Then its
+ * previous state (enabled/disabled) restored after changing the format.
+ *
+ * @return
+ * - IX_SSP_SUCCESS - frame format set with valid enum value
+ * - IX_SSP_INVALID_FRAME_FORMAT_ENUM_VALUE - invalid frame format value
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccFrameFormatSelect (
+ IxSspAccFrameFormat frameFormatSelected);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccDataSizeSelect (
+ IxSspAccDataSize dataSizeSelected)
+ *
+ * @brief Sets the data size for transfers
+ *
+ * @param "IxSspAccDataSize [in] dataSizeSelected" - The data size between 4
+ * and 16 that can be selected for data transfers
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will set the data size for the transfers via user input. It will
+ * disallow the change of the data size if either of the Rx/Tx FIFO is not
+ * empty to prevent data loss.
+ * *NOTE*: The SSP port will be disabled if the FIFOs are found to be empty and
+ * if between the check and disabling of the SSP (which clears the
+ * FIFOs) data is received into the FIFO, it might be lost.
+ * *NOTE*: The FIFOs can be cleared by disabling the SSP Port if necessary to
+ * force the data size change.
+ *
+ * @return
+ * - IX_SSP_SUCCESS - data size set with valid enum value
+ * - IX_SSP_RX_FIFO_NOT_EMPTY - Rx FIFO not empty, data size change is not
+ * allowed.
+ * - IX_SSP_TX_FIFO_NOT_EMPTY - Tx FIFO not empty, data size change is not
+ * allowed.
+ * - IX_SSP_INVALID_DATA_SIZE_ENUM_VALUE - invalid enum value
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccDataSizeSelect (
+ IxSspAccDataSize dataSizeSelected);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccClockSourceSelect(
+ IxSspAccClkSource clkSourceSelected)
+ *
+ * @brief Sets the clock source of the SSP Serial Port hardware
+ *
+ * @param "IxSspAccClkSource [in] clkSourceSelected" - The clock source from
+ * either external source on on-chip can be selected as the source
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will set the clock source for the transfers via user input.
+ *
+ * @return
+ * - IX_SSP_SUCCESS - clock source set with valid enum value
+ * - IX_SSP_INVALID_CLOCK_SOURCE_ENUM_VALUE - invalid enum value
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccClockSourceSelect (
+ IxSspAccClkSource clkSourceSelected);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccSerialClockRateConfigure (
+ UINT8 serialClockRateSelected)
+ *
+ * @brief Sets the on-chip Serial Clock Rate of the SSP Serial Port hardware.
+ *
+ * @param "UINT8 [in] serialClockRateSelected" - The serial clock rate that can
+ * be set is between 7.2Kbps and 1.8432Mbps. The formula used is
+ * Bit rate = 3.6864x10^6 / (2 x (SerialClockRateSelected + 1))
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will set the serial clock rate for the transfers via user input.
+ *
+ * @return
+ * - IX_SSP_SUCCESS - Serial clock rate configured successfully
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccSerialClockRateConfigure (
+ UINT8 serialClockRateSelected);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccRxFIFOIntEnable (
+ RxFIFOThresholdHandler rxFIFOIntrHandler)
+ *
+ * @brief Enables service request interrupt whenever the Rx FIFO hits its
+ * threshold
+ *
+ * @param "void [in] *rxFIFOIntrHandler(UINT32)" - function pointer to the
+ * interrupt handler for the Rx FIFO exceeded.
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will enable the service request interrupt for the Rx FIFO
+ *
+ * @return
+ * - IX_SSP_SUCCESS - Rx FIFO level interrupt enabled successfully
+ * - IX_SSP_RX_FIFO_HANDLER_MISSING - missing handler for Rx FIFO level interrupt
+ * - IX_SSP_POLL_MODE_BLOCKING - poll mode is selected at init, interrupt not
+ * allowed to be enabled. Use init to enable interrupt mode.
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccRxFIFOIntEnable (
+ RxFIFOThresholdHandler rxFIFOIntrHandler);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccRxFIFOIntDisable (
+ void)
+ *
+ * @brief Disables service request interrupt of the Rx FIFO.
+ *
+ * @param - None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will disable the service request interrupt of the Rx FIFO.
+ *
+ * @return
+ * - IX_SSP_SUCCESS - Rx FIFO Interrupt disabled successfully
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccRxFIFOIntDisable (
+ void);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccTxFIFOIntEnable (
+ TxFIFOThresholdHandler txFIFOIntrHandler)
+ *
+ * @brief Enables service request interrupt of the Tx FIFO.
+ *
+ * @param "void [in] *txFIFOIntrHandler(UINT32)" - function pointer to the
+ * interrupt handler for the Tx FIFO exceeded.
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will enable the service request interrupt of the Tx FIFO.
+ *
+ * @return
+ * - IX_SSP_SUCCESS - Tx FIFO level interrupt enabled successfully
+ * - IX_SSP_TX_FIFO_HANDLER_MISSING - missing handler for Tx FIFO level interrupt
+ * - IX_SSP_POLL_MODE_BLOCKING - poll mode is selected at init, interrupt not
+ * allowed to be enabled. Use init to enable interrupt mode.
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccTxFIFOIntEnable (
+ TxFIFOThresholdHandler txFIFOIntrHandler);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccTxFIFOIntDisable (
+ void)
+ *
+ * @brief Disables service request interrupt of the Tx FIFO
+ *
+ * @param - None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will disable the service request interrupt of the Tx FIFO
+ *
+ * @return
+ * - IX_SSP_SUCCESS - Tx FIFO Interrupt disabled successfuly.
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccTxFIFOIntDisable (
+ void);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccLoopbackEnable (
+ BOOL loopbackEnable)
+ *
+ * @brief Enables/disables the loopback mode
+ *
+ * @param "BOOL [in] loopbackEnable" - True to enable and false to disable.
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will set the mode of operation to either loopback or normal mode
+ * according to the user input.
+ *
+ * @return
+ * - IX_SSP_SUCCESS - Loopback enabled successfully
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccLoopbackEnable (
+ BOOL loopbackEnable);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccSpiSclkPolaritySet (
+ IxSspAccSpiSclkPolarity spiSclkPolaritySelected)
+ *
+ * @brief Sets the SPI SCLK Polarity to Low or High
+ *
+ * @param - "IxSspAccSpiSclkPolarity [in] spiSclkPolaritySelected" - SPI SCLK
+ * polarity that can be selected to either high or low
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API is only used for the SPI frame format and will set the SPI SCLK polarity
+ * to either low or high
+ *
+ * @return
+ * - IX_SSP_SUCCESS - SPI Sclk polarity set with valid enum value
+ * - IX_SSP_INVALID_SPI_POLARITY_ENUM_VALUE - invalid SPI polarity value
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccSpiSclkPolaritySet (
+ IxSspAccSpiSclkPolarity spiSclkPolaritySelected);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccSpiSclkPhaseSet (
+ IxSspAccSpiSclkPhase spiSclkPhaseSelected)
+ *
+ * @brief Sets the SPI SCLK Phase
+ *
+ * @param "IxSspAccSpiSclkPhase [in] spiSclkPhaseSelected" - Phase of either
+ * the SCLK is inactive one cycle at the start of a frame and 1/2
+ * cycle at the end of a frame, OR
+ * the SCLK is inactive 1/2 cycle at the start of a frame and one
+ * cycle at the end of a frame.
+ *
+ * Global Data :
+ * - IX_SSP_SUCCESS - SPI Sclk phase set with valid enum value
+ * - IX_SSP_INVALID_SPI_PHASE_ENUM_VALUE - invalid SPI phase value
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * This API is only used for the SPI frame format and will set the SPI SCLK
+ * phase according to user input.
+ *
+ * @return
+ * - None
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccSpiSclkPhaseSet (
+ IxSspAccSpiSclkPhase spiSclkPhaseSelected);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccMicrowireControlWordSet (
+ IxSspAccMicrowireCtlWord microwireCtlWordSelected)
+ *
+ * @brief Sets the Microwire control word to 8 or 16 bit format
+ *
+ * @param "IxSspAccMicrowireCtlWord [in] microwireCtlWordSelected" - Microwire
+ * control word format can be either 8 or 16 bit format
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API is only used for the Microwire frame format and will set the
+ * control word to 8 or 16 bit format
+ *
+ * @return
+ * - IX_SSP_SUCCESS - Microwire Control Word set with valid enum value
+ * - IX_SSP_TX_FIFO_NOT_EMPTY - Tx FIFO not empty, data size change is not
+ * allowed.
+ * - IX_SSP_INVALID_MICROWIRE_CTL_CMD_ENUM_VALUE - invalid enum value
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccMicrowireControlWordSet (
+ IxSspAccMicrowireCtlWord microwireCtlWordSelected);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccTxFIFOThresholdSet (
+ IxSspAccFifoThreshold txFIFOThresholdSelected)
+ *
+ * @brief Sets the Tx FIFO Threshold.
+ *
+ * @param "IxSspAccFifoThreshold [in] txFIFOThresholdSelected" - Threshold that
+ * is set for a Tx FIFO service request to be triggered
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will set the threshold for a Tx FIFO threshold to be triggered
+ *
+ * @return
+ * - IX_SSP_SUCCESS - Tx FIFO Threshold set with valid enum value
+ * - IX_SSP_INVALID_TX_FIFO_THRESHOLD_ENUM_VALUE - invalid enum value
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccTxFIFOThresholdSet (
+ IxSspAccFifoThreshold txFIFOThresholdSelected);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccRxFIFOThresholdSet (
+ IxSspAccFifoThreshold rxFIFOThresholdSelected)
+ *
+ * @brief Sets the Rx FIFO Threshold.
+ *
+ * @param "IxSspAccFifoThreshold [in] rxFIFOThresholdSelected" - Threshold that
+ * is set for a Tx FIFO service request to be triggered
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will will set the threshold for a Rx FIFO threshold to be triggered
+ *
+ * @return
+ * - IX_SSP_SUCCESS - Rx FIFO Threshold set with valid enum value
+ * - IX_SSP_INVALID_RX_FIFO_THRESHOLD_ENUM_VALUE - invalid enum value
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccRxFIFOThresholdSet (
+ IxSspAccFifoThreshold rxFIFOThresholdSelected);
+
+
+/**
+ * Debug functions
+ */
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccStatsGet (
+ IxSspAccStatsCounters *sspStats)
+ *
+ * @brief Returns the SSP Statistics through the pointer passed in
+ *
+ * @param "IxSspAccStatsCounters [in] *sspStats" - SSP statistics counter will
+ * be read and written to the location pointed by this pointer.
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will return the statistics counters of the SSP transfers.
+ *
+ * @return
+ * - IX_SSP_SUCCESS - Stats obtained into the pointer provided successfully
+ * - IX_SSP_FAIL - client provided pointer is NULL
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccStatsGet (
+ IxSspAccStatsCounters *sspStats);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccStatsReset (
+ void)
+ *
+ * @brief Resets the SSP Statistics
+ *
+ * @param - None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will reset the SSP statistics counters.
+ *
+ * @return
+ * - None
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC void
+ixSspAccStatsReset (
+ void);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccShow (
+ void)
+ *
+ * @brief Display SSP status registers and statistics counters.
+ *
+ * @param - None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will display the status registers of the SSP and the statistics
+ * counters.
+ *
+ * @return
+ * - IX_SSP_SUCCESS - SSP show called successfully.
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccShow (
+ void);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccSSPBusyCheck (
+ void)
+ *
+ * @brief Determine the state of the SSP serial port hardware.
+ *
+ * @param - None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will return the state of the SSP serial port hardware - busy or
+ * idle
+ *
+ * @return
+ * - IX_SSP_BUSY - SSP is busy
+ * - IX_SSP_IDLE - SSP is idle.
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccSSPBusyCheck (
+ void);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccTxFIFOLevelGet (
+ void)
+ *
+ * @brief Obtain the Tx FIFO's level
+ *
+ * @param - None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will return the level of the Tx FIFO
+ *
+ * @return
+ * - 0..16; 0 can also mean SSP not initialized and will need to be init.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC UINT8
+ixSspAccTxFIFOLevelGet (
+ void);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccRxFIFOLevelGet (
+ void)
+ *
+ * @brief Obtain the Rx FIFO's level
+ *
+ * @param - None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will return the level of the Rx FIFO
+ *
+ * @return
+ * - 0..16; 0 can also mean SSP not initialized and will need to be init.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC UINT8
+ixSspAccRxFIFOLevelGet (
+ void);
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @fn ixSspAccRxFIFOOverrunCheck (
+ void)
+ *
+ * @brief Check if the Rx FIFO has overrun its FIFOs
+ *
+ * @param - None
+ *
+ * Global Data :
+ * - None.
+ *
+ * This API will return whether the Rx FIFO has overrun its 16 FIFOs
+ *
+ * @return
+ * - IX_SSP_OVERRUN_OCCURRED - Rx FIFO overrun occurred
+ * - IX_SSP_NO_OVERRUN - Rx FIFO did not overrun
+ * - IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccRxFIFOOverrunCheck (
+ void);
+
+#endif /* __ixp46X */
+#endif /* IXSSPACC_H */
diff --git a/cpu/ixp/npe/include/IxTimeSyncAcc.h b/cpu/ixp/npe/include/IxTimeSyncAcc.h
new file mode 100644
index 0000000..25effed
--- /dev/null
+++ b/cpu/ixp/npe/include/IxTimeSyncAcc.h
@@ -0,0 +1,783 @@
+/**
+ * @file IxTimeSyncAcc.h
+ *
+ * @author Intel Corporation
+ * @date 07 May 2004
+ *
+ * @brief Header file for IXP400 Access Layer to IEEE 1588(TM) Precision
+ * Clock Synchronisation Protocol Hardware Assist
+ *
+ * @version 1
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxTimeSyncAcc IXP400 Time Sync Access Component API
+ *
+ * @brief Public API for IxTimeSyncAcc
+ *
+ * @{
+ */
+#ifndef IXTIMESYNCACC_H
+#define IXTIMESYNCACC_H
+
+#ifdef __ixp46X
+
+#include "IxOsal.h"
+
+/**
+ * Section for enum
+ */
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @enum IxTimeSyncAccStatus
+ *
+ * @brief The status as returned from the API
+ */
+typedef enum /**< IxTimeSyncAccStatus */
+{
+ IX_TIMESYNCACC_SUCCESS = IX_SUCCESS, /**< Requested operation successful */
+ IX_TIMESYNCACC_INVALIDPARAM, /**< An invalid parameter was passed */
+ IX_TIMESYNCACC_NOTIMESTAMP, /**< While polling no time stamp available */
+ IX_TIMESYNCACC_INTERRUPTMODEINUSE, /**< Polling not allowed while operating in interrupt mode */
+ IX_TIMESYNCACC_FAILED /**< Internal error occurred */
+}IxTimeSyncAccStatus;
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @enum IxTimeSyncAccAuxMode
+ *
+ * @brief Master or Slave Auxiliary Time Stamp (Snap Shot)
+ */
+typedef enum /**< IxTimeSyncAccAuxMode */
+{
+ IX_TIMESYNCACC_AUXMODE_MASTER, /**< Auxiliary Master Mode */
+ IX_TIMESYNCACC_AUXMODE_SLAVE, /**< Auxiliary Slave Mode */
+ IX_TIMESYNCACC_AUXMODE_INVALID /**< Invalid Auxiliary Mode */
+}IxTimeSyncAccAuxMode;
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @enum IxTimeSyncAcc1588PTPPort
+ *
+ * @brief IEEE 1588 PTP Communication Port(Channel)
+ */
+typedef enum /**< IxTimeSyncAcc1588PTPPort */
+{
+ IX_TIMESYNCACC_NPE_A_1588PTP_PORT, /**< PTP Communication Port on NPE-A */
+ IX_TIMESYNCACC_NPE_B_1588PTP_PORT, /**< PTP Communication Port on NPE-B */
+ IX_TIMESYNCACC_NPE_C_1588PTP_PORT, /**< PTP Communication Port on NPE-C */
+ IX_TIMESYNCACC_NPE_1588PORT_INVALID /**< Invalid PTP Communication Port */
+} IxTimeSyncAcc1588PTPPort;
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @enum IxTimeSyncAcc1588PTPPortMode
+ *
+ * @brief Master or Slave mode for IEEE 1588 PTP Communication Port
+ */
+typedef enum /**< IxTimeSyncAcc1588PTPPortMode */
+{
+ IX_TIMESYNCACC_1588PTP_PORT_MASTER, /**< PTP Communication Port in Master Mode */
+ IX_TIMESYNCACC_1588PTP_PORT_SLAVE, /**< PTP Communication Port in Slave Mode */
+ IX_TIMESYNCACC_1588PTP_PORT_ANYMODE, /**< PTP Communication Port in ANY Mode
+ allows time stamping of all messages
+ including non-1588 PTP */
+ IX_TIMESYNCACC_1588PTP_PORT_MODE_INVALID /**< Invalid PTP Port Mode */
+}IxTimeSyncAcc1588PTPPortMode;
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @enum IxTimeSyncAcc1588PTPMsgType
+ *
+ * @brief 1588 PTP Messages types that can be detected on communication port
+ *
+ * Note that client code can determine this based on master/slave mode in which
+ * it is already operating in and this information is made available for the sake
+ * of convenience only.
+ */
+typedef enum /**< IxTimeSyncAcc1588PTPMsgType */
+{
+ IX_TIMESYNCACC_1588PTP_MSGTYPE_SYNC, /**< PTP Sync message sent by Master or received by Slave */
+ IX_TIMESYNCACC_1588PTP_MSGTYPE_DELAYREQ, /**< PTP Delay_Req message sent by Slave or received by Master */
+ IX_TIMESYNCACC_1588PTP_MSGTYPE_UNKNOWN /**< Other PTP and non-PTP message sent or received by both
+ Master and/or Slave */
+} IxTimeSyncAcc1588PTPMsgType;
+
+/**
+ * Section for struct
+ */
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @struct IxTimeSyncAccTimeValue
+ *
+ * @brief Struct to hold 64 bit SystemTime and TimeStamp values
+ */
+typedef struct /**< IxTimeSyncAccTimeValue */
+{
+ UINT32 timeValueLowWord; /**< Lower 32 bits of the time value */
+ UINT32 timeValueHighWord; /**< Upper 32 bits of the time value */
+} IxTimeSyncAccTimeValue;
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @struct IxTimeSyncAccUuid
+ *
+ * @brief Struct to hold 48 bit UUID values captured in Sync or Delay_Req messages
+ */
+typedef struct /**< IxTimeSyncAccUuid */
+{
+ UINT32 uuidValueLowWord; /**<The lower 32 bits of the UUID */
+ UINT16 uuidValueHighHalfword; /**<The upper 16 bits of the UUID */
+} IxTimeSyncAccUuid;
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @struct IxTimeSyncAccPtpMsgData
+ *
+ * @brief Struct for data from the PTP message returned when TimeStamp available
+ */
+typedef struct /**< IxTimeSyncAccPtpMsgData */
+{
+ IxTimeSyncAcc1588PTPMsgType ptpMsgType; /**< PTP Messages type */
+ IxTimeSyncAccTimeValue ptpTimeStamp; /**< 64 bit TimeStamp value from PTP Message */
+ IxTimeSyncAccUuid ptpUuid; /**< 48 bit UUID value from the PTP Message */
+ UINT16 ptpSequenceNumber; /**< 16 bit Sequence Number from PTP Message */
+} IxTimeSyncAccPtpMsgData;
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @struct IxTimeSyncAccStats
+ *
+ * @brief Statistics for the PTP messages
+ */
+typedef struct /**< IxTimeSyncAccStats */
+{
+ UINT32 rxMsgs; /**< Count of timestamps for received PTP Messages */
+ UINT32 txMsgs; /**< Count of timestamps for transmitted PTP Messages */
+} IxTimeSyncAccStats;
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @typedef IxTimeSyncAccTargetTimeCallback
+ *
+ * @brief Callback for use by target time stamp interrupt
+ */
+typedef void (*IxTimeSyncAccTargetTimeCallback)(IxTimeSyncAccTimeValue targetTime);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @typedef IxTimeSyncAccAuxTimeCallback
+ *
+ * @brief Callback for use by auxiliary time interrupts
+ */
+typedef void (*IxTimeSyncAccAuxTimeCallback)(IxTimeSyncAccAuxMode auxMode,
+ IxTimeSyncAccTimeValue auxTime);
+
+/*
+ * Section for prototypes interface functions
+ */
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccPTPPortConfigSet(
+ IxTimeSyncAcc1588PTPPort ptpPort,
+ IxTimeSyncAcc1588PTPPortMode ptpPortMode)
+ *
+ * @brief Configures the IEEE 1588 message detect on particular PTP port.
+ *
+ * @param ptpPort [in] - PTP port to config
+ * @param ptpPortMode [in]- Port to operate in Master or Slave mode
+ *
+ * This API will enable the time stamping on a particular PTP port.
+ *
+ * @li Re-entrant : No
+ * @li ISR Callable : No
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccPTPPortConfigSet(IxTimeSyncAcc1588PTPPort ptpPort,
+ IxTimeSyncAcc1588PTPPortMode ptpPortMode);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccPTPPortConfigGet(
+ IxTimeSyncAcc1588PTPPort ptpPort,
+ IxTimeSyncAcc1588PTPPortMode *ptpPortMode)
+ *
+ * @brief Retrieves IEEE 1588 PTP operation mode on particular PTP port.
+ *
+ * @param ptpPort [in] - PTP port
+ * @param ptpPortMode [in]- Mode of operation of PTP port (Master or Slave)
+ *
+ * This API will identify the time stamping capability of a PTP port by means
+ * of obtaining its mode of operation.
+ *
+ * @li Re-entrant : No
+ * @li ISR Callable : No
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccPTPPortConfigGet(IxTimeSyncAcc1588PTPPort ptpPort,
+ IxTimeSyncAcc1588PTPPortMode *ptpPortMode);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccPTPRxPoll(
+ IxTimeSyncAcc1588PTPPort ptpPort,
+ IxTimeSyncAccPtpMsgData *ptpMsgData)
+ *
+ * @brief Polls the IEEE 1588 message/time stamp detect status on a particular
+ * PTP Port on the Receive side.
+ *
+ * @param ptpPort [in] - PTP port to poll
+ * @param ptpMsgData [out] - Current TimeStamp and other Data
+ *
+ * This API will poll for the availability of a time stamp on the received Sync
+ * (Slave) or Delay_Req (Master) messages.
+ * The client application will provide the buffer.
+ *
+ * @li Re-entrant : No
+ * @li ISR Callable : No
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed
+ * @li IX_TIMESYNCACC_NOTIMESTAMP - No time stamp available
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccPTPRxPoll(IxTimeSyncAcc1588PTPPort ptpPort,
+ IxTimeSyncAccPtpMsgData *ptpMsgData);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccPTPTxPoll(
+ IxTimeSyncAcc1588PTPPort ptpPort,
+ IxTimeSyncAccPtpMsgData *ptpMsgData)
+ *
+ *
+ * @brief Polls the IEEE 1588 message/time stamp detect status on a particular
+ * PTP Port on the Transmit side.
+ *
+ * @param ptpPort [in] - PTP port to poll
+ * @param ptpMsgData [out] - Current TimeStamp and other Data
+ *
+ * This API will poll for the availability of a time stamp on the transmitted
+ * Sync (Master) or Delay_Req (Slave) messages.
+ * The client application will provide the buffer.
+ *
+ * @li Re-entrant : No
+ * @li ISR Callable : No
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed
+ * @li IX_TIMESYNCACC_NOTIMESTAMP - No time stamp available
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccPTPTxPoll(IxTimeSyncAcc1588PTPPort ptpPort,
+ IxTimeSyncAccPtpMsgData *ptpMsgData);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccSystemTimeSet(
+ IxTimeSyncAccTimeValue systemTime)
+ *
+ * @brief Sets the System Time in the IEEE 1588 hardware assist block
+ *
+ * @param systemTime [in] - Value to set System Time
+ *
+ * This API will set the SystemTime to given value.
+ *
+ * @li Re-entrant : yes
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccSystemTimeSet(IxTimeSyncAccTimeValue systemTime);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccSystemTimeGet(
+ IxTimeSyncAccTimeValue *systemTime)
+ *
+ * @brief Gets the System Time from the IEEE 1588 hardware assist block
+ *
+ * @param systemTime [out] - Copy the current System Time into the client
+ * application provided buffer
+ *
+ * This API will get the SystemTime from IEEE1588 block and return to client
+ *
+ * @li Re-entrant : no
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccSystemTimeGet(IxTimeSyncAccTimeValue *systemTime);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccTickRateSet(
+ UINT32 tickRate)
+ *
+ * @brief Sets the Tick Rate (Frequency Scaling Value) in the IEEE 1588
+ * hardware assist block
+ *
+ * @param tickRate [in] - Value to set Tick Rate
+ *
+ * This API will set the Tick Rate (Frequency Scaling Value) in the IEEE
+ * 1588 block to the given value. The Accumulator register (not client
+ * visible) is incremented by this TickRate value every clock cycle. When
+ * the Accumulator overflows, the SystemTime is incremented by one. This
+ * TickValue can therefore be used to adjust the system timer.
+ *
+ * @li Re-entrant : yes
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccTickRateSet(UINT32 tickRate);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccTickRateGet(
+ UINT32 *tickRate)
+ *
+ * @brief Gets the Tick Rate (Frequency Scaling Value) from the IEEE 1588
+ * hardware assist block
+ *
+ * @param tickRate [out] - Current Tick Rate value in the IEEE 1588 block
+ *
+ * This API will get the TickRate on IEE15588 block. Refer to @ref
+ * ixTimeSyncAccTickRateSet for notes on usage of this value.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccTickRateGet(UINT32 *tickRate);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccTargetTimeInterruptEnable(
+ IxTimeSyncAccTargetTimeCallback targetTimeCallback)
+ *
+ * @brief Enables the interrupt to verify the condition where the System Time
+ * greater or equal to the Target Time in the IEEE 1588 hardware assist block.
+ * If the condition is true an interrupt will be sent to XScale.
+ *
+ * @param targetTimeCallback [in] - Callback to be invoked when interrupt fires
+ *
+ * This API will enable the Target Time reached/hit condition interrupt.
+ *
+ * NOTE: The client application needs to ensure that the APIs
+ * @ref ixTimeSyncAccTargetTimeInterruptEnable, @ref ixTimeSyncAccTargetTimeSet and
+ * @ref ixTimeSyncAccTargetTimeInterruptDisable are accessed in mutual exclusive
+ * manner with respect to each other.
+ *
+ * @li Re-entrant : no
+ * @li ISR Callable : yes
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed for callback
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccTargetTimeInterruptEnable(IxTimeSyncAccTargetTimeCallback targetTimeCallback);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccTargetTimeInterruptDisable(
+ void)
+ *
+ * @brief Disables the interrupt for the condition explained in the function
+ * description of @ref ixTimeSyncAccTargetTimeInterruptEnable.
+ *
+ * This API will disable the Target Time interrupt.
+ *
+ * NOTE: The client application needs to ensure that the APIs
+ * @ref ixTimeSyncAccTargetTimeInterruptEnable, @ref ixTimeSyncAccTargetTimeSet and
+ * @ref ixTimeSyncAccTargetTimeInterruptDisable are accessed in mutual exclusive
+ * manner with respect to each other.
+ *
+ * @li Re-entrant : no
+ * @li ISR Callable : yes
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccTargetTimeInterruptDisable(void);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccTargetTimePoll(
+ BOOL *ttmPollFlag,
+ IxTimeSyncAccTimeValue *targetTime)
+ *
+ * @brief Poll to verify the condition where the System Time greater or equal to
+ * the Target Time in the IEEE 1588 hardware assist block. If the condition is
+ * true an event flag is set in the hardware.
+ *
+ * @param ttmPollFlag [out] - TRUE if the target time reached/hit condition event set
+ * FALSE if the target time reached/hit condition event is
+ not set
+ * @param targetTime [out] - Capture current targetTime into client provided buffer
+ *
+ * Poll the target time reached/hit condition status. Return true and the current
+ * target time value, if the condition is true else return false.
+ *
+ * NOTE: The client application will need to clear the event flag that will be set
+ * as long as the condition that the System Time greater or equal to the Target Time is
+ * valid, in one of the following ways:
+ * 1) Invoke the API to change the target time
+ * 2) Change the system timer value
+ *
+ * @li Re-entrant : yes
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ * @li IX_TIMESYNCACC_INTERRUPTMODEINUSE - Interrupt mode in use
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccTargetTimePoll(BOOL *ttmPollFlag,
+ IxTimeSyncAccTimeValue *targetTime);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccTargetTimeSet(
+ IxTimeSyncAccTimeValue targetTime)
+ *
+ * @brief Sets the Target Time in the IEEE 1588 hardware assist block
+ *
+ * @param targetTime [in] - Value to set Target Time
+ *
+ * This API will set the Target Time to a given value.
+ *
+ * NOTE: The client application needs to ensure that the APIs
+ * @ref ixTimeSyncAccTargetTimeInterruptEnable, @ref ixTimeSyncAccTargetTimeSet and
+ * @ref ixTimeSyncAccTargetTimeInterruptDisable are accessed in mutual exclusive
+ * manner with respect to each other.
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : yes
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccTargetTimeSet(IxTimeSyncAccTimeValue targetTime);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccTargetTimeGet(
+ IxTimeSyncAccTimeValue *targetTime)
+ *
+ * @brief Gets the Target Time in the IEEE 1588 hardware assist block
+ *
+ * @param targetTime [out] - Copy current time to client provided buffer
+ *
+ * This API will get the Target Time from IEEE 1588 block and return to the
+ * client application
+ *
+ * @li Re-entrant : yes
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccTargetTimeGet(IxTimeSyncAccTimeValue *targetTime);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccAuxTimeInterruptEnable(
+ IxTimeSyncAccAuxMode auxMode,
+ IxTimeSyncAccAuxTimeCallback auxTimeCallback)
+ *
+ * @brief Enables the interrupt notification for the given mode of Auxiliary Time
+ * Stamp in the IEEE 1588 hardware assist block
+ *
+ * @param auxMode [in] - Auxiliary time stamp register (slave or master) to use
+ * @param auxTimeCallback [in] - Callback to be invoked when interrupt fires
+ *
+ * This API will enable the Auxiliary Master/Slave Time stamp Interrupt.
+ *
+ * <pre>
+ * NOTE: 1) An individual callback is to be registered for each Slave and Master
+ * Auxiliary Time Stamp registers. Thus to register for both Master and Slave time
+ * stamp interrupts either the same callback or two separate callbacks the API has
+ * to be invoked twice.
+ * 2) On the IXDP465 Development Platform, the Auxiliary Timestamp signal for
+ * slave mode is tied to GPIO 8 pin. This signal is software routed by default to
+ * PCI for backwards compatibility with the IXDP425 Development Platform. This
+ * routing must be disabled for the auxiliary slave time stamp register to work
+ * properly. The following commands may be used to accomplish this. However, refer
+ * to the IXDP465 Development Platform Users Guide or the BSP/LSP documentation for
+ * more specific information.
+ *
+ * For Linux (at the Redboot prompt i.e., before loading zImage):
+ * mfill -b 0x54100000 -1 -l 1 -p 8
+ * mfill -b 0x54100001 -1 -l 1 -p 0x7f
+ * For vxWorks, at the prompt:
+ * intDisable(25)
+ * ixdp400FpgaIODetach(8)
+ * </pre>
+ *
+ * @li Re-entrant : no
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed for callback or
+ invalid auxiliary snapshot mode
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccAuxTimeInterruptEnable(IxTimeSyncAccAuxMode auxMode,
+ IxTimeSyncAccAuxTimeCallback auxTimeCallback);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccAuxTimeInterruptDisable(
+ IxTimeSyncAccAuxMode auxMode)
+ *
+ * @brief Disables the interrupt for the indicated mode of Auxiliary Time Stamp
+ * in the IEEE 1588 hardware assist block
+ *
+ * @param auxMode [in] - Auxiliary time stamp mode (slave or master) using which
+ * the interrupt will be disabled.
+ *
+ * This API will disable the Auxiliary Time Stamp Interrupt (Master or Slave)
+ *
+ * @li Re-entrant : yes
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccAuxTimeInterruptDisable(IxTimeSyncAccAuxMode auxMode);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccAuxTimePoll(
+ IxTimeSyncAccAuxMode auxMode,
+ BOOL *auxPollFlag,
+ IxTimeSyncAccTimeValue *auxTime)
+ *
+ * @brief Poll for the Auxiliary Time Stamp captured for the mode indicated
+ * (Master or Slave)
+ *
+ * @param auxMode [in] - Auxiliary Snapshot Register (Slave or Master) to be checked
+ * @param auxPollFlag [out] - TRUE if the time stamp captured in auxiliary
+ snapshot register
+ * FALSE if the time stamp not captured in
+ auxiliary snapshot register
+ * @param auxTime [out] - Copy the current Auxiliary Snapshot Register value into the
+ * client provided buffer
+ *
+ * Polls for the Time stamp in the appropriate Auxiliary Snapshot Registers based
+ * on the mode specified. Return true and the contents of the Auxiliary snapshot,
+ * if it is available else return false.
+ *
+ * Please refer to the note #2 of the API @ref ixTimeSyncAccAuxTimeInterruptEnable
+ * for more information for Auxiliary Slave mode.
+ *
+ * @li Re-entrant : yes
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed for auxPollFlag,
+ callback or invalid auxiliary snapshot mode
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ * @li IX_TIMESYNCACC_INTERRUPTMODEINUSE - Interrupt mode in use
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccAuxTimePoll(IxTimeSyncAccAuxMode auxMode,
+ BOOL *auxPollFlag,
+ IxTimeSyncAccTimeValue *auxTime);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccReset(void)
+ *
+ * @brief Resets the IEEE 1588 hardware assist block
+ *
+ * Sets the reset bit in the IEEE1588 silicon which fully resets the silicon block
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccReset(void);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccStatsGet(IxTimeSyncAccStats
+ *timeSyncStats)
+ *
+ * @brief Returns the IxTimeSyncAcc Statistics in the client supplied buffer
+ *
+ * @param timeSyncStats [out] - TimeSync statistics counter values
+ *
+ * This API will return the statistics of the received or transmitted messages.
+ *
+ * NOTE: 1) These counters are updated only when the client polls for the time
+ * stamps or interrupt are enabled. This is because the IxTimeSyncAcc module
+ * does not either transmit or receive messages and does only run the code
+ * when explicit requests received by client application.
+ *
+ * 2) These statistics reflect the number of valid PTP messages exchanged
+ * in Master and Slave modes but includes all the messages (including valid
+ * non-PTP messages) while operating in the Any mode.
+ *
+ * @li Reentrant : no
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_INVALIDPARAM - NULL parameter passed
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccStatsGet(IxTimeSyncAccStats *timeSyncStats);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn void ixTimeSyncAccStatsReset(void)
+ *
+ * @brief Reset Time Sync statistics
+ *
+ * This API will reset the statistics counters of the TimeSync access layer.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable: no
+ *
+ * @return @li None
+ */
+PUBLIC void
+ixTimeSyncAccStatsReset(void);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccShow(void)
+ *
+ * @brief Displays the Time Sync current status
+ *
+ * This API will display status on the current configuration of the IEEE
+ * 1588 hardware assist block, contents of the various time stamp registers,
+ * outstanding interrupts and/or events.
+ *
+ * Note that this is intended for debug only, and in contrast to the other
+ * functions, it does not clear the any of the status bits associated with
+ * active timestamps and so is passive in its nature.
+ *
+ * @li Reentrant : yes
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ * @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccShow(void);
+
+#endif /* __ixp46X */
+#endif /* IXTIMESYNCACC_H */
+
+/**
+ * @} defgroup IxTimeSyncAcc
+ */
+
diff --git a/cpu/ixp/npe/include/IxTimerCtrl.h b/cpu/ixp/npe/include/IxTimerCtrl.h
new file mode 100644
index 0000000..669dd3e
--- /dev/null
+++ b/cpu/ixp/npe/include/IxTimerCtrl.h
@@ -0,0 +1,263 @@
+/**
+ * @file IxTimerCtrl.h
+ * @brief
+ * This is the header file for the Timer Control component.
+ *
+ * The timer callback control component provides a mechanism by which different
+ * client components can start a timer and have a supplied callback function
+ * invoked when the timer expires.
+ * The callbacks are all dispatched from one thread inside this component.
+ * Any component that needs to be called periodically should use this facility
+ * rather than create its own task with a sleep loop.
+ *
+ * @par
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxTimerCtrl IXP400 Timer Control (IxTimerCtrl) API
+ *
+ * @brief The public API for the IXP400 Timer Control Component.
+ *
+ * @{
+ */
+
+#ifndef IxTimerCtrl_H
+#define IxTimerCtrl_H
+
+
+#include "IxTypes.h"
+/* #include "Ossl.h" */
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @def IX_TIMERCTRL_NO_FREE_TIMERS
+ *
+ * @brief Timer schedule return code.
+ *
+ * Indicates that the request to start a timer failed because
+ * all available timer resources are used.
+ */
+#define IX_TIMERCTRL_NO_FREE_TIMERS 2
+
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @def IX_TIMERCTRL_PARAM_ERROR
+ *
+ * @brief Timer schedule return code.
+ *
+ * Indicates that the request to start a timer failed because
+ * the client has supplied invalid parameters.
+ */
+#define IX_TIMERCTRL_PARAM_ERROR 3
+
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @brief A typedef for a pointer to a timer callback function.
+ * @para void * - This parameter is supplied by the client when the
+ * timer is started and passed back to the client in the callback.
+ * @note in general timer callback functions should not block or
+ * take longer than 100ms. This constraint is required to ensure that
+ * higher priority callbacks are not held up.
+ * All callbacks are called from the same thread.
+ * This thread is a shared resource.
+ * The parameter passed is provided when the timer is scheduled.
+ */
+typedef void (*IxTimerCtrlTimerCallback)(void *userParam);
+
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @brief List used to identify the users of timers.
+ * @note The order in this list indicates priority. Components appearing
+ * higher in the list will be given priority over components lower in the
+ * list. When adding components, please insert at an appropriate position
+ * for priority ( i.e values should be less than IxTimerCtrlMaxPurpose ) .
+ */
+typedef enum
+{
+ IxTimerCtrlAdslPurpose,
+ /* Insert new purposes above this line only
+ */
+ IxTimerCtrlMaxPurpose
+}
+IxTimerCtrlPurpose;
+
+
+/*
+ * Function definition
+ */
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @fn ixTimerCtrlSchedule(IxTimerCtrlTimerCallback func,
+ void *userParam,
+ IxTimerCtrlPurpose purpose,
+ UINT32 relativeTime,
+ unsigned *timerId )
+ *
+ * @brief Schedules a callback function to be called after a period of "time".
+ * The callback function should not block or run for more than 100ms.
+ * This function
+ *
+ * @param func @ref IxTimerCtrlTimerCallback [in] - the callback function to be called.
+ * @param userParam void [in] - a parameter to send to the callback function, can be NULL.
+ * @param purpose @ref IxTimerCtrlPurpose [in] - the purpose of the callback, internally this component will
+ * decide the priority of callbacks with different purpose.
+ * @param relativeTime UINT32 [in] - time relative to now in milliseconds after which the callback
+ * will be called. The time must be greater than the duration of one OS tick.
+ * @param *timerId unsigned [out] - An id for the callback scheduled.
+ * This id can be used to cancel the callback.
+ * @return
+ * @li IX_SUCCESS - The timer was started successfully.
+ * @li IX_TIMERCTRL_NO_FREE_TIMERS - The timer was not started because the maximum number
+ * of running timers has been exceeded.
+ * @li IX_TIMERCTRL_PARAM_ERROR - The timer was not started because the client has supplied
+ * a NULL callback func, or the requested timeout is less than one OS tick.
+ * @note This function is re-entrant. The function accesses a list of running timers
+ * and may suspend the calling thread if this list is being accesed by another thread.
+ */
+PUBLIC IX_STATUS
+ixTimerCtrlSchedule(IxTimerCtrlTimerCallback func,
+ void *userParam,
+ IxTimerCtrlPurpose purpose,
+ UINT32 relativeTime,
+ unsigned *timerId );
+
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @fn ixTimerCtrlScheduleRepeating(IxTimerCtrlTimerCallback func,
+ void *param,
+ IxTimerCtrlPurpose purpose,
+ UINT32 interval,
+ unsigned *timerId )
+ *
+ * @brief Schedules a callback function to be called after a period of "time".
+ * The callback function should not block or run for more than 100ms.
+ *
+ * @param func @ref IxTimerCtrlTimerCallback [in] - the callback function to be called.
+ * @param userParam void [in] - a parameter to send to the callback function, can be NULL.
+ * @param purpose @ref IxTimerCtrlPurpose [in] - the purpose of the callback, internally this component will
+ * decide the priority of callbacks with different purpose.
+ * @param interval UINT32 [in] - the interval in milliseconds between calls to func.
+ * @param timerId unsigned [out] - An id for the callback scheduled.
+ * This id can be used to cancel the callback.
+ * @return
+ * @li IX_SUCCESS - The timer was started successfully.
+ * @li IX_TIMERCTRL_NO_FREE_TIMERS - The timer was not started because the maximum number
+ * of running timers has been exceeded.
+ * @li IX_TIMERCTRL_PARAM_ERROR - The timer was not started because the client has supplied
+ * a NULL callback func, or the requested timeout is less than one OS tick.
+ * @note This function is re-entrant. The function accesses a list of running timers
+ * and may suspend the calling thread if this list is being accesed by another thread.
+ */
+PUBLIC IX_STATUS
+ixTimerCtrlScheduleRepeating(IxTimerCtrlTimerCallback func,
+ void *param,
+ IxTimerCtrlPurpose purpose,
+ UINT32 interval,
+ unsigned *timerId );
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @fn ixTimerCtrlCancel (unsigned id)
+ *
+ * @brief Cancels a scheduled callback.
+ *
+ * @param id unsigned [in] - the id of the callback to be cancelled.
+ * @return
+ * @li IX_SUCCESS - The timer was successfully stopped.
+ * @li IX_FAIL - The id parameter did not corrrespond to any running timer..
+ * @note This function is re-entrant. The function accesses a list of running timers
+ * and may suspend the calling thread if this list is being accesed by another thread.
+ */
+PUBLIC IX_STATUS
+ixTimerCtrlCancel (unsigned id);
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @fn ixTimerCtrlInit(void)
+ *
+ * @brief Initialise the Timer Control Component.
+ * @return
+ * @li IX_SUCCESS - The timer control component initialized successfully.
+ * @li IX_FAIL - The timer control component initialization failed,
+ * or the component was already initialized.
+ * @note This must be done before any other API function is called.
+ * This function should be called once only and is not re-entrant.
+ */
+PUBLIC IX_STATUS
+ixTimerCtrlInit(void);
+
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @fn ixTimerCtrlShow( void )
+ *
+ * @brief Display the status of the Timer Control Component.
+ * @return void
+ * @note Displays a list of running timers.
+ * This function is not re-entrant. This function does not suspend the calling thread.
+ */
+PUBLIC void
+ixTimerCtrlShow( void );
+
+#endif /* IXTIMERCTRL_H */
+
diff --git a/cpu/ixp/npe/include/IxTypes.h b/cpu/ixp/npe/include/IxTypes.h
new file mode 100644
index 0000000..c4c5a2d
--- /dev/null
+++ b/cpu/ixp/npe/include/IxTypes.h
@@ -0,0 +1,86 @@
+/**
+ * @file IxTypes.h (Replaced by OSAL)
+ *
+ * @date 28-NOV-2001
+
+ * @brief This file contains basic types used by the IXP400 software
+ *
+ * Design Notes:
+ * This file shall only include fundamental types and definitions to be
+ * shared by all the IXP400 components.
+ * Please DO NOT add component-specific types here.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxTypes IXP400 Types (IxTypes)
+ *
+ * @brief Basic data types used by the IXP400 project
+ *
+ * @{
+ */
+
+#ifndef IxTypes_H
+
+#ifndef __doxygen_HIDE
+
+#define IxTypes_H
+
+#endif /* __doxygen_HIDE */
+
+
+/* WR51880: Undefined data types workaround for backward compatibility */
+#ifdef __linux
+#ifndef __INCvxTypesOldh
+typedef int (*FUNCPTR)(void);
+typedef int STATUS;
+#define OK (0)
+#define ERROR (-1)
+#endif
+#endif
+
+#include "IxOsalBackward.h"
+
+#endif /* IxTypes_H */
+
+/**
+ * @} addtogroup IxTypes
+ */
diff --git a/cpu/ixp/npe/include/IxUART.h b/cpu/ixp/npe/include/IxUART.h
new file mode 100644
index 0000000..03a4444
--- /dev/null
+++ b/cpu/ixp/npe/include/IxUART.h
@@ -0,0 +1,458 @@
+/**
+ * @file IxUART.h
+ *
+ * @date 12-OCT-01
+ *
+ * @brief Public header for the Intel IXP400 internal UART, generic driver.
+ *
+ * Design Notes:
+ * This driver allows you to perform the following functions:
+ * Device Initialization,
+ * send/receive characters.
+ *
+ * Perform Uart IOCTL for the following:
+ * Set/Get the current baud rate,
+ * set parity,
+ * set the number of Stop bits,
+ * set the character Length (5,6,7,8),
+ * enable/disable Hardware flow control.
+ *
+ * Only Polled mode is supported for now.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxUARTAccAPI IXP400 UART Access (IxUARTAcc) API
+ *
+ * @brief IXP400 UARTAcc Driver Public API
+ *
+ * @{
+ */
+
+
+/* Defaults */
+
+/**
+ * @defgroup DefaultDefines Defines for Default Values
+ *
+ * @brief Default values which can be used for UART configuration
+ *
+ * @sa ixUARTDev
+ */
+
+/**
+ * @def IX_UART_DEF_OPTS
+ *
+ * @brief The default hardware options to set the UART to -
+ * no flow control, 8 bit word, 1 stop bit, no parity
+ *
+ * @ingroup DefaultDefines
+ */
+#define IX_UART_DEF_OPTS (CLOCAL | CS8)
+
+/**
+ * @def IX_UART_DEF_XMIT
+ *
+ * @brief The default UART FIFO size - must be no bigger than 64
+ *
+ * @ingroup DefaultDefines
+ */
+#define IX_UART_DEF_XMIT 64
+
+/**
+ * @def IX_UART_DEF_BAUD
+ *
+ * @brief The default UART baud rate - 9600
+ *
+ * @ingroup DefaultDefines
+ */
+#define IX_UART_DEF_BAUD 9600
+
+/**
+ * @def IX_UART_MIN_BAUD
+ *
+ * @brief The minimum UART baud rate - 9600
+ *
+ * @ingroup DefaultDefines
+ */
+#define IX_UART_MIN_BAUD 9600
+
+/**
+ * @def IX_UART_MAX_BAUD
+ *
+ * @brief The maximum UART baud rate - 926100
+ *
+ * @ingroup DefaultDefines
+ */
+#define IX_UART_MAX_BAUD 926100
+
+/**
+ * @def IX_UART_XTAL
+ *
+ * @brief The UART clock speed
+ *
+ * @ingroup DefaultDefines
+ */
+#define IX_UART_XTAL 14745600
+
+
+
+/* IOCTL commands (Request codes) */
+
+/**
+ * @defgroup IoctlCommandDefines Defines for IOCTL Commands
+ *
+ * @brief IOCTL Commands (Request codes) which can be used
+ * with @ref ixUARTIoctl
+ */
+
+
+/**
+ * @ingroup IoctlCommandDefines
+ *
+ * @def IX_BAUD_SET
+ *
+ * @brief Set the baud rate
+ */
+#define IX_BAUD_SET 0
+
+/**
+ * @ingroup IoctlCommandDefines
+ *
+ * @def IX_BAUD_GET
+ *
+ * @brief Get the baud rate
+ */
+#define IX_BAUD_GET 1
+
+/**
+ * @ingroup IoctlCommandDefines
+ * @def IX_MODE_SET
+ * @brief Set the UART mode of operation
+ */
+#define IX_MODE_SET 2
+
+/**
+ * @ingroup IoctlCommandDefines
+ *
+ * @def IX_MODE_GET
+ *
+ * @brief Get the current UART mode of operation
+ */
+#define IX_MODE_GET 3
+
+/**
+ * @ingroup IoctlCommandDefines
+ *
+ * @def IX_OPTS_SET
+ *
+ * @brief Set the UART device options
+ */
+#define IX_OPTS_SET 4
+
+/**
+ * @ingroup IoctlCommandDefines
+ *
+ * @def IX_OPTS_GET
+ *
+ * @brief Get the UART device options
+ */
+#define IX_OPTS_GET 5
+
+/**
+ * @ingroup IoctlCommandDefines
+ *
+ * @def IX_STATS_GET
+ *
+ * @brief Get the UART statistics
+ */
+#define IX_STATS_GET 6
+
+
+/* POSIX style ioctl arguments */
+
+/**
+ * @defgroup IoctlArgDefines Defines for IOCTL Arguments
+ *
+ * @brief POSIX style IOCTL arguments which can be used
+ * with @ref ixUARTIoctl
+ *
+ * @sa ixUARTMode
+ */
+
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def CLOCAL
+ *
+ * @brief Software flow control
+ */
+#ifdef CLOCAL
+#undef CLOCAL
+#endif
+#define CLOCAL 0x1
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def CREAD
+ *
+ * @brief Enable interrupt receiver
+ */
+#ifdef CREAD
+#undef CREAD
+#endif
+#define CREAD 0x2
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def CSIZE
+ *
+ * @brief Characters size
+ */
+#ifdef CSIZE
+#undef CSIZE
+#endif
+#define CSIZE 0xc
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def CS5
+ *
+ * @brief 5 bits
+ */
+#ifdef CS5
+#undef CS5
+#endif
+#define CS5 0x0
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def CS6
+ *
+ * @brief 6 bits
+ */
+#ifdef CS6
+#undef CS6
+#endif
+#define CS6 0x4
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def CS7
+ *
+ * @brief 7 bits
+ */
+#ifdef CS7
+#undef CS7
+#endif
+#define CS7 0x8
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def CS8
+ *
+ * @brief 8 bits
+ */
+#ifdef CS8
+#undef CS8
+#endif
+#define CS8 0xc
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def STOPB
+ *
+ * @brief Send two stop bits (else one)
+ */
+#define STOPB 0x20
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def PARENB
+ *
+ * @brief Parity detection enabled (else disabled)
+ */
+#ifdef PARENB
+#undef PARENB
+#endif
+#define PARENB 0x40
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def PARODD
+ *
+ * @brief Odd parity (else even)
+ */
+#ifdef PARODD
+#undef PARODD
+#endif
+#define PARODD 0x80
+
+/**
+ * @enum ixUARTMode
+ * @brief The mode to set to UART to.
+ */
+typedef enum
+{
+ INTERRUPT=0, /**< Interrupt mode */
+ POLLED, /**< Polled mode */
+ LOOPBACK /**< Loopback mode */
+} ixUARTMode;
+
+/**
+ * @struct ixUARTStats
+ * @brief Statistics for the UART.
+ */
+typedef struct
+{
+ UINT32 rxCount;
+ UINT32 txCount;
+ UINT32 overrunErr;
+ UINT32 parityErr;
+ UINT32 framingErr;
+ UINT32 breakErr;
+} ixUARTStats;
+
+/**
+ * @struct ixUARTDev
+ * @brief Device descriptor for the UART.
+ */
+typedef struct
+{
+ UINT8 *addr; /**< device base address */
+ ixUARTMode mode; /**< interrupt, polled or loopback */
+ int baudRate; /**< baud rate */
+ int freq; /**< UART clock frequency */
+ int options; /**< hardware options */
+ int fifoSize; /**< FIFO xmit size */
+
+ ixUARTStats stats; /**< device statistics */
+} ixUARTDev;
+
+/**
+ * @ingroup IxUARTAccAPI
+ *
+ * @fn IX_STATUS ixUARTInit(ixUARTDev* pUART)
+ *
+ * @param pUART @ref ixUARTDev [in] - pointer to UART structure describing our device.
+ *
+ * @brief Initialise the UART. This puts the chip in a quiescent state.
+ *
+ * @pre The base address for the UART must contain a valid value.
+ * Also the baud rate and hardware options must contain sensible values
+ * otherwise the defaults will be used as defined in ixUART.h
+ *
+ * @post UART is initialized and ready to send and receive data.
+ *
+ * @note This function should only be called once per device.
+ *
+ * @retval IX_SUCCESS - UART device successfully initialised.
+ * @retval IX_FAIL - Critical error, device not initialised.
+ ***************************************************************************/
+PUBLIC IX_STATUS ixUARTInit(ixUARTDev* pUART);
+
+/**
+ * @ingroup IxUARTAccAPI
+ *
+ * @fn IX_STATUS ixUARTPollOutput(ixUARTDev* pUART, int outChar)
+ *
+ * @param pUART @ref ixUARTDev [out] - pointer to UART structure describing our device.
+ * @param outChar int [out] - character to transmit.
+ *
+ * @brief Transmit a character in polled mode.
+ *
+ * @pre UART device must be initialised.
+ *
+ * @retval IX_SUCCESS - character was successfully transmitted.
+ * @retval IX_FAIL - output buffer is full (try again).
+ ***************************************************************************/
+PUBLIC IX_STATUS ixUARTPollOutput(ixUARTDev* pUART, int outChar);
+
+/**
+ * @ingroup IxUARTAccAPI
+ *
+ * @fn IX_STATUS ixUARTPollInput(ixUARTDev* pUART, char *inChar)
+ *
+ * @param pUART @ref ixUARTDev [in] - pointer to UART structure describing our device.
+ * @param *inChar char [in] - character read from the device.
+ *
+ * @brief Receive a character in polled mode.
+ *
+ * @pre UART device must be initialised.
+ *
+ * @retval IX_SUCCESS - character was successfully read.
+ * @retval IX_FAIL - input buffer empty (try again).
+ ***************************************************************************/
+PUBLIC IX_STATUS ixUARTPollInput(ixUARTDev* pUART, char *inChar);
+
+/**
+ * @ingroup IxUARTAccAPI
+ *
+ * @fn IX_STATUS ixUARTIoctl(ixUARTDev* pUART, int cmd, void* arg)
+ *
+ * @param pUART @ref ixUARTDev [in] - pointer to UART structure describing our device.
+ * @param cmd int [in] - an ioctl request code.
+ * @param arg void* [in] - optional argument used to set the device mode,
+ * baud rate, and hardware options.
+ *
+ * @brief Perform I/O control routines on the device.
+ *
+ * @retval IX_SUCCESS - requested feature was set/read successfully.
+ * @retval IX_FAIL - error setting/reading the requested feature.
+ *
+ * @sa IoctlCommandDefines
+ * @sa IoctlArgDefines
+ ***************************************************************************/
+PUBLIC IX_STATUS ixUARTIoctl(ixUARTDev* pUART, int cmd, void* arg);
+
+/**
+ * @} defgroup IxUARTAcc
+ */
diff --git a/cpu/ixp/npe/include/IxVersionId.h b/cpu/ixp/npe/include/IxVersionId.h
new file mode 100644
index 0000000..27796ed
--- /dev/null
+++ b/cpu/ixp/npe/include/IxVersionId.h
@@ -0,0 +1,155 @@
+/**
+ * @file IxVersionId.h
+ *
+ * @date 22-Aug-2002
+ *
+ * @brief This file contains the IXP400 Software version identifier
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxVersionId IXP400 Version ID (IxVersionId)
+ *
+ * @brief Version Identifiers
+ *
+ * @{
+ */
+
+#ifndef IXVERSIONID_H
+#define IXVERSIONID_H
+
+/**
+ * @brief Version Identifier String
+ *
+ * This string will be updated with each customer release of the IXP400
+ * Software.
+ */
+#define IX_VERSION_ID "2_0"
+
+/**
+ * This string will be updated with each customer release of the IXP400
+ * ADSL driver package.
+ */
+#define IX_VERSION_ADSL_ID "1_12"
+
+
+/**
+ * This string will be updated with each customer release of the IXP400
+ * USB Client driver package.
+ */
+#define IX_VERSION_USBRNDIS_ID "1_9"
+
+/**
+ * This string will be updated with each customer release of the IXP400
+ * I2C Linux driver package.
+ */
+#define IX_VERSION_I2C_LINUX_ID "1_0"
+
+/**
+ * @brief Linux Ethernet Driver Patch Version Identifier String
+ *
+ * This string will be updated with each release of Linux Ethernet Patch
+ */
+#define LINUX_ETHERNET_DRIVER_PATCH_ID "1_4"
+
+/**
+ * @brief Linux Integration Patch Version Identifier String
+ *
+ * This String will be updated with each release of Linux Integration Patch
+ */
+#define LINUX_INTEGRATION_PATCH_ID "1_3"
+
+/**
+ * @brief Linux Ethernet Readme version Identifier String
+ *
+ * This string will be updated with each release of Linux Ethernet Readme
+ */
+#define LINUX_ETHERNET_README_ID "1_3"
+
+/**
+ * @brief Linux Integration Readme version Identifier String
+ *
+ * This string will be updated with each release of Linux Integration Readme
+ */
+
+#define LINUX_INTEGRATION_README_ID "1_3"
+
+/**
+ * @brief Linux I2C driver Readme version Identifier String
+ *
+ * This string will be updated with each release of Linux I2C Driver Readme
+ */
+#define LINUX_I2C_DRIVER_README_ID "1_0"
+
+/**
+ * @brief ixp425_eth_update_nf_bridge.patch version Identifier String
+ *
+ * This string will be updated with each release of ixp425_eth_update_nf_bridge.
+patch
+ *
+ */
+
+#define IXP425_ETH_UPDATE_NF_BRIDGE_ID "1_3"
+
+/**
+ * @brief Internal Release Identifier String
+ *
+ * This string will be updated with each internal release (SQA drop)
+ * of the IXP400 Software.
+ */
+#define IX_VERSION_INTERNAL_ID "SQA3_5"
+
+/**
+ * @brief Compatible Tornado Version Identifier
+ */
+#define IX_VERSION_COMPATIBLE_TORNADO "Tornado2_2_1-PNE2_0"
+
+/**
+ * @brief Compatible Linux Version Identifier
+ */
+#define IX_VERSION_COMPATIBLE_LINUX "MVL3_1"
+
+
+#endif /* IXVERSIONID_H */
+
+/**
+ * @} addtogroup IxVersionId
+ */
diff --git a/cpu/ixp/npe/include/ix_error.h b/cpu/ixp/npe/include/ix_error.h
new file mode 100644
index 0000000..d32ace2
--- /dev/null
+++ b/cpu/ixp/npe/include/ix_error.h
@@ -0,0 +1,66 @@
+/**
+ * ============================================================================
+ * = COPYRIGHT
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ * = PRODUCT
+ * Intel(r) IXP425 Software Release
+ *
+ * = FILENAME
+ * ix_error.h (Replaced by OSAL)
+ *
+ * = DESCRIPTION
+ * This file will describe the basic error type and support functions that
+ * will be used by the IXA SDK Framework API.
+ *
+ * = AUTHOR
+ * Intel Corporation
+ *
+ * = CHANGE HISTORY
+ * 4/22/2002 4:19:03 PM - creation time
+ * ============================================================================
+ */
+
+#if !defined(__IX_ERROR_H__)
+#define __IX_ERROR_H__
+
+#include "IxOsalBackward.h"
+
+#endif /* end !defined(__IX_ERROR_H__) */
+
diff --git a/cpu/ixp/npe/include/ix_macros.h b/cpu/ixp/npe/include/ix_macros.h
new file mode 100644
index 0000000..53f5942
--- /dev/null
+++ b/cpu/ixp/npe/include/ix_macros.h
@@ -0,0 +1,266 @@
+/**
+ * ============================================================================
+ * = COPYRIGHT
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ * = PRODUCT
+ * Intel(r) IXP425 Software Release
+ *
+ * = FILENAME
+ * ix_macros.h
+ *
+ * = DESCRIPTION
+ * This file will define the basic preprocessor macros that are going to be used
+ * the IXA SDK Framework API.
+ *
+ * = AUTHOR
+ * Intel Corporation
+ *
+ * = CHANGE HISTORY
+ * 4/22/2002 4:41:05 PM - creation time
+ * ============================================================================
+ */
+
+#if !defined(__IX_MACROS_H__)
+#define __IX_MACROS_H__
+
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif /* end defined(__cplusplus) */
+
+
+/**
+ * MACRO NAME: IX_BIT_FIELD_MASK16
+ *
+ * DESCRIPTION: Builds the mask required to extract the bit field from a 16 bit unsigned integer value.
+ *
+ * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant
+ * bit of the bit field.
+ * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant
+ * bit of the bit field.
+ *
+ * @Return: Returns a 16 bit mask that will extract the bit field from a 16 bit unsigned integer value.
+ */
+#define IX_BIT_FIELD_MASK16( \
+ arg_FieldLSBBit, \
+ arg_FieldMSBBit \
+ ) \
+ ((ix_bit_mask16)((((ix_uint16)1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - \
+ (ix_uint16)1) << arg_FieldLSBBit))
+
+
+
+/**
+ * MACRO NAME: IX_GET_BIT_FIELD16
+ *
+ * DESCRIPTION: Extracts a bit field from 16 bit unsigned integer. The returned value is normalized in
+ * in the sense that will be right aligned.
+ *
+ * @Param: - IN arg_PackedData16 a 16 bit unsigned integer that contains the bit field of interest.
+ * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant
+ * bit of the bit field.
+ * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant
+ * bit of the bit field.
+ *
+ * @Return: Returns the value of the bit field. The value can be from 0 to (1 << (arg_FieldMSBBit + 1 -
+ * arg_FieldLSBBit)) - 1.
+ */
+#define IX_GET_BIT_FIELD16( \
+ arg_PackedData16, \
+ arg_FieldLSBBit, \
+ arg_FieldMSBBit \
+ ) \
+ (((ix_uint16)(arg_PackedData16) & IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit)) >> \
+ arg_FieldLSBBit)
+
+
+/**
+ * MACRO NAME: IX_MAKE_BIT_FIELD16
+ *
+ * DESCRIPTION: This macro will create a temporary 16 bit value with the bit field
+ * desired set to the desired value.
+ *
+ * @Param: - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to
+ * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1.
+ * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant
+ * bit of the bit field.
+ * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant
+ * bit of the bit field.
+ *
+ * @Return: Returns a temporary ix_uint16 value that has the bit field set to the appropriate value.
+ */
+#define IX_MAKE_BIT_FIELD16( \
+ arg_BitFieldValue, \
+ arg_FieldLSBBit, \
+ arg_FieldMSBBit \
+ ) \
+ (((ix_uint16)(arg_BitFieldValue) << arg_FieldLSBBit) & \
+ IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit))
+
+/**
+ * MACRO NAME: IX_SET_BIT_FIELD16
+ *
+ * DESCRIPTION: Sets a new value for a bit field from a 16 bit unsigned integer.
+ *
+ * @Param: - IN arg_PackedData16 a 16 bit unsigned integer that contains the bit field of interest.
+ * @Param: - IN arg_BitFieldValue is the new vale of the bit field. The value can be from 0 to
+ * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1.
+ * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant
+ * bit of the bit field.
+ * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant
+ * bit of the bit field.
+ *
+ * @Return: Returns the updated value of arg_PackedData16.
+ */
+#define IX_SET_BIT_FIELD16( \
+ arg_PackedData16, \
+ arg_BitFieldValue, \
+ arg_FieldLSBBit, \
+ arg_FieldMSBBit \
+ ) \
+ (arg_PackedData16 = (((ix_uint16)(arg_PackedData16) & \
+ ~(IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit))) | \
+ IX_MAKE_BIT_FIELD16(arg_BitFieldValue, arg_FieldLSBBit, arg_FieldMSBBit)))
+
+
+/**
+ * MACRO NAME: IX_BIT_FIELD_MASK32
+ *
+ * DESCRIPTION: Builds the mask required to extract the bit field from a 32 bit unsigned integer value.
+ *
+ * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant
+ * bit of the bit field.
+ * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant
+ * bit of the bit field.
+ *
+ * @Return: Returns a 32 bit mask that will extract the bit field from a 32 bit unsigned integer value.
+ */
+#define IX_BIT_FIELD_MASK32( \
+ arg_FieldLSBBit, \
+ arg_FieldMSBBit \
+ ) \
+ ((ix_bit_mask32)((((ix_uint32)1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - \
+ (ix_uint32)1) << arg_FieldLSBBit))
+
+
+
+/**
+ * MACRO NAME: IX_GET_BIT_FIELD32
+ *
+ * DESCRIPTION: Extracts a bit field from 32 bit unsigned integer. The returned value is normalized in
+ * in the sense that will be right aligned.
+ *
+ * @Param: - IN arg_PackedData32 a 32 bit unsigned integer that contains the bit field of interest.
+ * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant
+ * bit of the bit field.
+ * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant
+ * bit of the bit field.
+ *
+ * @Return: Returns the value of the bit field. The value can be from 0 to (1 << (arg_FieldMSBBit + 1 -
+ * arg_FieldLSBBit)) - 1.
+ */
+#define IX_GET_BIT_FIELD32( \
+ arg_PackedData32, \
+ arg_FieldLSBBit, \
+ arg_FieldMSBBit \
+ ) \
+ (((ix_uint32)(arg_PackedData32) & IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit)) >> \
+ arg_FieldLSBBit)
+
+
+
+
+/**
+ * MACRO NAME: IX_MAKE_BIT_FIELD32
+ *
+ * DESCRIPTION: This macro will create a temporary 32 bit value with the bit field
+ * desired set to the desired value.
+ *
+ * @Param: - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to
+ * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1.
+ * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant
+ * bit of the bit field.
+ * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant
+ * bit of the bit field.
+ *
+ * @Return: Returns a temporary ix_uint32 value that has the bit field set to the appropriate value.
+ */
+#define IX_MAKE_BIT_FIELD32( \
+ arg_BitFieldValue, \
+ arg_FieldLSBBit, \
+ arg_FieldMSBBit \
+ ) \
+ (((ix_uint32)(arg_BitFieldValue) << arg_FieldLSBBit) & \
+ IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit))
+
+
+/**
+ * MACRO NAME: IX_SET_BIT_FIELD32
+ *
+ * DESCRIPTION: Sets a new value for a bit field from a 32 bit unsigned integer.
+ *
+ * @Param: - IN arg_PackedData32 a 32 bit unsigned integer that contains the bit field of interest.
+ * @Param: - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to
+ * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1.
+ * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant
+ * bit of the bit field.
+ * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant
+ * bit of the bit field.
+ *
+ * @Return: Returns the updated value of arg_PackedData32.
+ */
+#define IX_SET_BIT_FIELD32( \
+ arg_PackedData32, \
+ arg_BitFieldValue, \
+ arg_FieldLSBBit, \
+ arg_FieldMSBBit \
+ ) \
+ (arg_PackedData32 = (((ix_uint32)(arg_PackedData32) & \
+ ~(IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit))) | \
+ IX_MAKE_BIT_FIELD32(arg_BitFieldValue, arg_FieldLSBBit, arg_FieldMSBBit)))
+
+
+
+#if defined(__cplusplus)
+}
+#endif /* end defined(__cplusplus) */
+
+#endif /* end !defined(__IX_MACROS_H__) */
diff --git a/cpu/ixp/npe/include/ix_os_type.h b/cpu/ixp/npe/include/ix_os_type.h
new file mode 100644
index 0000000..8575096
--- /dev/null
+++ b/cpu/ixp/npe/include/ix_os_type.h
@@ -0,0 +1,65 @@
+/**
+ * ============================================================================
+ * = COPYRIGHT
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ * = PRODUCT
+ * Intel(r) IXP425 Software Release
+ *
+ * = FILENAME
+ * ix_os_type.h (Replaced by OSAL)
+ *
+ * = DESCRIPTION
+ * This file provides protable symbol definitions for the current OS type.
+ *
+ * = AUTHOR
+ * Intel Corporation
+ *
+ * = CHANGE HISTORY
+ * 4/22/2002 4:43:30 PM - creation time
+ * ============================================================================
+ */
+
+#if !defined(__IX_OS_TYPE_H__)
+#define __IX_OS_TYPE_H__
+
+#include "IxOsalBackward.h"
+
+#endif /* end !defined(__IX_OS_TYPE_H__) */
+
diff --git a/cpu/ixp/npe/include/ix_ossl.h b/cpu/ixp/npe/include/ix_ossl.h
new file mode 100644
index 0000000..b59f7d0
--- /dev/null
+++ b/cpu/ixp/npe/include/ix_ossl.h
@@ -0,0 +1,160 @@
+/**
+ * ============================================================================
+ * = COPYRIGHT
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ * = PRODUCT
+ * Intel(r) IXP425 Software Release
+ *
+ * = LIBRARY
+ * OSSL - Operating System Services Library
+ *
+ * = MODULE
+ * OSSL Abstraction layer header file
+ *
+ * = FILENAME
+ * ix_ossl.h (Replaced by OSAL)
+ *
+ * = DESCRIPTION
+ * This file contains the prototypes of OS-independent wrapper
+ * functions which allow the programmer not to be tied to a specific
+ * operating system. The OSSL functions can be divided into three classes:
+ *
+ * 1) synchronization-related wrapper functions around thread system calls
+ * 2) thread-related wrapper functions around thread calls
+ * 3) transactor/workbench osapi calls -- defined in osApi.h
+ *
+ * Both 1 and 2 classes of functions provide Thread Management, Thread
+ * Synchronization, Mutual Exclusion and Timer primitives. Namely,
+ * creation and deletion functions as well as the standard "wait" and
+ * "exit". Additionally, a couple of utility functions which enable to
+ * pause the execution of a thread are also provided.
+ *
+ * The 3rd class provides a slew of other OSAPI functions to handle
+ * Transactor/WorkBench OS calls.
+ *
+ *
+ * OSSL Thread APIs:
+ * The OSSL thread functions that allow for thread creation,
+ * get thread id, thread deletion and set thread priroity.
+ *
+ * ix_ossl_thread_create
+ * ix_ossl_thread_get_id
+ * ix_ossl_thread_exit
+ * ix_ossl_thread_kill
+ * ix_ossl_thread_set_priority
+ * ix_ossl_thread__delay
+ *
+ * OSSL Semaphore APIs:
+ * The OSSL semaphore functions that allow for initialization,
+ * posting, waiting and deletion of semaphores.
+ *
+ * ix_ossl_sem_init
+ * ix_ossl_sem_fini
+ * ix_ossl_sem_take
+ * ix_ossl_sem_give
+ * ix_ossl_sem_flush
+ *
+ * OSSL Mutex APIs:
+ * The OSSL wrapper functions that allow for initialization,
+ * posting, waiting and deletion of mutexes.
+ *
+ * ix_ossl_mutex_init
+ * ix_ossl_mutex_fini
+ * ix_ossl_mutex_lock
+ * ix_ossl_mutex_unlock
+ *
+ * OSSL Timer APIs:
+ * The timer APIs provide sleep and get time functions.
+ *
+ * ix_ossl_sleep
+ * ix_ossl_sleep_tick
+ * ix_ossl_time_get
+ *
+ * OSAPIs for Transactor/WorkBench:
+ * These OSAPI functions are used for transator OS calls.
+ * They are defined in osApi.h.
+ *
+ * Sem_Init
+ * Sem_Destroy
+ * Sem_Wait
+ * Sem_Wait
+ * Thread_Create
+ * Thread_Cancel
+ * Thread_SetPriority
+ * delayMs
+ * delayTick
+ *
+ *
+ *
+ **********************************************************************
+ *
+ *
+ * = AUTHOR
+ * Intel Corporation
+ *
+ * = ACKNOWLEDGEMENTS
+ *
+ *
+ * = CREATION TIME
+ * 1/8/2002 1:53:42 PM
+ *
+ * = CHANGE HISTORY
+ * 02/22/2002 : Renamed osapi.h os_api.h
+ * Moved OS header file includes from OSSL.h to os_api.h
+ * Moved OS specific datatypes to os_api.h
+ * Modified data types, macros and functions as per
+ * 'C' coding guidelines.
+ *
+ *
+ * ============================================================================
+ */
+
+#ifndef _IX_OSSL_H
+#ifndef __doxygen_hide
+#define _IX_OSSL_H
+#endif /* __doxygen_hide */
+
+#include "IxOsalBackward.h"
+
+#endif /* _IX_OSSL_H */
+
+/**
+ * @} defgroup IxOSSL
+ */
diff --git a/cpu/ixp/npe/include/ix_symbols.h b/cpu/ixp/npe/include/ix_symbols.h
new file mode 100644
index 0000000..f7bb029
--- /dev/null
+++ b/cpu/ixp/npe/include/ix_symbols.h
@@ -0,0 +1,106 @@
+/**
+ * ============================================================================
+ * = COPYRIGHT
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ * = PRODUCT
+ * Intel(r) IXP425 Software Release
+ *
+ * = FILENAME
+ * ix_symbols.h
+ *
+ * = DESCRIPTION
+ * This file declares all the global preprocessor symbols required by
+ * the IXA SDK Framework API.
+ *
+ * = AUTHOR
+ * Intel Corporation
+ *
+ * = CHANGE HISTORY
+ * 4/23/2002 10:41:13 AM - creation time
+ * ============================================================================
+ */
+
+#if !defined(__IX_SYMBOLS_H__)
+#define __IX_SYMBOLS_H__
+
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif /* end defined(__cplusplus) */
+
+/**
+ * The IX_EXPORT_FUNCTION symbol will be used for compilation on different platforms.
+ * We are planning to provide a simulation version of the library that should work
+ * with the Transactor rather than the hardware. This implementation will be done on
+ * WIN32 in the form of a DLL that will need to export functions and symbols.
+ */
+#if (_IX_OS_TYPE_ == _IX_OS_WIN32_)
+# if defined(_IX_LIB_INTERFACE_IMPLEMENTATION_)
+# define IX_EXPORT_FUNCTION __declspec( dllexport )
+# elif defined(_IX_LIB_INTERFACE_IMPORT_DLL_)
+# define IX_EXPORT_FUNCTION __declspec( dllimport )
+# else
+# define IX_EXPORT_FUNCTION extern
+# endif
+#elif (_IX_OS_TYPE_ == _IX_OS_WINCE_)
+# define IX_EXPORT_FUNCTION __declspec(dllexport)
+#else
+# define IX_EXPORT_FUNCTION extern
+#endif
+
+
+/**
+ * This symbols should be defined when we want to build for a multithreaded environment
+ */
+#define _IX_MULTI_THREADED_ 1
+
+
+/**
+ * This symbol should be defined in the case we to buils for a multithreaded environment
+ * but we want that our modules to work as if they are used in a single threaded environment.
+ */
+/* #define _IX_RM_EXPLICIT_SINGLE_THREADED_ 1 */
+
+#if defined(__cplusplus)
+}
+#endif /* end defined(__cplusplus) */
+
+#endif /* end !defined(__IX_SYMBOLS_H__) */
diff --git a/cpu/ixp/npe/include/ix_types.h b/cpu/ixp/npe/include/ix_types.h
new file mode 100644
index 0000000..fc7b1e9
--- /dev/null
+++ b/cpu/ixp/npe/include/ix_types.h
@@ -0,0 +1,208 @@
+/**
+ * ============================================================================
+ * = COPYRIGHT
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ * = PRODUCT
+ * Intel(r) IXP425 Software Release
+ *
+ * = FILENAME
+ * ix_types.h
+ *
+ * = DESCRIPTION
+ * This file will define generic types that will guarantee the protability
+ * between different architectures and compilers. It should be used the entire
+ * IXA SDK Framework API.
+ *
+ * = AUTHOR
+ * Intel Corporation
+ *
+ * = CHANGE HISTORY
+ * 4/22/2002 4:44:17 PM - creation time
+ * ============================================================================
+ */
+
+#if !defined(__IX_TYPES_H__)
+#define __IX_TYPES_H__
+
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif /* end defined(__cplusplus) */
+
+
+/**
+ * Define generic integral data types that will guarantee the size.
+ */
+
+/**
+ * TYPENAME: ix_int8
+ *
+ * DESCRIPTION: This type defines an 8 bit signed integer value.
+ *
+ */
+typedef signed char ix_int8;
+
+
+/**
+ * TYPENAME: ix_uint8
+ *
+ * DESCRIPTION: This type defines an 8 bit unsigned integer value.
+ *
+ */
+typedef unsigned char ix_uint8;
+
+
+/**
+ * TYPENAME: ix_int16
+ *
+ * DESCRIPTION: This type defines an 16 bit signed integer value.
+ *
+ */
+typedef signed short int ix_int16;
+
+
+/**
+ * TYPENAME: ix_uint16
+ *
+ * DESCRIPTION: This type defines an 16 bit unsigned integer value.
+ *
+ */
+typedef unsigned short int ix_uint16;
+
+
+/**
+ * TYPENAME: ix_int32
+ *
+ * DESCRIPTION: This type defines an 32 bit signed integer value.
+ *
+ */
+typedef signed int ix_int32;
+
+
+/**
+ * TYPENAME: ix_uint32
+ *
+ * DESCRIPTION: This type defines an 32 bit unsigned integer value.
+ *
+ */
+#ifndef __wince
+typedef unsigned int ix_uint32;
+#else
+typedef unsigned long ix_uint32;
+#endif
+
+/**
+ * TYPENAME: ix_int64
+ *
+ * DESCRIPTION: This type defines an 64 bit signed integer value.
+ *
+ */
+#ifndef __wince
+__extension__ typedef signed long long int ix_int64;
+#endif
+
+/**
+ * TYPENAME: ix_uint64
+ *
+ * DESCRIPTION: This type defines an 64 bit unsigned integer value.
+ *
+ */
+#ifndef __wince
+__extension__ typedef unsigned long long int ix_uint64;
+#endif
+
+
+/**
+ * TYPENAME: ix_bit_mask8
+ *
+ * DESCRIPTION: This is a generic type for a 8 bit mask.
+ */
+typedef ix_uint8 ix_bit_mask8;
+
+
+/**
+ * TYPENAME: ix_bit_mask16
+ *
+ * DESCRIPTION: This is a generic type for a 16 bit mask.
+ */
+typedef ix_uint16 ix_bit_mask16;
+
+
+/**
+ * TYPENAME: ix_bit_mask32
+ *
+ * DESCRIPTION: This is a generic type for a 32 bit mask.
+ */
+typedef ix_uint32 ix_bit_mask32;
+
+
+/**
+ * TYPENAME: ix_bit_mask64
+ *
+ * DESCRIPTION: This is a generic type for a 64 bit mask.
+ */
+#ifndef __wince
+typedef ix_uint64 ix_bit_mask64;
+#endif
+
+
+/**
+ * TYPENAME: ix_handle
+ *
+ * DESCRIPTION: This type defines a generic handle.
+ *
+ */
+typedef ix_uint32 ix_handle;
+
+
+
+/**
+ * DESCRIPTION: This symbol defines a NULL handle
+ *
+ */
+#define IX_NULL_HANDLE ((ix_handle)0)
+
+
+#if defined(__cplusplus)
+}
+#endif /* end defined(__cplusplus) */
+
+#endif /* end !defined(__IX_TYPES_H__) */
diff --git a/cpu/ixp/npe/include/npe.h b/cpu/ixp/npe/include/npe.h
new file mode 100644
index 0000000..e53458d
--- /dev/null
+++ b/cpu/ixp/npe/include/npe.h
@@ -0,0 +1,90 @@
+/*
+ * (C) Copyright 2005
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef NPE_H
+#define NPE_H
+
+/*
+ * defines...
+ */
+#define CFG_NPE_NUMS 1
+#ifdef CONFIG_HAS_ETH1
+#undef CFG_NPE_NUMS
+#define CFG_NPE_NUMS 2
+#endif
+
+#define NPE_NUM_PORTS 3
+#define ACTIVE_PORTS 1
+
+#define NPE_PKT_SIZE 1600
+
+#define CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS 64
+#define CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS 2
+
+#define NPE_MBUF_POOL_SIZE \
+ ((CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS + \
+ CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS) * \
+ sizeof(IX_OSAL_MBUF) * ACTIVE_PORTS)
+
+#define NPE_PKT_POOL_SIZE \
+ ((CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS + \
+ CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS) * \
+ NPE_PKT_SIZE * ACTIVE_PORTS)
+
+#define NPE_MEM_POOL_SIZE (NPE_MBUF_POOL_SIZE + NPE_PKT_POOL_SIZE)
+
+#define PHY_AUTONEGOTIATE_TIMEOUT 4000 /* 4000 ms autonegotiate timeout */
+
+/*
+ * structs...
+ */
+struct npe {
+ u8 active; /* NPE active */
+ u8 eth_id; /* IX_ETH_PORT_1 or IX_ETH_PORT_2 */
+ u8 phy_no; /* which PHY (0 - 31) */
+ u8 mac_address[6];
+
+ IX_OSAL_MBUF *rxQHead;
+ IX_OSAL_MBUF *txQHead;
+
+ u8 *tx_pkts;
+ u8 *rx_pkts;
+ IX_OSAL_MBUF *rx_mbufs;
+ IX_OSAL_MBUF *tx_mbufs;
+
+ int print_speed;
+
+ int rx_read;
+ int rx_write;
+ int rx_len[PKTBUFSRX];
+};
+
+/*
+ * prototypes...
+ */
+extern int npe_miiphy_read (char *devname, unsigned char addr,
+ unsigned char reg, unsigned short *value);
+extern int npe_miiphy_write (char *devname, unsigned char addr,
+ unsigned char reg, unsigned short value);
+
+#endif /* ifndef NPE_H */
diff --git a/cpu/ixp/npe/include/os_datatypes.h b/cpu/ixp/npe/include/os_datatypes.h
new file mode 100644
index 0000000..4387b2a
--- /dev/null
+++ b/cpu/ixp/npe/include/os_datatypes.h
@@ -0,0 +1,82 @@
+/**
+ * ============================================================================
+ * = COPYRIGHT
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ *
+ * @par
+ * -- End of Copyright Notice --
+ * = PRODUCT
+ * Intel(r) IXP425 Software Release
+ *
+ * = LIBRARY
+ * OSSL - Operating System Services Library
+ *
+ * = MODULE
+ * OS Specific Data Types header file
+ *
+ * = FILENAME
+ * OSSL.h (Replaced by OSAL)
+ *
+ * = DESCRIPTION
+ * This file contains definitions and encapsulations for OS specific data types. These
+ * encapsulated data types are used by OSSL header files and OS API functions.
+ *
+ *
+ **********************************************************************
+ *
+ *
+ * = AUTHOR
+ * Intel Corporation
+ *
+ * = AKNOWLEDGEMENTS
+ *
+ *
+ * = CREATION TIME
+ * 1/8/2002 1:53:42 PM
+ *
+ * = CHANGE HISTORY
+
+ * ============================================================================
+ */
+
+#ifndef _OS_DATATYPES_H
+#define _OS_DATATYPES_H
+
+#include "IxOsalBackward.h"
+
+#endif /* _OS_DATATYPES_H */
+
diff --git a/cpu/ixp/npe/miiphy.c b/cpu/ixp/npe/miiphy.c
new file mode 100644
index 0000000..c63c54e
--- /dev/null
+++ b/cpu/ixp/npe/miiphy.c
@@ -0,0 +1,118 @@
+/*-----------------------------------------------------------------------------+
+ |
+ | This source code has been made available to you by IBM on an AS-IS
+ | basis. Anyone receiving this source is licensed under IBM
+ | copyrights to use it in any way he or she deems fit, including
+ | copying it, modifying it, compiling it, and redistributing it either
+ | with or without modifications. No license under IBM patents or
+ | patent applications is to be implied by the copyright license.
+ |
+ | Any user of this software should understand that IBM cannot provide
+ | technical support for this software and will not be responsible for
+ | any consequences resulting from the use of this software.
+ |
+ | Any person who transfers this source code or any derivative work
+ | must include the IBM copyright notice, this paragraph, and the
+ | preceding two paragraphs in the transferred software.
+ |
+ | COPYRIGHT I B M CORPORATION 1995
+ | LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
+ +-----------------------------------------------------------------------------*/
+/*-----------------------------------------------------------------------------+
+ |
+ | File Name: miiphy.c
+ |
+ | Function: This module has utilities for accessing the MII PHY through
+ | the EMAC3 macro.
+ |
+ | Author: Mark Wisner
+ |
+ | Change Activity-
+ |
+ | Date Description of Change BY
+ | --------- --------------------- ---
+ | 05-May-99 Created MKW
+ | 01-Jul-99 Changed clock setting of sta_reg from 66Mhz to 50Mhz to
+ | better match OPB speed. Also modified delay times. JWB
+ | 29-Jul-99 Added Full duplex support MKW
+ | 24-Aug-99 Removed printf from dp83843_duplex() JWB
+ | 19-Jul-00 Ported to esd cpci405 sr
+ | 23-Dec-03 Ported from miiphy.c to 440GX Travis Sawyer TBS
+ | <travis.sawyer@sandburst.com>
+ |
+ +-----------------------------------------------------------------------------*/
+
+#include <common.h>
+#include <miiphy.h>
+#include "IxOsal.h"
+#include "IxEthAcc.h"
+#include "IxEthAcc_p.h"
+#include "IxEthAccMac_p.h"
+#include "IxEthAccMii_p.h"
+
+/***********************************************************/
+/* Dump out to the screen PHY regs */
+/***********************************************************/
+
+void miiphy_dump (char *devname, unsigned char addr)
+{
+ unsigned long i;
+ unsigned short data;
+
+
+ for (i = 0; i < 0x1A; i++) {
+ if (miiphy_read (devname, addr, i, &data)) {
+ printf ("read error for reg %lx\n", i);
+ return;
+ }
+ printf ("Phy reg %lx ==> %4x\n", i, data);
+
+ /* jump to the next set of regs */
+ if (i == 0x07)
+ i = 0x0f;
+
+ } /* end for loop */
+} /* end dump */
+
+
+/***********************************************************/
+/* (Re)start autonegotiation */
+/***********************************************************/
+int phy_setup_aneg (char *devname, unsigned char addr)
+{
+ unsigned short ctl, adv;
+
+ /* Setup standard advertise */
+ miiphy_read (devname, addr, PHY_ANAR, &adv);
+ adv |= (PHY_ANLPAR_ACK | PHY_ANLPAR_RF | PHY_ANLPAR_T4 |
+ PHY_ANLPAR_TXFD | PHY_ANLPAR_TX | PHY_ANLPAR_10FD |
+ PHY_ANLPAR_10);
+ miiphy_write (devname, addr, PHY_ANAR, adv);
+
+ /* Start/Restart aneg */
+ miiphy_read (devname, addr, PHY_BMCR, &ctl);
+ ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
+ miiphy_write (devname, addr, PHY_BMCR, ctl);
+
+ return 0;
+}
+
+
+int npe_miiphy_read (char *devname, unsigned char addr,
+ unsigned char reg, unsigned short *value)
+{
+ u16 val;
+
+ ixEthAccMiiReadRtn(addr, reg, &val);
+ *value = val;
+
+ return 0;
+} /* phy_read */
+
+
+int npe_miiphy_write (char *devname, unsigned char addr,
+ unsigned char reg, unsigned short value)
+{
+ ixEthAccMiiWriteRtn(addr, reg, value);
+ return 0;
+} /* phy_write */
diff --git a/cpu/ixp/npe/npe.c b/cpu/ixp/npe/npe.c
new file mode 100644
index 0000000..ab7ca8b
--- /dev/null
+++ b/cpu/ixp/npe/npe.c
@@ -0,0 +1,694 @@
+/*
+ * (C) Copyright 2005-2006
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#if 0
+#define DEBUG /* define for debug output */
+#endif
+
+#include <config.h>
+#include <common.h>
+#include <net.h>
+#include <miiphy.h>
+#include <malloc.h>
+#include <asm/processor.h>
+#include <asm/arch-ixp/ixp425.h>
+
+#include <IxOsal.h>
+#include <IxEthAcc.h>
+#include <IxEthDB.h>
+#include <IxNpeDl.h>
+#include <IxQMgr.h>
+#include <IxNpeMh.h>
+#include <ix_ossl.h>
+#include <IxFeatureCtrl.h>
+
+#include <npe.h>
+
+#ifdef CONFIG_IXP4XX_NPE
+
+static IxQMgrDispatcherFuncPtr qDispatcherFunc = NULL;
+static int npe_exists[NPE_NUM_PORTS];
+static int npe_used[NPE_NUM_PORTS];
+
+/* A little extra so we can align to cacheline. */
+static u8 npe_alloc_pool[NPE_MEM_POOL_SIZE + CFG_CACHELINE_SIZE - 1];
+static u8 *npe_alloc_end;
+static u8 *npe_alloc_free;
+
+static void *npe_alloc(int size)
+{
+ static int count = 0;
+ void *p = NULL;
+
+ size = (size + (CFG_CACHELINE_SIZE-1)) & ~(CFG_CACHELINE_SIZE-1);
+ count++;
+
+ if ((npe_alloc_free + size) < npe_alloc_end) {
+ p = npe_alloc_free;
+ npe_alloc_free += size;
+ } else {
+ printf("%s: failed (count=%d, size=%d)!\n", count, size);
+ }
+ return p;
+}
+
+/* Not interrupt safe! */
+static void mbuf_enqueue(IX_OSAL_MBUF **q, IX_OSAL_MBUF *new)
+{
+ IX_OSAL_MBUF *m = *q;
+
+ IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(new) = NULL;
+
+ if (m) {
+ while(IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m))
+ m = IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m);
+ IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m) = new;
+ } else
+ *q = new;
+}
+
+/* Not interrupt safe! */
+static IX_OSAL_MBUF *mbuf_dequeue(IX_OSAL_MBUF **q)
+{
+ IX_OSAL_MBUF *m = *q;
+ if (m)
+ *q = IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m);
+ return m;
+}
+
+static void reset_tx_mbufs(struct npe* p_npe)
+{
+ IX_OSAL_MBUF *m;
+ int i;
+
+ p_npe->txQHead = NULL;
+
+ for (i = 0; i < CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS; i++) {
+ m = &p_npe->tx_mbufs[i];
+
+ memset(m, 0, sizeof(*m));
+
+ IX_OSAL_MBUF_MDATA(m) = (void *)&p_npe->tx_pkts[i * NPE_PKT_SIZE];
+ IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE;
+ mbuf_enqueue(&p_npe->txQHead, m);
+ }
+}
+
+static void reset_rx_mbufs(struct npe* p_npe)
+{
+ IX_OSAL_MBUF *m;
+ int i;
+
+ p_npe->rxQHead = NULL;
+
+ HAL_DCACHE_INVALIDATE(p_npe->rx_pkts, NPE_PKT_SIZE *
+ CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS);
+
+ for (i = 0; i < CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS; i++) {
+ m = &p_npe->rx_mbufs[i];
+
+ memset(m, 0, sizeof(*m));
+
+ IX_OSAL_MBUF_MDATA(m) = (void *)&p_npe->rx_pkts[i * NPE_PKT_SIZE];
+ IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE;
+
+ if(ixEthAccPortRxFreeReplenish(p_npe->eth_id, m) != IX_SUCCESS) {
+ printf("ixEthAccPortRxFreeReplenish failed for port %d\n", p_npe->eth_id);
+ break;
+ }
+ }
+}
+
+static void init_rx_mbufs(struct npe* p_npe)
+{
+ p_npe->rxQHead = NULL;
+
+ p_npe->rx_pkts = npe_alloc(NPE_PKT_SIZE *
+ CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS);
+ if (p_npe->rx_pkts == NULL) {
+ printf("alloc of packets failed.\n");
+ return;
+ }
+
+ p_npe->rx_mbufs = (IX_OSAL_MBUF *)
+ npe_alloc(sizeof(IX_OSAL_MBUF) *
+ CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS);
+ if (p_npe->rx_mbufs == NULL) {
+ printf("alloc of mbufs failed.\n");
+ return;
+ }
+
+ reset_rx_mbufs(p_npe);
+}
+
+static void init_tx_mbufs(struct npe* p_npe)
+{
+ p_npe->tx_pkts = npe_alloc(NPE_PKT_SIZE *
+ CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS);
+ if (p_npe->tx_pkts == NULL) {
+ printf("alloc of packets failed.\n");
+ return;
+ }
+
+ p_npe->tx_mbufs = (IX_OSAL_MBUF *)
+ npe_alloc(sizeof(IX_OSAL_MBUF) *
+ CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS);
+ if (p_npe->tx_mbufs == NULL) {
+ printf("alloc of mbufs failed.\n");
+ return;
+ }
+
+ reset_tx_mbufs(p_npe);
+}
+
+/* Convert IX_ETH_PORT_n to IX_NPEMH_NPEID_NPEx */
+static int __eth_to_npe(int eth_id)
+{
+ switch(eth_id) {
+ case IX_ETH_PORT_1:
+ return IX_NPEMH_NPEID_NPEB;
+
+ case IX_ETH_PORT_2:
+ return IX_NPEMH_NPEID_NPEC;
+
+ case IX_ETH_PORT_3:
+ return IX_NPEMH_NPEID_NPEA;
+ }
+ return 0;
+}
+
+/* Poll the CSR machinery. */
+static void npe_poll(int eth_id)
+{
+ if (qDispatcherFunc != NULL) {
+ ixNpeMhMessagesReceive(__eth_to_npe(eth_id));
+ (*qDispatcherFunc)(IX_QMGR_QUELOW_GROUP);
+ }
+}
+
+/* ethAcc RX callback */
+static void npe_rx_callback(u32 cbTag, IX_OSAL_MBUF *m, IxEthAccPortId portid)
+{
+ struct npe* p_npe = (struct npe *)cbTag;
+
+ if (IX_OSAL_MBUF_MLEN(m) > 0) {
+ mbuf_enqueue(&p_npe->rxQHead, m);
+
+ if (p_npe->rx_write == ((p_npe->rx_read-1) & (PKTBUFSRX-1))) {
+ debug("Rx overflow: rx_write=%d rx_read=%d\n",
+ p_npe->rx_write, p_npe->rx_read);
+ } else {
+ debug("Received message #%d (len=%d)\n", p_npe->rx_write,
+ IX_OSAL_MBUF_MLEN(m));
+ memcpy((void *)NetRxPackets[p_npe->rx_write], IX_OSAL_MBUF_MDATA(m),
+ IX_OSAL_MBUF_MLEN(m));
+ p_npe->rx_len[p_npe->rx_write] = IX_OSAL_MBUF_MLEN(m);
+ p_npe->rx_write++;
+ if (p_npe->rx_write == PKTBUFSRX)
+ p_npe->rx_write = 0;
+
+#ifdef CONFIG_PRINT_RX_FRAMES
+ {
+ u8 *ptr = IX_OSAL_MBUF_MDATA(m);
+ int i;
+
+ for (i=0; i<60; i++) {
+ debug("%02x ", *ptr++);
+ }
+ debug("\n");
+ }
+#endif
+ }
+
+ m = mbuf_dequeue(&p_npe->rxQHead);
+ } else {
+ debug("Received frame with length 0!!!\n");
+ m = mbuf_dequeue(&p_npe->rxQHead);
+ }
+
+ /* Now return mbuf to NPE */
+ IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE;
+ IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m) = NULL;
+ IX_OSAL_MBUF_FLAGS(m) = 0;
+
+ if(ixEthAccPortRxFreeReplenish(p_npe->eth_id, m) != IX_SUCCESS) {
+ debug("npe_rx_callback: Error returning mbuf.\n");
+ }
+}
+
+/* ethAcc TX callback */
+static void npe_tx_callback(u32 cbTag, IX_OSAL_MBUF *m)
+{
+ struct npe* p_npe = (struct npe *)cbTag;
+
+ debug("%s\n", __FUNCTION__);
+
+ IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE;
+ IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m) = NULL;
+ IX_OSAL_MBUF_FLAGS(m) = 0;
+
+ mbuf_enqueue(&p_npe->txQHead, m);
+}
+
+
+static int npe_set_mac_address(struct eth_device *dev)
+{
+ struct npe *p_npe = (struct npe *)dev->priv;
+ IxEthAccMacAddr npeMac;
+
+ debug("%s\n", __FUNCTION__);
+
+ /* Set MAC address */
+ memcpy(npeMac.macAddress, dev->enetaddr, 6);
+
+ if (ixEthAccPortUnicastMacAddressSet(p_npe->eth_id, &npeMac) != IX_ETH_ACC_SUCCESS) {
+ printf("Error setting unicast address! %02x:%02x:%02x:%02x:%02x:%02x\n",
+ npeMac.macAddress[0], npeMac.macAddress[1],
+ npeMac.macAddress[2], npeMac.macAddress[3],
+ npeMac.macAddress[4], npeMac.macAddress[5]);
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Boot-time CSR library initialization. */
+static int npe_csr_load(void)
+{
+ int i;
+
+ if (ixQMgrInit() != IX_SUCCESS) {
+ debug("Error initialising queue manager!\n");
+ return 0;
+ }
+
+ ixQMgrDispatcherLoopGet(&qDispatcherFunc);
+
+ if(ixNpeMhInitialize(IX_NPEMH_NPEINTERRUPTS_YES) != IX_SUCCESS) {
+ printf("Error initialising NPE Message handler!\n");
+ return 0;
+ }
+
+ if (npe_used[IX_ETH_PORT_1] && npe_exists[IX_ETH_PORT_1] &&
+ ixNpeDlNpeInitAndStart(IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS)
+ != IX_SUCCESS) {
+ printf("Error downloading firmware to NPE-B!\n");
+ return 0;
+ }
+
+ if (npe_used[IX_ETH_PORT_2] && npe_exists[IX_ETH_PORT_2] &&
+ ixNpeDlNpeInitAndStart(IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS)
+ != IX_SUCCESS) {
+ printf("Error downloading firmware to NPE-C!\n");
+ return 0;
+ }
+
+ /* don't need this for U-Boot */
+ ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, FALSE);
+
+ if (ixEthAccInit() != IX_ETH_ACC_SUCCESS) {
+ printf("Error initialising Ethernet access driver!\n");
+ return 0;
+ }
+
+ for (i = 0; i < IX_ETH_ACC_NUMBER_OF_PORTS; i++) {
+ if (!npe_used[i] || !npe_exists[i])
+ continue;
+ if (ixEthAccPortInit(i) != IX_ETH_ACC_SUCCESS) {
+ printf("Error initialising Ethernet port%d!\n", i);
+ }
+ if (ixEthAccTxSchedulingDisciplineSet(i, FIFO_NO_PRIORITY) != IX_ETH_ACC_SUCCESS) {
+ printf("Error setting scheduling discipline for port %d.\n", i);
+ }
+ if (ixEthAccPortRxFrameAppendFCSDisable(i) != IX_ETH_ACC_SUCCESS) {
+ printf("Error disabling RX FCS for port %d.\n", i);
+ }
+ if (ixEthAccPortTxFrameAppendFCSEnable(i) != IX_ETH_ACC_SUCCESS) {
+ printf("Error enabling TX FCS for port %d.\n", i);
+ }
+ }
+
+ return 1;
+}
+
+static int npe_init(struct eth_device *dev, bd_t * bis)
+{
+ struct npe *p_npe = (struct npe *)dev->priv;
+ int i;
+ u16 reg_short;
+ int speed;
+ int duplex;
+
+ debug("%s: 1\n", __FUNCTION__);
+
+ miiphy_read (dev->name, p_npe->phy_no, PHY_BMSR, &reg_short);
+
+ /*
+ * Wait if PHY is capable of autonegotiation and autonegotiation is not complete
+ */
+ if ((reg_short & PHY_BMSR_AUTN_ABLE) && !(reg_short & PHY_BMSR_AUTN_COMP)) {
+ puts ("Waiting for PHY auto negotiation to complete");
+ i = 0;
+ while (!(reg_short & PHY_BMSR_AUTN_COMP)) {
+ /*
+ * Timeout reached ?
+ */
+ if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
+ puts (" TIMEOUT !\n");
+ break;
+ }
+
+ if ((i++ % 1000) == 0) {
+ putc ('.');
+ miiphy_read (dev->name, p_npe->phy_no, PHY_BMSR, &reg_short);
+ }
+ udelay (1000); /* 1 ms */
+ }
+ puts (" done\n");
+ udelay (500000); /* another 500 ms (results in faster booting) */
+ }
+
+ speed = miiphy_speed (dev->name, p_npe->phy_no);
+ duplex = miiphy_duplex (dev->name, p_npe->phy_no);
+
+ if (p_npe->print_speed) {
+ p_npe->print_speed = 0;
+ printf ("ENET Speed is %d Mbps - %s duplex connection\n",
+ (int) speed, (duplex == HALF) ? "HALF" : "FULL");
+ }
+
+ npe_alloc_end = npe_alloc_pool + sizeof(npe_alloc_pool);
+ npe_alloc_free = (u8 *)(((unsigned)npe_alloc_pool +
+ CFG_CACHELINE_SIZE - 1) & ~(CFG_CACHELINE_SIZE - 1));
+
+ /* initialize mbuf pool */
+ init_rx_mbufs(p_npe);
+ init_tx_mbufs(p_npe);
+
+ if (ixEthAccPortRxCallbackRegister(p_npe->eth_id, npe_rx_callback,
+ (u32)p_npe) != IX_ETH_ACC_SUCCESS) {
+ printf("can't register RX callback!\n");
+ return 0;
+ }
+
+ if (ixEthAccPortTxDoneCallbackRegister(p_npe->eth_id, npe_tx_callback,
+ (u32)p_npe) != IX_ETH_ACC_SUCCESS) {
+ printf("can't register TX callback!\n");
+ return 0;
+ }
+
+ npe_set_mac_address(dev);
+
+ if (ixEthAccPortEnable(p_npe->eth_id) != IX_ETH_ACC_SUCCESS) {
+ printf("can't enable port!\n");
+ return 0;
+ }
+
+ p_npe->active = 1;
+
+ return 1;
+}
+
+#if 0 /* test-only: probably have to deal with it when booting linux (for a clean state) */
+/* Uninitialize CSR library. */
+static void npe_csr_unload(void)
+{
+ ixEthAccUnload();
+ ixEthDBUnload();
+ ixNpeMhUnload();
+ ixQMgrUnload();
+}
+
+/* callback which is used by ethAcc to recover RX buffers when stopping */
+static void npe_rx_stop_callback(u32 cbTag, IX_OSAL_MBUF *m, IxEthAccPortId portid)
+{
+ debug("%s\n", __FUNCTION__);
+}
+
+/* callback which is used by ethAcc to recover TX buffers when stopping */
+static void npe_tx_stop_callback(u32 cbTag, IX_OSAL_MBUF *m)
+{
+ debug("%s\n", __FUNCTION__);
+}
+#endif
+
+static void npe_halt(struct eth_device *dev)
+{
+ struct npe *p_npe = (struct npe *)dev->priv;
+ int i;
+
+ debug("%s\n", __FUNCTION__);
+
+ /* Delay to give time for recovery of mbufs */
+ for (i = 0; i < 100; i++) {
+ npe_poll(p_npe->eth_id);
+ udelay(100);
+ }
+
+#if 0 /* test-only: probably have to deal with it when booting linux (for a clean state) */
+ if (ixEthAccPortRxCallbackRegister(p_npe->eth_id, npe_rx_stop_callback,
+ (u32)p_npe) != IX_ETH_ACC_SUCCESS) {
+ debug("Error registering rx callback!\n");
+ }
+
+ if (ixEthAccPortTxDoneCallbackRegister(p_npe->eth_id, npe_tx_stop_callback,
+ (u32)p_npe) != IX_ETH_ACC_SUCCESS) {
+ debug("Error registering tx callback!\n");
+ }
+
+ if (ixEthAccPortDisable(p_npe->eth_id) != IX_ETH_ACC_SUCCESS) {
+ debug("npe_stop: Error disabling NPEB!\n");
+ }
+
+ /* Delay to give time for recovery of mbufs */
+ for (i = 0; i < 100; i++) {
+ npe_poll(p_npe->eth_id);
+ udelay(10000);
+ }
+
+ /*
+ * For U-Boot only, we are probably launching Linux or other OS that
+ * needs a clean slate for its NPE library.
+ */
+#if 0 /* test-only */
+ for (i = 0; i < IX_ETH_ACC_NUMBER_OF_PORTS; i++) {
+ if (npe_used[i] && npe_exists[i])
+ if (ixNpeDlNpeStopAndReset(__eth_to_npe(i)) != IX_SUCCESS)
+ printf("Failed to stop and reset NPE B.\n");
+ }
+#endif
+
+#endif
+ p_npe->active = 0;
+}
+
+
+static int npe_send(struct eth_device *dev, volatile void *packet, int len)
+{
+ struct npe *p_npe = (struct npe *)dev->priv;
+ u8 *dest;
+ int err;
+ IX_OSAL_MBUF *m;
+
+ debug("%s\n", __FUNCTION__);
+ m = mbuf_dequeue(&p_npe->txQHead);
+ dest = IX_OSAL_MBUF_MDATA(m);
+ IX_OSAL_MBUF_PKT_LEN(m) = IX_OSAL_MBUF_MLEN(m) = len;
+ IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m) = NULL;
+
+ memcpy(dest, (char *)packet, len);
+
+ if ((err = ixEthAccPortTxFrameSubmit(p_npe->eth_id, m, IX_ETH_ACC_TX_DEFAULT_PRIORITY))
+ != IX_ETH_ACC_SUCCESS) {
+ printf("npe_send: Can't submit frame. err[%d]\n", err);
+ mbuf_enqueue(&p_npe->txQHead, m);
+ return 0;
+ }
+
+#ifdef DEBUG_PRINT_TX_FRAMES
+ {
+ u8 *ptr = IX_OSAL_MBUF_MDATA(m);
+ int i;
+
+ for (i=0; i<IX_OSAL_MBUF_MLEN(m); i++) {
+ printf("%02x ", *ptr++);
+ }
+ printf(" (tx-len=%d)\n", IX_OSAL_MBUF_MLEN(m));
+ }
+#endif
+
+ npe_poll(p_npe->eth_id);
+
+ return len;
+}
+
+static int npe_rx(struct eth_device *dev)
+{
+ struct npe *p_npe = (struct npe *)dev->priv;
+
+ debug("%s\n", __FUNCTION__);
+ npe_poll(p_npe->eth_id);
+
+ debug("%s: rx_write=%d rx_read=%d\n", __FUNCTION__, p_npe->rx_write, p_npe->rx_read);
+ while (p_npe->rx_write != p_npe->rx_read) {
+ debug("Reading message #%d\n", p_npe->rx_read);
+ NetReceive(NetRxPackets[p_npe->rx_read], p_npe->rx_len[p_npe->rx_read]);
+ p_npe->rx_read++;
+ if (p_npe->rx_read == PKTBUFSRX)
+ p_npe->rx_read = 0;
+ }
+
+ return 0;
+}
+
+int npe_initialize(bd_t * bis)
+{
+ static int virgin = 0;
+ struct eth_device *dev;
+ int eth_num = 0;
+ struct npe *p_npe = NULL;
+
+ for (eth_num = 0; eth_num < CFG_NPE_NUMS; eth_num++) {
+
+ /* See if we can actually bring up the interface, otherwise, skip it */
+ switch (eth_num) {
+ default: /* fall through */
+ case 0:
+ if (memcmp (bis->bi_enetaddr, "\0\0\0\0\0\0", 6) == 0) {
+ continue;
+ }
+ break;
+#ifdef CONFIG_HAS_ETH1
+ case 1:
+ if (memcmp (bis->bi_enet1addr, "\0\0\0\0\0\0", 6) == 0) {
+ continue;
+ }
+ break;
+#endif
+ }
+
+ /* Allocate device structure */
+ dev = (struct eth_device *)malloc(sizeof(*dev));
+ if (dev == NULL) {
+ printf ("%s: Cannot allocate eth_device %d\n", __FUNCTION__, eth_num);
+ return -1;
+ }
+ memset(dev, 0, sizeof(*dev));
+
+ /* Allocate our private use data */
+ p_npe = (struct npe *)malloc(sizeof(struct npe));
+ if (p_npe == NULL) {
+ printf("%s: Cannot allocate private hw data for eth_device %d",
+ __FUNCTION__, eth_num);
+ free(dev);
+ return -1;
+ }
+ memset(p_npe, 0, sizeof(struct npe));
+
+ switch (eth_num) {
+ default: /* fall through */
+ case 0:
+ memcpy(dev->enetaddr, bis->bi_enetaddr, 6);
+ p_npe->eth_id = 0;
+ p_npe->phy_no = CONFIG_PHY_ADDR;
+ break;
+
+#ifdef CONFIG_HAS_ETH1
+ case 1:
+ memcpy(dev->enetaddr, bis->bi_enet1addr, 6);
+ p_npe->eth_id = 1;
+ p_npe->phy_no = CONFIG_PHY1_ADDR;
+ break;
+#endif
+ }
+
+ sprintf(dev->name, "NPE%d", eth_num);
+ dev->priv = (void *)p_npe;
+ dev->init = npe_init;
+ dev->halt = npe_halt;
+ dev->send = npe_send;
+ dev->recv = npe_rx;
+
+ p_npe->print_speed = 1;
+
+ if (0 == virgin) {
+ virgin = 1;
+
+ if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X) {
+ switch (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) {
+ case IX_FEATURE_CTRL_SILICON_TYPE_B0:
+ /*
+ * If it is B0 Silicon, we only enable port when its corresponding
+ * Eth Coprocessor is available.
+ */
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
+ IX_FEATURE_CTRL_COMPONENT_ENABLED)
+ npe_exists[IX_ETH_PORT_1] = TRUE;
+
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
+ IX_FEATURE_CTRL_COMPONENT_ENABLED)
+ npe_exists[IX_ETH_PORT_2] = TRUE;
+ break;
+ case IX_FEATURE_CTRL_SILICON_TYPE_A0:
+ /*
+ * If it is A0 Silicon, we enable both as both Eth Coprocessors
+ * are available.
+ */
+ npe_exists[IX_ETH_PORT_1] = TRUE;
+ npe_exists[IX_ETH_PORT_2] = TRUE;
+ break;
+ }
+ } else if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X) {
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
+ IX_FEATURE_CTRL_COMPONENT_ENABLED)
+ npe_exists[IX_ETH_PORT_1] = TRUE;
+
+ if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
+ IX_FEATURE_CTRL_COMPONENT_ENABLED)
+ npe_exists[IX_ETH_PORT_2] = TRUE;
+ }
+
+ npe_used[IX_ETH_PORT_1] = 1;
+ npe_used[IX_ETH_PORT_2] = 1;
+
+ npe_alloc_end = npe_alloc_pool + sizeof(npe_alloc_pool);
+ npe_alloc_free = (u8 *)(((unsigned)npe_alloc_pool +
+ CFG_CACHELINE_SIZE - 1)
+ & ~(CFG_CACHELINE_SIZE - 1));
+
+ if (!npe_csr_load())
+ return 0;
+ }
+
+ eth_register(dev);
+
+#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
+ miiphy_register(dev->name, npe_miiphy_read, npe_miiphy_write);
+#endif
+
+ } /* end for each supported device */
+
+ return 1;
+}
+
+#endif /* CONFIG_IXP4XX_NPE */
diff --git a/cpu/ixp/start.S b/cpu/ixp/start.S
index 2726f65..757cfaa 100644
--- a/cpu/ixp/start.S
+++ b/cpu/ixp/start.S
@@ -211,7 +211,7 @@ reset:
/* copy */
mov r0, #0
mov r4, r0
- add r2, r0, #0x40000
+ add r2, r0, #CFG_MONITOR_LEN
mov r1, #0x10000000
mov r5, r1
@@ -497,3 +497,29 @@ reset_cpu:
reset_endless:
b reset_endless
+
+#ifdef CONFIG_USE_IRQ
+
+.LC0: .word loops_per_jiffy
+
+/*
+ * 0 <= r0 <= 2000
+ */
+.globl udelay
+udelay:
+ mov r2, #0x6800
+ orr r2, r2, #0x00db
+ mul r0, r2, r0
+ ldr r2, .LC0
+ ldr r2, [r2] @ max = 0x0fffffff
+ mov r0, r0, lsr #11 @ max = 0x00003fff
+ mov r2, r2, lsr #11 @ max = 0x0003ffff
+ mul r0, r2, r0 @ max = 2^32-1
+ movs r0, r0, lsr #6
+
+delay_loop:
+ subs r0, r0, #1
+ bne delay_loop
+ mov pc, lr
+
+#endif /* CONFIG_USE_IRQ */
diff --git a/cpu/ixp/timer.c b/cpu/ixp/timer.c
index 8df2a31..920f34e 100644
--- a/cpu/ixp/timer.c
+++ b/cpu/ixp/timer.c
@@ -1,5 +1,7 @@
-/* vi: set ts=8 sw=8 noet: */
/*
+ * (C) Copyright 2006
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
@@ -30,6 +32,7 @@
#include <common.h>
#include <asm/arch/ixp425.h>
+#ifndef CONFIG_USE_IRQ
ulong get_timer (ulong base)
{
return get_timer_masked () - base;
@@ -77,3 +80,4 @@ ulong get_timer_masked (void)
}
return (reload_constant - current);
}
+#endif /* #ifndef CONFIG_USE_IRQ */
diff --git a/cpu/lh7a40x/Makefile b/cpu/lh7a40x/Makefile
index b45bd6a..2fcafb0 100644
--- a/cpu/lh7a40x/Makefile
+++ b/cpu/lh7a40x/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000, 2001, 2002
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = cpu.o speed.o interrupts.o serial.o
+COBJS = cpu.o speed.o interrupts.o serial.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mcf52x2/Makefile b/cpu/mcf52x2/Makefile
index 879deb7..a05a803 100644
--- a/cpu/mcf52x2/Makefile
+++ b/cpu/mcf52x2/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2004
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -25,21 +25,25 @@ include $(TOPDIR)/config.mk
# CFLAGS += -DET_DEBUG
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START =
-OBJS = serial.o interrupts.o cpu.o speed.o cpu_init.o fec.o
+COBJS = serial.o interrupts.o cpu.o speed.o cpu_init.o fec.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mcf52x2/cpu.c b/cpu/mcf52x2/cpu.c
index 32a524f..aa6b2bd 100644
--- a/cpu/mcf52x2/cpu.c
+++ b/cpu/mcf52x2/cpu.c
@@ -2,6 +2,10 @@
* (C) Copyright 2003
* Josef Baumgartner <josef.baumgartner@telex.de>
*
+ * MCF5282 additionals
+ * (C) Copyright 2005
+ * BuS Elektronik GmbH & Co. KG <esw@bus-elektronik.de>
+ *
* See file CREDITS for list of people who contributed to this
* project.
*
@@ -25,19 +29,61 @@
#include <watchdog.h>
#include <command.h>
+#ifdef CONFIG_M5271
+#include <asm/immap_5271.h>
+#include <asm/m5271.h>
+#endif
+
#ifdef CONFIG_M5272
#include <asm/immap_5272.h>
#include <asm/m5272.h>
#endif
#ifdef CONFIG_M5282
-
+#include <asm/m5282.h>
+#include <asm/immap_5282.h>
#endif
#ifdef CONFIG_M5249
#include <asm/m5249.h>
#endif
+#ifdef CONFIG_M5271
+int checkcpu (void)
+{
+ char buf[32];
+
+ printf ("CPU: Freescale Coldfire MCF5271 at %s MHz\n", strmhz(buf, CFG_CLK));
+ return 0;
+}
+
+int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) {
+ mbar_writeByte(MCF_RCM_RCR,
+ MCF_RCM_RCR_SOFTRST | MCF_RCM_RCR_FRCRSTOUT);
+ return 0;
+};
+
+#if defined(CONFIG_WATCHDOG)
+void watchdog_reset (void)
+{
+ mbar_writeShort(MCF_WTM_WSR, 0x5555);
+ mbar_writeShort(MCF_WTM_WSR, 0xAAAA);
+}
+
+int watchdog_disable (void)
+{
+ mbar_writeShort(MCF_WTM_WCR, 0);
+ return (0);
+}
+
+int watchdog_init (void)
+{
+ mbar_writeShort(MCF_WTM_WCR, MCF_WTM_WCR_EN);
+ return (0);
+}
+#endif /* #ifdef CONFIG_WATCHDOG */
+
+#endif
#ifdef CONFIG_M5272
int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) {
@@ -66,16 +112,15 @@ int checkcpu(void) {
case 0x4: suf = "3K75N"; break;
default:
suf = NULL;
- printf ("MOTOROLA MCF5272 (Mask:%01x)\n", msk);
+ printf ("Freescale MCF5272 (Mask:%01x)\n", msk);
break;
}
if (suf)
- printf ("MOTOROLA MCF5272 %s\n", suf);
+ printf ("Freescale MCF5272 %s\n", suf);
return 0;
};
-
#if defined(CONFIG_WATCHDOG)
/* Called by macro WATCHDOG_RESET */
void watchdog_reset (void)
@@ -117,11 +162,25 @@ int watchdog_init (void)
#ifdef CONFIG_M5282
int checkcpu (void)
{
- puts ("CPU: MOTOROLA Coldfire MCF5282\n");
+ unsigned char resetsource = MCFRESET_RSR;
+
+ printf ("CPU: Freescale Coldfire MCF5282 (PIN: %2.2x REV: %2.2x)\n",
+ MCFCCM_CIR>>8,MCFCCM_CIR & MCFCCM_CIR_PRN_MASK);
+ printf ("Reset:%s%s%s%s%s%s%s\n",
+ (resetsource & MCFRESET_RSR_LOL) ? " Loss of Lock" : "",
+ (resetsource & MCFRESET_RSR_LOC) ? " Loss of Clock" : "",
+ (resetsource & MCFRESET_RSR_EXT) ? " External" : "",
+ (resetsource & MCFRESET_RSR_POR) ? " Power On" : "",
+ (resetsource & MCFRESET_RSR_WDR) ? " Watchdog" : "",
+ (resetsource & MCFRESET_RSR_SOFT) ? " Software" : "",
+ (resetsource & MCFRESET_RSR_LVD) ? " Low Voltage" : ""
+ );
return 0;
}
-int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) {
+int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+ MCFRESET_RCR = MCFRESET_RCR_SOFTRST;
return 0;
};
#endif
@@ -131,7 +190,7 @@ int checkcpu (void)
{
char buf[32];
- printf ("CPU: MOTOROLA Coldfire MCF5249 at %s MHz\n", strmhz(buf, CFG_CLK));
+ printf ("CPU: Freescale Coldfire MCF5249 at %s MHz\n", strmhz(buf, CFG_CLK));
return 0;
}
diff --git a/cpu/mcf52x2/cpu_init.c b/cpu/mcf52x2/cpu_init.c
index 350c431..1748ea9 100644
--- a/cpu/mcf52x2/cpu_init.c
+++ b/cpu/mcf52x2/cpu_init.c
@@ -2,6 +2,10 @@
* (C) Copyright 2003
* Josef Baumgartner <josef.baumgartner@telex.de>
*
+ * MCF5282 additionals
+ * (C) Copyright 2005
+ * BuS Elektronik GmbH & Co. KG <esw@bus-elektronik.de>
+ *
* See file CREDITS for list of people who contributed to this
* project.
*
@@ -12,7 +16,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
@@ -24,6 +28,11 @@
#include <common.h>
#include <watchdog.h>
+#ifdef CONFIG_M5271
+#include <asm/m5271.h>
+#include <asm/immap_5271.h>
+#endif
+
#ifdef CONFIG_M5272
#include <asm/m5272.h>
#include <asm/immap_5272.h>
@@ -38,6 +47,38 @@
#include <asm/m5249.h>
#endif
+#if defined(CONFIG_M5271)
+void cpu_init_f (void)
+{
+#ifndef CONFIG_WATCHDOG
+ /* Disable the watchdog if we aren't using it */
+ mbar_writeShort(MCF_WTM_WCR, 0);
+#endif
+
+ /* Set clockspeed to 100MHz */
+ mbar_writeShort(MCF_FMPLL_SYNCR,
+ MCF_FMPLL_SYNCR_MFD(0) | MCF_FMPLL_SYNCR_RFD(0));
+ while (!mbar_readByte(MCF_FMPLL_SYNSR) & MCF_FMPLL_SYNSR_LOCK);
+
+ /* Enable UART pins */
+ mbar_writeShort(MCF_GPIO_PAR_UART, MCF_GPIO_PAR_UART_U0TXD |
+ MCF_GPIO_PAR_UART_U0RXD |
+ MCF_GPIO_PAR_UART_U1RXD_UART1 |
+ MCF_GPIO_PAR_UART_U1TXD_UART1);
+
+ /* Enable Ethernet pins */
+ mbar_writeByte(MCF_GPIO_PAR_FECI2C, CFG_FECI2C);
+}
+
+/*
+ * initialize higher level parts of CPU like timers
+ */
+int cpu_init_r (void)
+{
+ return (0);
+}
+#endif
+
#if defined(CONFIG_M5272)
/*
* Breath some life into the CPU...
@@ -60,7 +101,7 @@ void cpu_init_f (void)
regp->sysctrl_reg.sc_scr = CFG_SCR;
regp->sysctrl_reg.sc_spr = CFG_SPR;
- /* Setup Ports: */
+ /* Setup Ports: */
regp->gpio_reg.gpio_pacnt = CFG_PACNT;
regp->gpio_reg.gpio_paddr = CFG_PADDR;
regp->gpio_reg.gpio_padat = CFG_PADAT;
@@ -110,15 +151,15 @@ void cpu_init_f (void)
#endif /* #ifndef CONFIG_MONITOR_IS_IN_RAM */
- /* enable instruction cache now */
- icache_enable();
+ /* enable instruction cache now */
+ icache_enable();
}
/*
* initialize higher level parts of CPU like timers
*/
-int cpu_init_r (void)
+int cpu_init_r (void)
{
return (0);
}
@@ -135,13 +176,186 @@ int cpu_init_r (void)
*/
void cpu_init_f (void)
{
+#ifndef CONFIG_WATCHDOG
+ /* disable watchdog if we aren't using it */
+ MCFWTM_WCR = 0;
+#endif
+
+#ifndef CONFIG_MONITOR_IS_IN_RAM
+ /* Set speed /PLL */
+ MCFCLOCK_SYNCR = MCFCLOCK_SYNCR_MFD(CFG_MFD) | MCFCLOCK_SYNCR_RFD(CFG_RFD);
+
+ /* Set up the GPIO ports */
+#ifdef CFG_PEPAR
+ MCFGPIO_PEPAR = CFG_PEPAR;
+#endif
+#ifdef CFG_PFPAR
+ MCFGPIO_PFPAR = CFG_PFPAR;
+#endif
+#ifdef CFG_PJPAR
+ MCFGPIO_PJPAR = CFG_PJPAR;
+#endif
+#ifdef CFG_PSDPAR
+ MCFGPIO_PSDPAR = CFG_PSDPAR;
+#endif
+#ifdef CFG_PASPAR
+ MCFGPIO_PASPAR = CFG_PASPAR;
+#endif
+#ifdef CFG_PEHLPAR
+ MCFGPIO_PEHLPAR = CFG_PEHLPAR;
+#endif
+#ifdef CFG_PQSPAR
+ MCFGPIO_PQSPAR = CFG_PQSPAR;
+#endif
+#ifdef CFG_PTCPAR
+ MCFGPIO_PTCPAR = CFG_PTCPAR;
+#endif
+#ifdef CFG_PTDPAR
+ MCFGPIO_PTDPAR = CFG_PTDPAR;
+#endif
+#ifdef CFG_PUAPAR
+ MCFGPIO_PUAPAR = CFG_PUAPAR;
+#endif
+
+#ifdef CFG_DDRUA
+ MCFGPIO_DDRUA = CFG_DDRUA;
+#endif
+
+ /* This is probably a bad place to setup chip selects, but everyone
+ else is doing it! */
+
+#if defined(CFG_CS0_BASE) & defined(CFG_CS0_SIZE) & \
+ defined(CFG_CS0_WIDTH) & defined(CFG_CS0_RO) & \
+ defined(CFG_CS0_WS)
+
+ MCFCSM_CSAR0 = (CFG_CS0_BASE >> 16) & 0xFFFF;
+
+ #if (CFG_CS0_WIDTH == 8)
+ #define CFG_CS0_PS MCFCSM_CSCR_PS_8
+ #elif (CFG_CS0_WIDTH == 16)
+ #define CFG_CS0_PS MCFCSM_CSCR_PS_16
+ #elif (CFG_CS0_WIDTH == 32)
+ #define CFG_CS0_PS MCFCSM_CSCR_PS_32
+ #else
+ #error "CFG_CS0_WIDTH: Fault - wrong bus with for CS0"
+ #endif
+ MCFCSM_CSCR0 = MCFCSM_CSCR_WS(CFG_CS0_WS)
+ |CFG_CS0_PS
+ |MCFCSM_CSCR_AA;
+
+ #if (CFG_CS0_RO != 0)
+ MCFCSM_CSMR0 = MCFCSM_CSMR_BAM(CFG_CS0_SIZE-1)
+ |MCFCSM_CSMR_WP|MCFCSM_CSMR_V;
+ #else
+ MCFCSM_CSMR0 = MCFCSM_CSMR_BAM(CFG_CS0_SIZE-1)|MCFCSM_CSMR_V;
+ #endif
+#else
+ #waring "Chip Select 0 are not initialized/used"
+#endif
+
+#if defined(CFG_CS1_BASE) & defined(CFG_CS1_SIZE) & \
+ defined(CFG_CS1_WIDTH) & defined(CFG_CS1_RO) & \
+ defined(CFG_CS1_WS)
+
+ MCFCSM_CSAR1 = (CFG_CS1_BASE >> 16) & 0xFFFF;
+
+ #if (CFG_CS1_WIDTH == 8)
+ #define CFG_CS1_PS MCFCSM_CSCR_PS_8
+ #elif (CFG_CS1_WIDTH == 16)
+ #define CFG_CS1_PS MCFCSM_CSCR_PS_16
+ #elif (CFG_CS1_WIDTH == 32)
+ #define CFG_CS1_PS MCFCSM_CSCR_PS_32
+ #else
+ #error "CFG_CS1_WIDTH: Fault - wrong bus with for CS1"
+ #endif
+ MCFCSM_CSCR1 = MCFCSM_CSCR_WS(CFG_CS1_WS)
+ |CFG_CS1_PS
+ |MCFCSM_CSCR_AA;
+
+ #if (CFG_CS1_RO != 0)
+ MCFCSM_CSMR1 = MCFCSM_CSMR_BAM(CFG_CS1_SIZE-1)
+ |MCFCSM_CSMR_WP
+ |MCFCSM_CSMR_V;
+ #else
+ MCFCSM_CSMR1 = MCFCSM_CSMR_BAM(CFG_CS1_SIZE-1)
+ |MCFCSM_CSMR_V;
+ #endif
+#else
+ #warning "Chip Select 1 are not initialized/used"
+#endif
+
+#if defined(CFG_CS2_BASE) & defined(CFG_CS2_SIZE) & \
+ defined(CFG_CS2_WIDTH) & defined(CFG_CS2_RO) & \
+ defined(CFG_CS2_WS)
+
+ MCFCSM_CSAR2 = (CFG_CS2_BASE >> 16) & 0xFFFF;
+
+ #if (CFG_CS2_WIDTH == 8)
+ #define CFG_CS2_PS MCFCSM_CSCR_PS_8
+ #elif (CFG_CS2_WIDTH == 16)
+ #define CFG_CS2_PS MCFCSM_CSCR_PS_16
+ #elif (CFG_CS2_WIDTH == 32)
+ #define CFG_CS2_PS MCFCSM_CSCR_PS_32
+ #else
+ #error "CFG_CS2_WIDTH: Fault - wrong bus with for CS2"
+ #endif
+ MCFCSM_CSCR2 = MCFCSM_CSCR_WS(CFG_CS2_WS)
+ |CFG_CS2_PS
+ |MCFCSM_CSCR_AA;
+
+ #if (CFG_CS2_RO != 0)
+ MCFCSM_CSMR2 = MCFCSM_CSMR_BAM(CFG_CS2_SIZE-1)
+ |MCFCSM_CSMR_WP
+ |MCFCSM_CSMR_V;
+ #else
+ MCFCSM_CSMR2 = MCFCSM_CSMR_BAM(CFG_CS2_SIZE-1)
+ |MCFCSM_CSMR_V;
+ #endif
+#else
+ #warning "Chip Select 2 are not initialized/used"
+#endif
+#if defined(CFG_CS3_BASE) & defined(CFG_CS3_SIZE) & \
+ defined(CFG_CS3_WIDTH) & defined(CFG_CS3_RO) & \
+ defined(CFG_CS3_WS)
+
+ MCFCSM_CSAR3 = (CFG_CS3_BASE >> 16) & 0xFFFF;
+
+ #if (CFG_CS3_WIDTH == 8)
+ #define CFG_CS3_PS MCFCSM_CSCR_PS_8
+ #elif (CFG_CS3_WIDTH == 16)
+ #define CFG_CS3_PS MCFCSM_CSCR_PS_16
+ #elif (CFG_CS3_WIDTH == 32)
+ #define CFG_CS3_PS MCFCSM_CSCR_PS_32
+ #else
+ #error "CFG_CS3_WIDTH: Fault - wrong bus with for CS1"
+ #endif
+ MCFCSM_CSCR3 = MCFCSM_CSCR_WS(CFG_CS3_WS)
+ |CFG_CS3_PS
+ |MCFCSM_CSCR_AA;
+
+ #if (CFG_CS3_RO != 0)
+ MCFCSM_CSMR3 = MCFCSM_CSMR_BAM(CFG_CS3_SIZE-1)
+ |MCFCSM_CSMR_WP
+ |MCFCSM_CSMR_V;
+ #else
+ MCFCSM_CSMR3 = MCFCSM_CSMR_BAM(CFG_CS3_SIZE-1)
+ |MCFCSM_CSMR_V;
+ #endif
+#else
+ #warning "Chip Select 3 are not initialized/used"
+#endif
+
+#endif /* CONFIG_MONITOR_IS_IN_RAM */
+
+ /* defer enabling cache until boot (see do_go) */
+ /* icache_enable(); */
}
/*
* initialize higher level parts of CPU like timers
*/
-int cpu_init_r (void)
+int cpu_init_r (void)
{
return (0);
}
@@ -165,23 +379,23 @@ void cpu_init_f (void)
volatile unsigned long cpll = mbar2_readLong(MCFSIM_PLLCR);
unsigned long pllcr;
#ifdef CFG_FAST_CLK
- pllcr = 0x925a3100; /* ~140MHz clock (PLL bypass = 0) */
+ pllcr = 0x925a3100; /* ~140MHz clock (PLL bypass = 0) */
#else
- pllcr = 0x135a4140; /* ~72MHz clock (PLL bypass = 0) */
-#endif
- cpll = cpll & 0xfffffffe; /* Set PLL bypass mode = 0 (PSTCLK = crystal) */
- mbar2_writeLong(MCFSIM_PLLCR, cpll); /* Set the PLL to bypass mode (PSTCLK = crystal) */
- mbar2_writeLong(MCFSIM_PLLCR, pllcr); /* set the clock speed */
- pllcr ^= 0x00000001; /* Set pll bypass to 1 */
- mbar2_writeLong(MCFSIM_PLLCR, pllcr); /* Start locking (pll bypass = 1) */
- udelay(0x20); /* Wait for a lock ... */
+ pllcr = 0x135a4140; /* ~72MHz clock (PLL bypass = 0) */
+#endif
+ cpll = cpll & 0xfffffffe; /* Set PLL bypass mode = 0 (PSTCLK = crystal) */
+ mbar2_writeLong(MCFSIM_PLLCR, cpll); /* Set the PLL to bypass mode (PSTCLK = crystal) */
+ mbar2_writeLong(MCFSIM_PLLCR, pllcr); /* set the clock speed */
+ pllcr ^= 0x00000001; /* Set pll bypass to 1 */
+ mbar2_writeLong(MCFSIM_PLLCR, pllcr); /* Start locking (pll bypass = 1) */
+ udelay(0x20); /* Wait for a lock ... */
#endif /* #ifndef CFG_PLL_BYPASS */
/*
* NOTE: by setting the GPIO_FUNCTION registers, we ensure that the UART pins
- * (UART0: gpio 30,27, UART1: gpio 31, 28) will be used as UART pins
- * which is their primary function.
- * ~Jeremy
+ * (UART0: gpio 30,27, UART1: gpio 31, 28) will be used as UART pins
+ * which is their primary function.
+ * ~Jeremy
*/
mbar2_writeLong(MCFSIM_GPIO_FUNC, CFG_GPIO_FUNC);
mbar2_writeLong(MCFSIM_GPIO1_FUNC, CFG_GPIO1_FUNC);
@@ -196,7 +410,7 @@ void cpu_init_f (void)
* (Internal Register Display) command
* ~Jeremy
*
- */
+ */
mbar_writeByte(MCFSIM_MPARK, 0x30); /* 5249 Internal Core takes priority over DMA */
mbar_writeByte(MCFSIM_SYPCR, 0x00);
mbar_writeByte(MCFSIM_SWIVR, 0x0f);
@@ -215,9 +429,9 @@ void cpu_init_f (void)
mbar_writeByte(MCFSIM_QSPIICR, 0x00);
mbar2_writeLong(MCFSIM_GPIO_INT_EN, 0x00000080);
- mbar2_writeByte(MCFSIM_INTBASE, 0x40); /* Base interrupts at 64 */
+ mbar2_writeByte(MCFSIM_INTBASE, 0x40); /* Base interrupts at 64 */
mbar2_writeByte(MCFSIM_SPURVEC, 0x00);
- mbar2_writeLong(MCFSIM_IDECONFIG1, 0x00000020); /* Enable a 1 cycle pre-drive cycle on CS1 */
+ mbar2_writeLong(MCFSIM_IDECONFIG1, 0x00000020); /* Enable a 1 cycle pre-drive cycle on CS1 */
/* Setup interrupt priorities for gpio7 */
/* mbar2_writeLong(MCFSIM_INTLEV5, 0x70000000); */
@@ -245,7 +459,7 @@ void cpu_init_f (void)
/*
* initialize higher level parts of CPU like timers
*/
-int cpu_init_r (void)
+int cpu_init_r (void)
{
return (0);
}
diff --git a/cpu/mcf52x2/fec.c b/cpu/mcf52x2/fec.c
index a5c50af..b6540b5 100644
--- a/cpu/mcf52x2/fec.c
+++ b/cpu/mcf52x2/fec.c
@@ -25,6 +25,11 @@
#include <malloc.h>
#include <asm/fec.h>
+#ifdef CONFIG_M5271
+#include <asm/m5271.h>
+#include <asm/immap_5271.h>
+#endif
+
#ifdef CONFIG_M5272
#include <asm/m5272.h>
#include <asm/immap_5272.h>
@@ -41,7 +46,7 @@
#ifdef CONFIG_M5272
#define FEC_ADDR (CFG_MBAR + 0x840)
#endif
-#ifdef CONFIG_M5282
+#if defined(CONFIG_M5282) || defined(CONFIG_M5271)
#define FEC_ADDR (CFG_MBAR + 0x1000)
#endif
@@ -200,7 +205,9 @@ int eth_rx (void)
int eth_init (bd_t * bd)
{
-
+#ifndef CFG_ENET_BD_BASE
+ DECLARE_GLOBAL_DATA_PTR;
+#endif
int i;
volatile fec_t *fecp = (fec_t *) (FEC_ADDR);
@@ -240,10 +247,27 @@ int eth_init (bd_t * bd)
#endif
#undef ea
+#ifdef CONFIG_M5271
+ /* Clear multicast address hash table
+ */
+ fecp->fec_ghash_table_high = 0;
+ fecp->fec_ghash_table_low = 0;
+
+ /* Clear individual address hash table
+ */
+ fecp->fec_ihash_table_high = 0;
+ fecp->fec_ihash_table_low = 0;
+#else
/* Clear multicast address hash table
*/
+#ifdef CONFIG_M5282
+ fecp->fec_ihash_table_high = 0;
+ fecp->fec_ihash_table_low = 0;
+#else
fecp->fec_hash_table_high = 0;
fecp->fec_hash_table_low = 0;
+#endif
+#endif
/* Set maximum receive buffer size.
*/
@@ -256,7 +280,16 @@ int eth_init (bd_t * bd)
txIdx = 0;
if (!rtx) {
+#ifdef CFG_ENET_BD_BASE
rtx = (RTXBD *) CFG_ENET_BD_BASE;
+#else
+ rtx = (RTXBD *) (CFG_MONITOR_BASE+gd->reloc_off -
+ (((PKTBUFSRX+TX_BUF_CNT)*+sizeof(cbd_t)
+ +0xFF)
+ & ~0xFF)
+ );
+ debug("set ENET_DB_BASE to %lX\n",(long) rtx);
+#endif
}
/*
@@ -290,15 +323,18 @@ int eth_init (bd_t * bd)
/* Enable MII mode
*/
-#if 0 /* Full duplex mode */
+
+#if 0 /* Full duplex mode */
fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE;
fecp->fec_x_cntrl = FEC_TCNTRL_FDEN;
-#else /* Half duplex mode */
- fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE | FEC_RCNTRL_DRT;
+#else /* Half duplex mode */
+ fecp->fec_r_cntrl = (PKT_MAXBUF_SIZE << 16); /* set max frame length */
+ fecp->fec_r_cntrl |= FEC_RCNTRL_MII_MODE | FEC_RCNTRL_DRT;
fecp->fec_x_cntrl = 0;
#endif
/* Set MII speed */
- fecp->fec_mii_speed = 0x0e;
+ fecp->fec_mii_speed = (((CFG_CLK / 2) / (2500000 / 10)) + 5) / 10;
+ fecp->fec_mii_speed *= 2;
/* Configure port B for MII.
*/
@@ -402,7 +438,7 @@ static void mii_discover_phy (void)
*/
udelay (10000); /* wait 10ms */
}
- for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) {
+ for (phyno = 1; phyno < 32 && phyaddr < 0; ++phyno) {
phytype = mii_send (mk_mii_read (phyno, PHY_PHYIDR1));
#ifdef ET_DEBUG
printf ("PHY type 0x%x pass %d type ", phytype, pass);
diff --git a/cpu/mcf52x2/interrupts.c b/cpu/mcf52x2/interrupts.c
index 868df39..116747a 100644
--- a/cpu/mcf52x2/interrupts.c
+++ b/cpu/mcf52x2/interrupts.c
@@ -27,6 +27,11 @@
#include <watchdog.h>
#include <asm/processor.h>
+#ifdef CONFIG_M5271
+#include <asm/m5271.h>
+#include <asm/immap_5271.h>
+#endif
+
#ifdef CONFIG_M5272
#include <asm/m5272.h>
#include <asm/immap_5272.h>
@@ -171,7 +176,7 @@ int interrupt_init (void)
}
#endif
-#ifdef CONFIG_M5282
+#if defined(CONFIG_M5282) || defined(CONFIG_M5271)
int interrupt_init (void)
{
return 0;
diff --git a/cpu/mcf52x2/serial.c b/cpu/mcf52x2/serial.c
index 79628d0..8be09e3 100644
--- a/cpu/mcf52x2/serial.c
+++ b/cpu/mcf52x2/serial.c
@@ -23,9 +23,14 @@
#include <common.h>
#include <command.h>
+#include <watchdog.h>
#include <asm/mcfuart.h>
+#ifdef CONFIG_M5271
+#include <asm/m5271.h>
+#endif
+
#ifdef CONFIG_M5272
#include <asm/m5272.h>
#endif
@@ -40,7 +45,7 @@
DECLARE_GLOBAL_DATA_PTR;
-#ifdef CONFIG_M5249
+#if defined(CONFIG_M5249) || defined(CONFIG_M5271)
#define DoubleClock(a) ((double)(CFG_CLK/2) / 32.0 / (double)(a))
#else
#define DoubleClock(a) ((double)(CFG_CLK) / 32.0 / (double)(a))
@@ -48,41 +53,77 @@ DECLARE_GLOBAL_DATA_PTR;
void rs_serial_setbaudrate(int port,int baudrate)
{
-#if defined(CONFIG_M5272) || defined(CONFIG_M5249)
+#if defined(CONFIG_M5272) || defined(CONFIG_M5249) || defined(CONFIG_M5271)
volatile unsigned char *uartp;
- double clock, fraction;
+# ifndef CONFIG_M5271
+ double fraction;
+# endif
+ double clock;
if (port == 0)
- uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1);
+ uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1);
else
- uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE2);
+ uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE2);
+
+ clock = DoubleClock(baudrate); /* Set baud above */
- clock = DoubleClock(baudrate); /* Set baud above */
+ uartp[MCFUART_UBG1] = (((int)clock >> 8) & 0xff); /* set msb baud */
+ uartp[MCFUART_UBG2] = ((int)clock & 0xff); /* set lsb baud */
+# ifndef CONFIG_M5271
fraction = ((clock - (int)clock) * 16.0) + 0.5;
+ uartp[MCFUART_UFPD] = ((int)fraction & 0xf); /* set baud fraction adjust */
+# endif
+#endif
+
+#if defined(CONFIG_M5282)
+ volatile unsigned char *uartp;
+ long clock;
+
+ switch (port) {
+ case 1:
+ uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE2);
+ break;
+ case 2:
+ uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE3);
+ break;
+ default:
+ uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1);
+ }
+
+ clock = (long) CFG_CLK / ((long) 32 * baudrate); /* Set baud above */
+
+ uartp[MCFUART_UBG1] = (((int)clock >> 8) & 0xff); /* set msb baud */
+ uartp[MCFUART_UBG2] = ((int) clock & 0xff); /* set lsb baud */
- uartp[MCFUART_UBG1] = (((int)clock >> 8) & 0xff); /* set msb baud */
- uartp[MCFUART_UBG2] = ((int)clock & 0xff); /* set lsb baud */
- uartp[MCFUART_UFPD] = ((int)fraction & 0xf); /* set baud fraction adjust */
#endif
};
-void rs_serial_init(int port,int baudrate)
+void rs_serial_init (int port, int baudrate)
{
- volatile unsigned char *uartp;
+ volatile unsigned char *uartp;
/*
- * Reset UART, get it into known state...
+ * Reset UART, get it into known state...
*/
- if (port == 0)
- uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1);
- else
+ switch (port) {
+ case 1:
uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE2);
+ break;
+#if defined(CONFIG_M5282)
+ case 2:
+ uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE3);
+ break;
+#endif
+ default:
+ uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1);
+ }
+
+ uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */
+ uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */
- uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */
- uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */
- uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETMRPTR; /* reset MR pointer */
- uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR; /* reset Error pointer */
+ uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETMRPTR; /* reset MR pointer */
+ uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR; /* reset Error pointer */
/*
* Set port for CONSOLE_BAUD_RATE, 8 data bits, 1 stop bit, no parity.
@@ -90,9 +131,15 @@ void rs_serial_init(int port,int baudrate)
uartp[MCFUART_UMR] = MCFUART_MR1_PARITYNONE | MCFUART_MR1_CS8;
uartp[MCFUART_UMR] = MCFUART_MR2_STOP1;
- rs_serial_setbaudrate(port,baudrate);
+ /* Mask UART interrupts */
+ uartp[MCFUART_UIMR] = 0;
+ /* Set clock Select Register: Tx/Rx clock is timer */
uartp[MCFUART_UCSR] = MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER;
+
+ rs_serial_setbaudrate (port, baudrate);
+
+ /* Enable Tx/Rx */
uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE;
return;
@@ -152,13 +199,14 @@ void serial_putc(const char c) {
}
void serial_puts (const char *s) {
- while (*s) {
+ while (*s)
serial_putc(*s++);
- }
}
int serial_getc(void) {
- while(!rs_is_char());
+ while(!rs_is_char())
+ WATCHDOG_RESET();
+
return rs_get_char();
}
diff --git a/cpu/mcf52x2/start.S b/cpu/mcf52x2/start.S
index b4926e2..f1f4077 100644
--- a/cpu/mcf52x2/start.S
+++ b/cpu/mcf52x2/start.S
@@ -55,7 +55,15 @@
*/
_vectors:
-.long 0x00000000, _START
+.long 0x00000000 /* Flash offset is 0 until we setup CS0 */
+#if defined(CONFIG_R5200)
+.long 0x400
+#elif defined(CONFIG_M5282)
+.long _start - TEXT_BASE
+#else
+.long _START
+#endif
+
.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
@@ -96,20 +104,23 @@ _vectors:
.text
+
+#if defined(CFG_INT_FLASH_BASE) && \
+ (defined(CONFIG_M5282) || defined(CONFIG_M5281))
+ #if (TEXT_BASE == CFG_INT_FLASH_BASE)
+ .long 0x55AA55AA,0xAA55AA55 /* CFM Backdoorkey */
+ .long 0xFFFFFFFF /* all sectors protected */
+ .long 0x00000000 /* supervisor/User restriction */
+ .long 0x00000000 /* programm/data space restriction */
+ .long 0x00000000 /* Flash security */
+ #endif
+#endif
.globl _start
_start:
nop
nop
move.w #0x2700,%sr
- /* if we come from a pre-loader we have no exception table and
- * therefore no VBR to set
- */
-#if !defined(CONFIG_MONITOR_IS_IN_RAM)
- move.l #CFG_FLASH_BASE, %d0
- movec %d0, %VBR
-#endif
-
#if defined(CONFIG_M5272) || defined(CONFIG_M5249)
move.l #(CFG_MBAR + 1), %d0 /* set MBAR address + valid flag */
move.c %d0, %MBAR
@@ -124,26 +135,72 @@ _start:
movec %d0, %RAMBAR0
#endif /* #if defined(CONFIG_M5272) || defined(CONFIG_M5249) */
-#ifdef CONFIG_M5282
+#if defined(CONFIG_M5282) || defined(CONFIG_M5271)
/* Initialize IPSBAR */
move.l #(CFG_MBAR + 1), %d0 /* set IPSBAR address + valid flag */
move.l %d0, 0x40000000
+#if defined(CONFIG_M5282)
+ /* Initialize RAMBAR1: locate SRAM and validate it */
+ move.l #(CFG_INIT_RAM_ADDR + 0x21), %d0
+ movec %d0, %RAMBAR1
+
+#if (TEXT_BASE == CFG_INT_FLASH_BASE)
+ /* Setup code in SRAM to initialize FLASHBAR, if start from internal Flash */
+
+ move.l #(_flashbar_setup-CFG_INT_FLASH_BASE), %a0
+ move.l #(_flashbar_setup_end-CFG_INT_FLASH_BASE), %a1
+ move.l #(CFG_INIT_RAM_ADDR), %a2
+_copy_flash:
+ move.l (%a0)+, (%a2)+
+ cmp.l %a0, %a1
+ bgt.s _copy_flash
+ jmp CFG_INIT_RAM_ADDR
+
+_flashbar_setup:
/* Initialize FLASHBAR: locate internal Flash and validate it */
move.l #(CFG_INT_FLASH_BASE + 0x21), %d0
movec %d0, %RAMBAR0
+ jmp _after_flashbar_copy.L /* Force jump to absolute address */
+_flashbar_setup_end:
+ nop
+_after_flashbar_copy:
+#else
+ /* Setup code to initialize FLASHBAR, if start from external Memory */
+ move.l #(CFG_INT_FLASH_BASE + 0x21), %d0
+ movec %d0, %RAMBAR0
+#endif /* (TEXT_BASE == CFG_INT_FLASH_BASE) */
- /* Initialize RAMBAR1: locate SRAM and validate it */
- move.l #(CFG_INIT_RAM_ADDR + 0x21), %d0
- movec %d0, %RAMBAR1
+#endif
+#endif
+ /* if we come from a pre-loader we have no exception table and
+ * therefore no VBR to set
+ */
+#if !defined(CONFIG_MONITOR_IS_IN_RAM)
+ move.l #CFG_FLASH_BASE, %d0
+ movec %d0, %VBR
#endif
+#ifdef CONFIG_R5200
+ move.l #(_flash_setup-CFG_FLASH_BASE), %a0
+ move.l #(_flash_setup_end-CFG_FLASH_BASE), %a1
+ move.l #(CFG_INIT_RAM_ADDR), %a2
+_copy_flash:
+ move.l (%a0)+, (%a2)+
+ cmp.l %a0, %a1
+ bgt.s _copy_flash
+ jmp CFG_INIT_RAM_ADDR
+_after_flash_copy:
+#endif
+
+#if 0
/* invalidate and disable cache */
move.l #0x01000000, %d0 /* Invalidate cache cmd */
movec %d0, %CACR /* Invalidate cache */
move.l #0, %d0
movec %d0, %ACR0
movec %d0, %ACR1
+#endif
/* set stackpointer to end of internal ram to get some stackspace for the first c-code */
move.l #(CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET), %sp
@@ -154,10 +211,28 @@ _start:
bsr cpu_init_f /* run low-level CPU init code (from flash) */
bsr board_init_f /* run low-level board init code (from flash) */
- /* board_init_f() does not return
+ /* board_init_f() does not return */
/*------------------------------------------------------------------------------*/
+#ifdef CONFIG_R5200
+_flash_setup:
+ /* CSAR0 */
+ move.l #((CFG_FLASH_BASE & 0xffff0000) >> 16), %d0
+ move.w %d0, 0x40000080
+
+ /* CSCR0 */
+ move.l #0x2180, %d0 /* 8 wait states, 16bit port, auto ack, */
+ move.w %d0, 0x4000008A
+
+ /* CSMR0 */
+ move.l #0x001f0001, %d0 /* 2 MB, valid */
+ move.l %d0, 0x40000084
+
+ jmp _after_flash_copy.L
+_flash_setup_end:
+#endif
+
/*
* void relocate_code (addr_sp, gd, addr_moni)
*
@@ -180,7 +255,6 @@ relocate_code:
move.l #CFG_MONITOR_BASE, %a1
move.l #__init_end, %a2
move.l %a0, %a3
-
/* copy the code to RAM */
1:
move.l (%a1)+, (%a3)+
@@ -191,14 +265,14 @@ relocate_code:
* We are done. Do not return, instead branch to second part of board
* initialization, now running from RAM.
*/
- move.l %a0, %a1
+ move.l %a0, %a1
add.l #(in_ram - CFG_MONITOR_BASE), %a1
jmp (%a1)
in_ram:
clear_bss:
- /*
+ /*
* Now clear BSS segment
*/
move.l %a0, %a1
@@ -228,6 +302,23 @@ clear_bss:
cmp.l %a2, %a1
bne 7b
+#if defined(CONFIG_M5281) || defined(CONFIG_M5282)
+ /* patch the 3 accesspoints to 3 ichache_state */
+ /* quick and dirty */
+
+ move.l %a0,%d1
+ add.l #(icache_state - CFG_MONITOR_BASE),%d1
+ move.l %a0,%a1
+ add.l #(icache_state_access_1+2 - CFG_MONITOR_BASE),%a1
+ move.l %d1,(%a1)
+ move.l %a0,%a1
+ add.l #(icache_state_access_2+2 - CFG_MONITOR_BASE),%a1
+ move.l %d1,(%a1)
+ move.l %a0,%a1
+ add.l #(icache_state_access_3+2 - CFG_MONITOR_BASE),%a1
+ move.l %d1,(%a1)
+#endif
+
/* calculate relative jump to board_init_r in ram */
move.l %a0, %a1
add.l #(board_init_r - CFG_MONITOR_BASE), %a1
@@ -235,6 +326,10 @@ clear_bss:
/* set parameters for board_init_r */
move.l %a0,-(%sp) /* dest_addr */
move.l %d0,-(%sp) /* gd */
+ #if defined(DEBUG) && (TEXT_BASE != CFG_INT_FLASH_BASE) && \
+ defined(CFG_HALT_BEFOR_RAM_JUMP)
+ halt
+ #endif
jsr (%a1)
/*------------------------------------------------------------------------------*/
@@ -289,6 +384,7 @@ icache_enable:
move.l #0x80400100, %d0 /* Setup cache mask, data cache disabel*/
movec %d0, %CACR /* Enable cache */
moveq #1, %d0
+icache_state_access_1:
move.l %d0, icache_state
rts
#endif
@@ -323,18 +419,19 @@ icache_disable:
movec %d0, %ACR0 /* Enable cache */
movec %d0, %ACR1 /* Enable cache */
moveq #0, %d0
+icache_state_access_2:
move.l %d0, icache_state
rts
.globl icache_status
icache_status:
+icache_state_access_3:
move.l icache_state, %d0
rts
.data
icache_state:
- .long 1
-
+ .long 0 /* cache is diabled on inirialization */
/*------------------------------------------------------------------------------*/
diff --git a/cpu/microblaze/Makefile b/cpu/microblaze/Makefile
index 610043e..07ed6ce 100644
--- a/cpu/microblaze/Makefile
+++ b/cpu/microblaze/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = cpu.o interrupts.o
+COBJS = cpu.o interrupts.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mips/Makefile b/cpu/mips/Makefile
index c8b30c7..f9a49df 100644
--- a/cpu/mips/Makefile
+++ b/cpu/mips/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2003
+# (C) Copyright 2003-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,23 +23,27 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = asc_serial.o au1x00_serial.o au1x00_eth.o au1x00_usb_ohci.o \
+COBJS = asc_serial.o au1x00_serial.o au1x00_eth.o au1x00_usb_ohci.o \
cpu.o interrupts.o incaip_clock.o
SOBJS = incaip_wdt.o cache.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-$(LIB): $(OBJS) $(SOBJS)
- $(AR) crv $@ $(OBJS) $(SOBJS)
+all: $(obj).depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mips/config.mk b/cpu/mips/config.mk
index c357615..b29986e 100644
--- a/cpu/mips/config.mk
+++ b/cpu/mips/config.mk
@@ -21,7 +21,7 @@
# MA 02111-1307 USA
#
v=$(shell \
-mips-linux-as --version|grep "GNU assembler"|awk '{print $$3}'|awk -F . '{print $$2}')
+$(CROSS_COMPILE)as --version|grep "GNU assembler"|awk '{print $$3}'|awk -F . '{print $$2}')
MIPSFLAGS=$(shell \
if [ "$v" -lt "14" ]; then \
echo "-mcpu=4kc"; \
diff --git a/cpu/mpc5xx/Makefile b/cpu/mpc5xx/Makefile
index b787b61..d696e79 100644
--- a/cpu/mpc5xx/Makefile
+++ b/cpu/mpc5xx/Makefile
@@ -1,4 +1,7 @@
#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
# (C) Copyright 2003
# Martin Winistoerfer, martinwinistoerfer@gmx.ch.
#
@@ -32,21 +35,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
+
+START = start.o
+COBJS = serial.o cpu.o cpu_init.o interrupts.o traps.o speed.o spi.o
-START = start.S
-OBJS = serial.o cpu.o cpu_init.o interrupts.o traps.o speed.o spi.o
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-all: .depend $(START) $(LIB)
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mpc5xxx/Makefile b/cpu/mpc5xxx/Makefile
index a97b625..683ded8 100644
--- a/cpu/mpc5xxx/Makefile
+++ b/cpu/mpc5xxx/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2003
+# (C) Copyright 2003-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,23 +23,27 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-ASOBJS = io.o firmware_sc_task_bestcomm.impl.o firmware_sc_task.impl.o
-OBJS = i2c.o traps.o cpu.o cpu_init.o fec.o ide.o interrupts.o \
+SOBJS = io.o firmware_sc_task_bestcomm.impl.o firmware_sc_task.impl.o
+COBJS = i2c.o traps.o cpu.o cpu_init.o fec.o ide.o interrupts.o \
loadtask.o pci_mpc5200.o serial.o speed.o usb_ohci.o
-all: .depend $(START) $(ASOBJS) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(ASOBJS) $(OBJS)
+ $(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(ASOBJS:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mpc5xxx/interrupts.c b/cpu/mpc5xxx/interrupts.c
index 7bacecd..7b5cb8b 100644
--- a/cpu/mpc5xxx/interrupts.c
+++ b/cpu/mpc5xxx/interrupts.c
@@ -1,4 +1,7 @@
/*
+ * (C) Copyright 2006
+ * Detlev Zundel, DENX Software Engineering, dzu@denx.de
+ *
* (C) Copyright -2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
@@ -24,18 +27,212 @@
* MA 02111-1307 USA
*/
-/*
- * interrupts.c - just enough support for the decrementer/timer
+/* this section was ripped out of arch/ppc/syslib/mpc52xx_pic.c in the
+ * Linux 2.6 source with the following copyright.
+ *
+ * Based on (well, mostly copied from) the code from the 2.4 kernel by
+ * Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg.
+ *
+ * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2003 Montavista Software, Inc
*/
#include <common.h>
#include <asm/processor.h>
+#include <asm/io.h>
#include <command.h>
-int interrupt_init_cpu (ulong *decrementer_count)
+struct irq_action {
+ interrupt_handler_t *handler;
+ void *arg;
+ ulong count;
+};
+
+static struct irq_action irq_handlers[NR_IRQS];
+
+static struct mpc5xxx_intr *intr;
+static struct mpc5xxx_sdma *sdma;
+
+static void mpc5xxx_ic_disable(unsigned int irq)
+{
+ u32 val;
+
+ if (irq == MPC5XXX_IRQ0) {
+ val = in_be32(&intr->ctrl);
+ val &= ~(1 << 11);
+ out_be32(&intr->ctrl, val);
+ } else if (irq < MPC5XXX_IRQ1) {
+ BUG();
+ } else if (irq <= MPC5XXX_IRQ3) {
+ val = in_be32(&intr->ctrl);
+ val &= ~(1 << (10 - (irq - MPC5XXX_IRQ1)));
+ out_be32(&intr->ctrl, val);
+ } else if (irq < MPC5XXX_SDMA_IRQ_BASE) {
+ val = in_be32(&intr->main_mask);
+ val |= 1 << (16 - (irq - MPC5XXX_MAIN_IRQ_BASE));
+ out_be32(&intr->main_mask, val);
+ } else if (irq < MPC5XXX_PERP_IRQ_BASE) {
+ val = in_be32(&sdma->IntMask);
+ val |= 1 << (irq - MPC5XXX_SDMA_IRQ_BASE);
+ out_be32(&sdma->IntMask, val);
+ } else {
+ val = in_be32(&intr->per_mask);
+ val |= 1 << (31 - (irq - MPC5XXX_PERP_IRQ_BASE));
+ out_be32(&intr->per_mask, val);
+ }
+}
+
+static void mpc5xxx_ic_enable(unsigned int irq)
+{
+ u32 val;
+
+ if (irq == MPC5XXX_IRQ0) {
+ val = in_be32(&intr->ctrl);
+ val |= 1 << 11;
+ out_be32(&intr->ctrl, val);
+ } else if (irq < MPC5XXX_IRQ1) {
+ BUG();
+ } else if (irq <= MPC5XXX_IRQ3) {
+ val = in_be32(&intr->ctrl);
+ val |= 1 << (10 - (irq - MPC5XXX_IRQ1));
+ out_be32(&intr->ctrl, val);
+ } else if (irq < MPC5XXX_SDMA_IRQ_BASE) {
+ val = in_be32(&intr->main_mask);
+ val &= ~(1 << (16 - (irq - MPC5XXX_MAIN_IRQ_BASE)));
+ out_be32(&intr->main_mask, val);
+ } else if (irq < MPC5XXX_PERP_IRQ_BASE) {
+ val = in_be32(&sdma->IntMask);
+ val &= ~(1 << (irq - MPC5XXX_SDMA_IRQ_BASE));
+ out_be32(&sdma->IntMask, val);
+ } else {
+ val = in_be32(&intr->per_mask);
+ val &= ~(1 << (31 - (irq - MPC5XXX_PERP_IRQ_BASE)));
+ out_be32(&intr->per_mask, val);
+ }
+}
+
+static void mpc5xxx_ic_ack(unsigned int irq)
+{
+ u32 val;
+
+ /*
+ * Only some irqs are reset here, others in interrupting hardware.
+ */
+
+ switch (irq) {
+ case MPC5XXX_IRQ0:
+ val = in_be32(&intr->ctrl);
+ val |= 0x08000000;
+ out_be32(&intr->ctrl, val);
+ break;
+ case MPC5XXX_CCS_IRQ:
+ val = in_be32(&intr->enc_status);
+ val |= 0x00000400;
+ out_be32(&intr->enc_status, val);
+ break;
+ case MPC5XXX_IRQ1:
+ val = in_be32(&intr->ctrl);
+ val |= 0x04000000;
+ out_be32(&intr->ctrl, val);
+ break;
+ case MPC5XXX_IRQ2:
+ val = in_be32(&intr->ctrl);
+ val |= 0x02000000;
+ out_be32(&intr->ctrl, val);
+ break;
+ case MPC5XXX_IRQ3:
+ val = in_be32(&intr->ctrl);
+ val |= 0x01000000;
+ out_be32(&intr->ctrl, val);
+ break;
+ default:
+ if (irq >= MPC5XXX_SDMA_IRQ_BASE
+ && irq < (MPC5XXX_SDMA_IRQ_BASE + MPC5XXX_SDMA_IRQ_NUM)) {
+ out_be32(&sdma->IntPend,
+ 1 << (irq - MPC5XXX_SDMA_IRQ_BASE));
+ }
+ break;
+ }
+}
+
+static void mpc5xxx_ic_disable_and_ack(unsigned int irq)
+{
+ mpc5xxx_ic_disable(irq);
+ mpc5xxx_ic_ack(irq);
+}
+
+static void mpc5xxx_ic_end(unsigned int irq)
+{
+ mpc5xxx_ic_enable(irq);
+}
+
+void mpc5xxx_init_irq(void)
+{
+ u32 intr_ctrl;
+
+ /* Remap the necessary zones */
+ intr = (struct mpc5xxx_intr *)(MPC5XXX_ICTL);
+ sdma = (struct mpc5xxx_sdma *)(MPC5XXX_SDMA);
+
+ /* Disable all interrupt sources. */
+ out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */
+ out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */
+ out_be32(&intr->per_mask, 0x7ffffc00); /* 1 means disabled */
+ out_be32(&intr->main_mask, 0x00010fff); /* 1 means disabled */
+ intr_ctrl = in_be32(&intr->ctrl);
+ intr_ctrl |= 0x0f000000 | /* clear IRQ 0-3 */
+ 0x00ff0000 | /* IRQ 0-3 level sensitive low active */
+ 0x00001000 | /* MEE master external enable */
+ 0x00000000 | /* 0 means disable IRQ 0-3 */
+ 0x00000001; /* CEb route critical normally */
+ out_be32(&intr->ctrl, intr_ctrl);
+
+ /* Zero a bunch of the priority settings. */
+ out_be32(&intr->per_pri1, 0);
+ out_be32(&intr->per_pri2, 0);
+ out_be32(&intr->per_pri3, 0);
+ out_be32(&intr->main_pri1, 0);
+ out_be32(&intr->main_pri2, 0);
+}
+
+int mpc5xxx_get_irq(struct pt_regs *regs)
+{
+ u32 status;
+ int irq = -1;
+
+ status = in_be32(&intr->enc_status);
+
+ if (status & 0x00000400) { /* critical */
+ irq = (status >> 8) & 0x3;
+ if (irq == 2) /* high priority peripheral */
+ goto peripheral;
+ irq += MPC5XXX_CRIT_IRQ_BASE;
+ } else if (status & 0x00200000) { /* main */
+ irq = (status >> 16) & 0x1f;
+ if (irq == 4) /* low priority peripheral */
+ goto peripheral;
+ irq += MPC5XXX_MAIN_IRQ_BASE;
+ } else if (status & 0x20000000) { /* peripheral */
+ peripheral:
+ irq = (status >> 24) & 0x1f;
+ if (irq == 0) { /* bestcomm */
+ status = in_be32(&sdma->IntPend);
+ irq = ffs(status) + MPC5XXX_SDMA_IRQ_BASE - 1;
+ } else
+ irq += MPC5XXX_PERP_IRQ_BASE;
+ }
+
+ return irq;
+}
+
+/****************************************************************************/
+
+int interrupt_init_cpu(ulong * decrementer_count)
{
*decrementer_count = get_tbclk() / CFG_HZ;
+ mpc5xxx_init_irq();
+
return (0);
}
@@ -44,14 +241,32 @@ int interrupt_init_cpu (ulong *decrementer_count)
/*
* Handle external interrupts
*/
-void
-external_interrupt(struct pt_regs *regs)
+void external_interrupt(struct pt_regs *regs)
{
- puts("external_interrupt (oops!)\n");
+ int irq, unmask = 1;
+
+ irq = mpc5xxx_get_irq(regs);
+
+ mpc5xxx_ic_disable_and_ack(irq);
+
+ enable_interrupts();
+
+ if (irq_handlers[irq].handler != NULL)
+ (*irq_handlers[irq].handler) (irq_handlers[irq].arg);
+ else {
+ printf("\nBogus External Interrupt IRQ %d\n", irq);
+ /*
+ * turn off the bogus interrupt, otherwise it
+ * might repeat forever
+ */
+ unmask = 0;
+ }
+
+ if (unmask)
+ mpc5xxx_ic_end(irq);
}
-void
-timer_interrupt_cpu (struct pt_regs *regs)
+void timer_interrupt_cpu(struct pt_regs *regs)
{
/* nothing to do here */
return;
@@ -63,22 +278,69 @@ timer_interrupt_cpu (struct pt_regs *regs)
* Install and free a interrupt handler.
*/
-void
-irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
+void irq_install_handler(int irq, interrupt_handler_t * handler, void *arg)
{
+ if (irq < 0 || irq >= NR_IRQS) {
+ printf("irq_install_handler: bad irq number %d\n", irq);
+ return;
+ }
+ if (irq_handlers[irq].handler != NULL)
+ printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n",
+ (ulong) handler, (ulong) irq_handlers[irq].handler);
+
+ irq_handlers[irq].handler = handler;
+ irq_handlers[irq].arg = arg;
+
+ mpc5xxx_ic_enable(irq);
}
-void
-irq_free_handler(int vec)
+void irq_free_handler(int irq)
{
+ if (irq < 0 || irq >= NR_IRQS) {
+ printf("irq_free_handler: bad irq number %d\n", irq);
+ return;
+ }
+
+ mpc5xxx_ic_disable(irq);
+ irq_handlers[irq].handler = NULL;
+ irq_handlers[irq].arg = NULL;
}
/****************************************************************************/
-void
-do_irqinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+#if (CONFIG_COMMANDS & CFG_CMD_IRQ)
+void do_irqinfo(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
{
- puts("IRQ related functions are unimplemented currently.\n");
+ int irq, re_enable;
+ u32 intr_ctrl;
+ char *irq_config[] = { "level sensitive, active high",
+ "edge sensitive, rising active edge",
+ "edge sensitive, falling active edge",
+ "level sensitive, active low"
+ };
+
+ re_enable = disable_interrupts();
+
+ intr_ctrl = in_be32(&intr->ctrl);
+ printf("Interrupt configuration:\n");
+
+ for (irq = 0; irq <= 3; irq++) {
+ printf("IRQ%d: %s\n", irq,
+ irq_config[(intr_ctrl >> (22 - 2 * irq)) & 0x3]);
+ }
+
+ puts("\nInterrupt-Information:\n" "Nr Routine Arg Count\n");
+
+ for (irq = 0; irq < NR_IRQS; irq++)
+ if (irq_handlers[irq].handler != NULL)
+ printf("%02d %08lx %08lx %ld\n", irq,
+ (ulong) irq_handlers[irq].handler,
+ (ulong) irq_handlers[irq].arg,
+ irq_handlers[irq].count);
+
+ if (re_enable)
+ enable_interrupts();
}
+#endif
diff --git a/cpu/mpc5xxx/serial.c b/cpu/mpc5xxx/serial.c
index cacb9f0..430d63f 100644
--- a/cpu/mpc5xxx/serial.c
+++ b/cpu/mpc5xxx/serial.c
@@ -23,6 +23,9 @@
* Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 19-Oct-00, with
* changes based on the file arch/ppc/mbxboot/m8260_tty.c from the
* Linux/PPC sources (m8260_tty.c had no copyright info in it).
+ *
+ * Martin Krause, 8 Jun 2006
+ * Added CONFIG_SERIAL_MULTI support
*/
/*
@@ -33,6 +36,10 @@
#include <common.h>
#include <mpc5xxx.h>
+#if defined (CONFIG_SERIAL_MULTI)
+#include <serial.h>
+#endif
+
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_PSC_CONSOLE)
@@ -55,9 +62,41 @@ DECLARE_GLOBAL_DATA_PTR;
#error CONFIG_PSC_CONSOLE must be in 1 ... 6
#endif
+#if defined(CONFIG_SERIAL_MULTI) && !defined(CONFIG_PSC_CONSOLE2)
+#error you must define CONFIG_PSC_CONSOLE2 if CONFIG_SERIAL_MULTI is set
+#endif
+
+#if defined(CONFIG_SERIAL_MULTI)
+#if CONFIG_PSC_CONSOLE2 == 1
+#define PSC_BASE2 MPC5XXX_PSC1
+#elif CONFIG_PSC_CONSOLE2 == 2
+#define PSC_BASE2 MPC5XXX_PSC2
+#elif CONFIG_PSC_CONSOLE2 == 3
+#define PSC_BASE2 MPC5XXX_PSC3
+#elif defined(CONFIG_MGT5100)
+#error CONFIG_PSC_CONSOLE2 must be in 1, 2 or 3
+#elif CONFIG_PSC_CONSOLE2 == 4
+#define PSC_BASE2 MPC5XXX_PSC4
+#elif CONFIG_PSC_CONSOLE2 == 5
+#define PSC_BASE2 MPC5XXX_PSC5
+#elif CONFIG_PSC_CONSOLE2 == 6
+#define PSC_BASE2 MPC5XXX_PSC6
+#else
+#error CONFIG_PSC_CONSOLE2 must be in 1 ... 6
+#endif
+#endif /* CONFIG_SERIAL_MULTI */
+
+#if defined(CONFIG_SERIAL_MULTI)
+int serial_init_dev (unsigned long dev_base)
+#else
int serial_init (void)
+#endif
{
+#if defined(CONFIG_SERIAL_MULTI)
+ volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
unsigned long baseclk;
int div;
@@ -100,13 +139,24 @@ int serial_init (void)
return (0);
}
-void
-serial_putc(const char c)
+#if defined(CONFIG_SERIAL_MULTI)
+void serial_putc_dev (unsigned long dev_base, const char c)
+#else
+void serial_putc(const char c)
+#endif
{
+#if defined(CONFIG_SERIAL_MULTI)
+ volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
if (c == '\n')
+#if defined(CONFIG_SERIAL_MULTI)
+ serial_putc_dev (dev_base, '\r');
+#else
serial_putc('\r');
+#endif
/* Wait for last character to go. */
while (!(psc->psc_status & PSC_SR_TXEMP))
@@ -115,18 +165,51 @@ serial_putc(const char c)
psc->psc_buffer_8 = c;
}
-void
-serial_puts (const char *s)
+#if defined(CONFIG_SERIAL_MULTI)
+void serial_putc_raw_dev(unsigned long dev_base, const char c)
+#else
+void serial_putc_raw(const char c)
+#endif
+{
+#if defined(CONFIG_SERIAL_MULTI)
+ volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
+ volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
+ /* Wait for last character to go. */
+ while (!(psc->psc_status & PSC_SR_TXEMP))
+ ;
+
+ psc->psc_buffer_8 = c;
+}
+
+
+#if defined(CONFIG_SERIAL_MULTI)
+void serial_puts_dev (unsigned long dev_base, const char *s)
+#else
+void serial_puts (const char *s)
+#endif
{
while (*s) {
+#if defined(CONFIG_SERIAL_MULTI)
+ serial_putc_dev (dev_base, *s++);
+#else
serial_putc (*s++);
+#endif
}
}
-int
-serial_getc(void)
+#if defined(CONFIG_SERIAL_MULTI)
+int serial_getc_dev (unsigned long dev_base)
+#else
+int serial_getc(void)
+#endif
{
+#if defined(CONFIG_SERIAL_MULTI)
+ volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
/* Wait for a character to arrive. */
while (!(psc->psc_status & PSC_SR_RXRDY))
@@ -135,18 +218,32 @@ serial_getc(void)
return psc->psc_buffer_8;
}
-int
-serial_tstc(void)
+#if defined(CONFIG_SERIAL_MULTI)
+int serial_tstc_dev (unsigned long dev_base)
+#else
+int serial_tstc(void)
+#endif
{
+#if defined(CONFIG_SERIAL_MULTI)
+ volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
return (psc->psc_status & PSC_SR_RXRDY);
}
-void
-serial_setbrg(void)
+#if defined(CONFIG_SERIAL_MULTI)
+void serial_setbrg_dev (unsigned long dev_base)
+#else
+void serial_setbrg(void)
+#endif
{
+#if defined(CONFIG_SERIAL_MULTI)
+ volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
unsigned long baseclk, div;
#if defined(CONFIG_MGT5100)
@@ -160,4 +257,124 @@ serial_setbrg(void)
psc->ctur = (div >> 8) & 0xFF;
psc->ctlr = div & 0xff;
}
+
+#if defined(CONFIG_SERIAL_MULTI)
+void serial_setrts_dev (unsigned long dev_base, int s)
+#else
+void serial_setrts(int s)
+#endif
+{
+#if defined(CONFIG_SERIAL_MULTI)
+ volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
+ volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
+
+ if (s) {
+ /* Assert RTS (become LOW) */
+ psc->op1 = 0x1;
+ }
+ else {
+ /* Negate RTS (become HIGH) */
+ psc->op0 = 0x1;
+ }
+}
+
+#if defined(CONFIG_SERIAL_MULTI)
+int serial_getcts_dev (unsigned long dev_base)
+#else
+int serial_getcts(void)
+#endif
+{
+#if defined(CONFIG_SERIAL_MULTI)
+ volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
+ volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
+
+ return (psc->ip & 0x1) ? 0 : 1;
+}
+
+#if defined(CONFIG_SERIAL_MULTI)
+int serial0_init(void)
+{
+ return (serial_init_dev(PSC_BASE));
+}
+
+int serial1_init(void)
+{
+ return (serial_init_dev(PSC_BASE2));
+}
+void serial0_setbrg (void)
+{
+ serial_setbrg_dev(PSC_BASE);
+}
+void serial1_setbrg (void)
+{
+ serial_setbrg_dev(PSC_BASE2);
+}
+
+void serial0_putc(const char c)
+{
+ serial_putc_dev(PSC_BASE,c);
+}
+
+void serial1_putc(const char c)
+{
+ serial_putc_dev(PSC_BASE2, c);
+}
+void serial0_puts(const char *s)
+{
+ serial_puts_dev(PSC_BASE, s);
+}
+
+void serial1_puts(const char *s)
+{
+ serial_puts_dev(PSC_BASE2, s);
+}
+
+int serial0_getc(void)
+{
+ return(serial_getc_dev(PSC_BASE));
+}
+
+int serial1_getc(void)
+{
+ return(serial_getc_dev(PSC_BASE2));
+}
+int serial0_tstc(void)
+{
+ return (serial_tstc_dev(PSC_BASE));
+}
+
+int serial1_tstc(void)
+{
+ return (serial_tstc_dev(PSC_BASE2));
+}
+
+struct serial_device serial0_device =
+{
+ "serial0",
+ "UART0",
+ serial0_init,
+ serial0_setbrg,
+ serial0_getc,
+ serial0_tstc,
+ serial0_putc,
+ serial0_puts,
+};
+
+struct serial_device serial1_device =
+{
+ "serial1",
+ "UART1",
+ serial1_init,
+ serial1_setbrg,
+ serial1_getc,
+ serial1_tstc,
+ serial1_putc,
+ serial1_puts,
+};
+#endif /* CONFIG_SERIAL_MULTI */
+
#endif /* CONFIG_PSC_CONSOLE */
diff --git a/cpu/mpc8220/Makefile b/cpu/mpc8220/Makefile
index 7c9b6c9..1f2e931 100644
--- a/cpu/mpc8220/Makefile
+++ b/cpu/mpc8220/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2003
+# (C) Copyright 2003-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,24 +23,28 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-ASOBJS = io.o fec_dma_tasks.o
-OBJS = cpu.o cpu_init.o dramSetup.o fec.o i2c.o \
+SOBJS = io.o fec_dma_tasks.o
+COBJS = cpu.o cpu_init.o dramSetup.o fec.o i2c.o \
interrupts.o loadtask.o speed.o \
traps.o uart.o pci.o
-all: .depend $(START) $(ASOBJS) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(ASOBJS) $(OBJS)
+ $(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(ASOBJS:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mpc8220/pci.c b/cpu/mpc8220/pci.c
index ca4a04d..4ef214e 100644
--- a/cpu/mpc8220/pci.c
+++ b/cpu/mpc8220/pci.c
@@ -170,7 +170,7 @@ pci_mpc8220_init(struct pci_controller *hose)
hose->region_count = 3;
hose->cfg_addr = &(xcpci->cfg_adr);
- hose->cfg_data = CONFIG_PCI_CFG_BUS;
+ hose->cfg_data = (volatile unsigned char *)CONFIG_PCI_CFG_BUS;
pci_set_ops(hose,
mpc8220_pci_read_config_byte,
diff --git a/cpu/mpc824x/Makefile b/cpu/mpc824x/Makefile
index df0d64e..d9fd9bf 100644
--- a/cpu/mpc824x/Makefile
+++ b/cpu/mpc824x/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -22,26 +22,35 @@
#
include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)drivers/epic)
+$(shell mkdir -p $(obj)drivers/i2c)
+endif
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
-START = start.S
-OBJS = traps.o cpu.o cpu_init.o interrupts.o speed.o \
- drivers/epic/epic1.o drivers/i2c/i2c.o pci.o bedbug_603e.o
+START = start.o
+COBJS = traps.o cpu.o cpu_init.o interrupts.o speed.o \
+ drivers/epic/epic1.o drivers/i2c/i2c.o pci.o
+COBJS_LN = bedbug_603e.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) $(addprefix $(obj),$(COBJS_LN:.o=.c))
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS) $(COBJS_LN))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
-bedbug_603e.c:
- ln -s ../mpc8260/bedbug_603e.c bedbug_603e.c
+$(obj)bedbug_603e.c:
+ ln -s $(src)../mpc8260/bedbug_603e.c $(obj)bedbug_603e.c
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mpc824x/drivers/dma/Makefile b/cpu/mpc824x/drivers/dma/Makefile
deleted file mode 100644
index 59e2fac..0000000
--- a/cpu/mpc824x/drivers/dma/Makefile
+++ /dev/null
@@ -1,83 +0,0 @@
-##########################################################################
-#
-# Copyright Motorola, Inc. 1997
-# ALL RIGHTS RESERVED
-#
-# You are hereby granted a copyright license to use, modify, and
-# distribute the SOFTWARE so long as this entire notice is retained
-# without alteration in any modified and/or redistributed versions,
-# and that such modified versions are clearly identified as such.
-# No licenses are granted by implication, estoppel or otherwise under
-# any patents or trademarks of Motorola, Inc.
-#
-# The SOFTWARE is provided on an "AS IS" basis and without warranty.
-# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-# INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libdma.a
-
-DEBUG = -DDMADBG
-LST = -Hanno -S
-OPTIM =
-CC = /risc/tools/pkgs/metaware/bin/hcppc
-CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT = -big_si -c
-ASDEBUG = -l -fm
-AS = /risc/tools/pkgs/metaware/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT = -Bbase=0 -q -r -Qn
-LKCMD =
-LINK = /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL = rm
-COPY = cp
-LIST = ls
-
-OBJECTS = dma1.o dma2.o
-
-all: $(TARGET)
-
-$(TARGET): $(OBJECTS)
- $(LINK) $(OBJECTS) -o $@
-
-objects: dma1.o
-
-clean:
- $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
-# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
- $(CCobj) $<
-
-.c.s:
- $(CCobj) $(LST) $<
-
-dma1.o: dma_export.h dma.h dma1.c
-
-dma2.o: dma.h dma2.s
diff --git a/cpu/mpc824x/drivers/dma/Makefile_pc b/cpu/mpc824x/drivers/dma/Makefile_pc
deleted file mode 100644
index 8df2a3c..0000000
--- a/cpu/mpc824x/drivers/dma/Makefile_pc
+++ /dev/null
@@ -1,89 +0,0 @@
-##########################################################################
-#
-# makefile_pc for use with mksnt tools drivers/dma
-#
-# Copyright Motorola, Inc. 1997
-# ALL RIGHTS RESERVED
-#
-# You are hereby granted a copyright license to use, modify, and
-# distribute the SOFTWARE so long as this entire notice is retained
-# without alteration in any modified and/or redistributed versions,
-# and that such modified versions are clearly identified as such.
-# No licenses are granted by implication, estoppel or otherwise under
-# any patents or trademarks of Motorola, Inc.
-#
-# The SOFTWARE is provided on an "AS IS" basis and without warranty.
-# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-# INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libdma.a
-
-DEBUG = -DDMADBG
-LST = -Hanno -S
-OPTIM =
-CC = m:/old_tools/tools/hcppc/bin/hcppc
-CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT = -big_si -c
-ASDEBUG = -l -fm
-AS = m:/old_tools/tools/hcppc/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT = -Bbase=0 -q -r -Qn
-LKCMD =
-LINK = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL = rm
-COPY = cp
-LIST = ls
-
-OBJECTS = dma1.o dma2.o
-
-all: $(TARGET)
-
-$(TARGET): $(OBJECTS)
- $(LINK) $(OBJECTS) -o $@
-
-objects: dma1.o
-
-clean:
- $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
-# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
- $(CCobj) $<
-
-.c.s:
- $(CCobj) $(LST) $<
-
-dma1.o: dma_export.h dma.h dma1.c
- $(CCobj) $<
-
-dma2.o: dma.h dma2.s
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
diff --git a/cpu/mpc824x/drivers/dma/README b/cpu/mpc824x/drivers/dma/README
deleted file mode 100644
index 06f4bc0..0000000
--- a/cpu/mpc824x/drivers/dma/README
+++ /dev/null
@@ -1,100 +0,0 @@
-CONTENT:
-
- dma.h
- dma1.c
- dma2.s
-
-WHAT ARE THESE FILES:
-
-These files contain MPC8240 (Kahlua) DMA controller
-driver routines. The driver routines are not
-written for any specific operating system.
-They serves the purpose of code sample, and
-jump-start for using the MPC8240 DMA controller.
-
-For the reason of correctness of C language
-syntax, these files are compiled by Metaware
-C compiler and assembler.
-
-ENDIAN NOTATION:
-
-The algorithm is designed for big-endian mode,
-software is responsible for byte swapping.
-
-USAGE:
-
-1. The host system that is running on MPC8240
- or using MPC8240 as I/O device shall link
- the files listed here. The memory location
- of driver routines shall take into account of
- that driver routines need to run in supervisor
- mode and they process DMA controller interrupt.
-
-2. The host system is responsible for configuring
- the MPC8240 including Embedded Utilities Memory
- Block. Since the DMA controller on MPC8240 can
- be accessed by either local 603e core or the host
- that MPC8240 serves as I/O processor through host
- PCI configuration, it is important that the local
- processor uses EUMBBAR to access its local DMA
- controller while the PCI master uses I/O
- processor's PCSRBAR to access the DMA controller
- on I/O device.
-
- To qualify whether is EUMBBAR or PCSRBAR, one
- additional parameter is requied from the host
- system, LOCAL or REMOTE so that the base value
- can be correctly interpreted.
-
-3. If the host system is also using the EPIC unit
- on MPC8240, the system can register the
- DMA_ISR with the EPIC including other
- desired resources.
-
- If the host system does not using the EPIC unit
- on MPC8240, DMA_ISR function can be called for
- each desired time interval.
-
- In both cases, the host system is free to
- provide its own interrupt service routine.
-
-4. To start a direct mode DMA transaction,
- use DMA_Bld_Curr with the start parameter
- set to 1.
-
- To start a chaining mode DMA transaction,
- the application shall build descriptors
- in memory first, next, use DMA_Bld_Desp
- with the start parameter set to 1.
-
-5. DMA_Start function clears, then sets the CS
- bit of DMA mode register.
-
- DMA_Halt function clears the CS bit of DMA
- mode register.
-
- These functions can be used to start and
- halt the DMA transaction.
-
- If the chaining descriptors has been
- modified since the last time a DMA
- transaction started, use DMA_Chn_Cnt
- function to let DMA controller process
- the modified descriptor chain without
- stopping or disturbing the current DMA
- transaction.
-
- It is the host system's responsibility of
- setting up the correct DMA transfer mode
- and pass the correct memory address parameters.
-
-6. It is the host system's responsibility of
- queueing the DMA I/O request. The host
- system can call the DMA_ISR with its own
- desired interrupt service subroutines to
- handle each individual interrupt and queued
- DMA I/O requests.
-
-7. The DMA driver routines contains a set
- of utilities, Set and Get, for host system
- to query and modify the desired DMA registers.
diff --git a/cpu/mpc824x/drivers/dma/dma.h b/cpu/mpc824x/drivers/dma/dma.h
deleted file mode 100644
index a21be74..0000000
--- a/cpu/mpc824x/drivers/dma/dma.h
+++ /dev/null
@@ -1,326 +0,0 @@
-#ifndef DMA_H
-#define DMA_H
-/*******************************************************
- *
- * copyright @ Motorola 1999
- *
- *******************************************************/
-#define NUM_DMA_REG 7
-#define DMA_MR_REG 0
-#define DMA_SR_REG 1
-#define DMA_CDAR_REG 2
-#define DMA_SAR_REG 3
-#define DMA_DAR_REG 4
-#define DMA_BCR_REG 5
-#define DMA_NDAR_REG 6
-
-typedef enum _dmastatus
-{
- DMASUCCESS = 0x1000,
- DMALMERROR,
- DMAPERROR,
- DMACHNBUSY,
- DMAEOSINT,
- DMAEOCAINT,
- DMAINVALID,
- DMANOEVENT,
-} DMAStatus;
-
-typedef enum _location
-{
- LOCAL = 0, /* local processor accesses on board DMA,
- local processor's eumbbar is required */
- REMOTE = 1, /* PCI master accesses DMA on I/O board,
- I/O processor's pcsrbar is required */
-} LOCATION;
-
-typedef enum dma_mr_bit
-{
- IRQS = 0x00080000,
- PDE = 0x00040000,
- DAHTS = 0x00030000,
- SAHTS = 0x0000c000,
- DAHE = 0x00002000,
- SAHE = 0x00001000,
- PRC = 0x00000c00,
- EIE = 0x00000080,
- EOTIE = 0x00000040,
- DL = 0x00000008,
- CTM = 0x00000004,
- CC = 0x00000002,
- CS = 0x00000001,
-} DMA_MR_BIT;
-
-typedef enum dma_sr_bit
-{
- LME = 0x00000080,
- PE = 0x00000010,
- CB = 0x00000004,
- EOSI = 0x00000002,
- EOCAI = 0x00000001,
-} DMA_SR_BIT;
-
-/* structure for DMA Mode Register */
-typedef struct _dma_mr
-{
- unsigned int reserved0 : 12;
- unsigned int irqs : 1;
- unsigned int pde : 1;
- unsigned int dahts : 2;
- unsigned int sahts : 2;
- unsigned int dahe : 1;
- unsigned int sahe : 1;
- unsigned int prc : 2;
- unsigned int reserved1 : 1;
- unsigned int eie : 1;
- unsigned int eotie : 1;
- unsigned int reserved2 : 3;
- unsigned int dl : 1;
- unsigned int ctm : 1;
- /* if chaining mode is enabled, any time, user can modify the
- * descriptor and does not need to halt the current DMA transaction.
- * Set CC bit, enable DMA to process the modified descriptors
- * Hardware will clear this bit each time, DMA starts.
- */
- unsigned int cc : 1;
- /* cs bit has dua role, halt the current DMA transaction and
- * (re)start DMA transaction. In chaining mode, if the descriptor
- * needs modification, cs bit shall be used not the cc bit.
- * Hardware will not set/clear this bit each time DMA transaction
- * stops or starts. Software shall do it.
- *
- * cs bit shall not be used to halt chaining DMA transaction for
- * modifying the descriptor. That is the role of CC bit.
- */
- unsigned int cs : 1;
-} DMA_MR;
-
-/* structure for DMA Status register */
-typedef struct _dma_sr
-{
- unsigned int reserved0 : 24;
- unsigned int lme : 1;
- unsigned int reserved1 : 2;
- unsigned int pe : 1;
- unsigned int reserved2 : 1;
- unsigned int cb : 1;
- unsigned int eosi : 1;
- unsigned int eocai : 1;
-} DMA_SR;
-
-/* structure for DMA current descriptor address register */
-typedef struct _dma_cdar
-{
- unsigned int cda : 27;
- unsigned int snen : 1;
- unsigned int eosie : 1;
- unsigned int ctt : 2;
- unsigned int eotd : 1;
-} DMA_CDAR;
-
-/* structure for DMA byte count register */
-typedef struct _dma_bcr
-{
- unsigned int reserved : 6;
- unsigned int bcr : 26;
-} DMA_BCR;
-
-/* structure for DMA Next Descriptor Address register */
-typedef struct _dma_ndar
-{
- unsigned int nda : 27;
- unsigned int ndsnen : 1;
- unsigned int ndeosie: 1;
- unsigned int ndctt : 2;
- unsigned int eotd : 1;
-} DMA_NDAR;
-
-/* structure for DMA current transaction info */
-typedef struct _dma_curr
-{
- unsigned int src_addr;
- unsigned int dest_addr;
- unsigned int byte_cnt;
-} DMA_CURR;
-
-/************************* Kernel API********************
- * Kernel APIs are used to interface with O.S. kernel.
- * They are the functions required by O.S. kernel to
- * provide I/O service.
- ********************************************************/
-
-/**************DMA Device Control Functions ********/
-
-/**
- * Note:
- *
- * In all following functions, the host (KAHLUA) processor has a
- * choice of accessing on board local DMA (LOCAL),
- * or DMA on a distributed KAHLUA (REMOTE). In either case,
- * the caller shall pass the configured embedded utility memory
- * block base address relative to the DMA. If LOCAL DMA is used,
- * this parameter shall be EUMBBAR, if REMOTE is used, the
- * parameter shall be the corresponding PCSRBAR.
- **/
-
-/**************************************************************
- * function: DMA_Get_Stat
- *
- * description: return the content of status register of
- * the given DMA channel
- * if error, return DMAINVALID. Otherwise return
- * DMASUCCESS.
- *
- **************************************************************/
-static DMAStatus DMA_Get_Stat( LOCATION, unsigned int eumbbar, unsigned int channel, DMA_SR * );
-
-/**************************************************************
- * function: DMA_Get_Mode
- *
- * description: return the content of mode register of the
- * given DMA channel
- * if error, return DMAINVALID. Otherwise return DMASUCCESS.
- *
- **************************************************************/
-static DMAStatus DMA_Get_Mode( LOCATION, unsigned int eumbbar, unsigned int channel, DMA_MR * );
-
-/**************************************************************
- * function: DMA_Set_Mode
- *
- * description: Set a new mode to a given DMA channel
- * return DMASUCCESS if success, otherwise return DMACHNINVALID
- *
- * note: It is not a good idea of changing the DMA mode during
- * the middle of a transaction.
- **************************************************************/
-static DMAStatus DMA_Set_Mode( LOCATION, unsigned int eumbbar, unsigned int channel, DMA_MR mode );
-
-/*************************************************************
- * function: DMA_ISR
- *
- * description: DMA interrupt service routine
- * return DMAStatus based on the status
- *
- *************************************************************/
-static DMAStatus DMA_ISR( unsigned int eumbbar,
- unsigned int channel,
- DMAStatus (*lme_func)( unsigned int, unsigned int, DMAStatus ),
- DMAStatus (*pe_func) ( unsigned int, unsigned int, DMAStatus ),
- DMAStatus (*eosi_func)( unsigned int, unsigned int, DMAStatus ),
- DMAStatus (*eocai_func)(unsigned int, unsigned int, DMAStatus ));
-
-static DMAStatus dma_error_func( unsigned int, unsigned int, DMAStatus );
-
-/********************* DMA I/O function ********************/
-
-/************************************************************
- * function: DMA_Start
- *
- * description: start a given DMA channel transaction
- * return DMASUCCESS if success, otherwise return DMACHNINVALID
- *
- * note: this function will clear DMA_MR(CC) first, then
- * set DMA_MR(CC).
- ***********************************************************/
-static DMAStatus DMA_Start( LOCATION, unsigned int eumbbar,unsigned int channel );
-
-/***********************************************************
- * function: DMA_Halt
- *
- * description: halt the current dma transaction on the specified
- * channel.
- * return DMASUCCESS if success, otherwise return DMACHNINVALID
- *
- * note: if the specified DMA channel is idle, nothing happens
- *************************************************************/
-static DMAStatus DMA_Halt( LOCATION, unsigned int eumbbar,unsigned int channel );
-
-/*************************************************************
- * function: DMA_Chn_Cnt
- *
- * description: set the DMA_MR(CC) bit for a given channel
- * that is in chaining mode.
- * return DMASUCCESS if successfule, otherwise return DMACHNINVALID
- *
- * note: if the given channel is not in chaining mode, nothing
- * happen.
- *
- *************************************************************/
-static DMAStatus DMA_Chn_Cnt( LOCATION, unsigned int eumbbar,unsigned int channel );
-
-/*********************** App. API ***************************
- * App. API are the APIs Kernel provides for the application
- * level program
- ************************************************************/
-/**************************************************************
- * function: DMA_Bld_Curr
- *
- * description: set current src, dest, byte count registers
- * according to the desp for a given channel
- *
- * if the given channel is busy, no change made,
- * return DMACHNBUSY.
- *
- * otherwise return DMASUCCESS.
- *
- * note:
- **************************************************************/
-static DMAStatus DMA_Bld_Curr( LOCATION,
- unsigned int eumbbar,
- unsigned int channel,
- DMA_CURR desp );
-
-/**************************************************************
- * function: DMA_Poke_Curr
- *
- * description: poke the current src, dest, byte count registers
- * for a given channel.
- *
- * return DMASUCCESS if no error otherwise return DMACHNERROR
- *
- * note: Due to the undeterministic parallelism, in chaining
- * mode, the value returned by this function shall
- * be taken as reference when the query is made rather
- * than the absolute snapshot when the value is returned.
- **************************************************************/
-static DMAStatus DMA_Poke_Curr( LOCATION,
- unsigned int eumbbar,
- unsigned int channel,
- DMA_CURR* desp );
-
-/**************************************************************
- * function: DMA_Bld_Desp
- *
- * description: set current descriptor address register
- * according to the desp for a given channel
- *
- * if the given channel is busy return DMACHNBUSY
- * and no change made, otherwise return DMASUCCESS.
- *
- * note:
- **************************************************************/
-static DMAStatus DMA_Bld_Desp( LOCATION host,
- unsigned int eumbbar,
- unsigned int channel,
- DMA_CDAR desp );
-
-/**************************************************************
- * function: DMA_Poke_Desp
- *
- * description: poke the current descriptor address register
- * for a given channel
- *
- * return DMASUCCESS if no error otherwise return
- * DMAINVALID
- *
- * note: Due to the undeterministic parallellism of DMA operation,
- * the value returned by this function shall be taken as
- * the most recently used descriptor when the last time
- * DMA starts a chaining mode operation.
- **************************************************************/
-static DMAStatus DMA_Poke_Desp( LOCATION,
- unsigned int eumbbar,
- unsigned int channel,
- DMA_CDAR *desp );
-
-#endif
diff --git a/cpu/mpc824x/drivers/dma/dma1.c b/cpu/mpc824x/drivers/dma/dma1.c
deleted file mode 100644
index 9c85267..0000000
--- a/cpu/mpc824x/drivers/dma/dma1.c
+++ /dev/null
@@ -1,801 +0,0 @@
-/************************************************************
- *
- * copyright @ Motorola, 1999
- *
- * App. API
- *
- * App. API are the APIs Kernel provides for the application
- * level program
- *
- ************************************************************/
-#include "dma_export.h"
-#include "dma.h"
-
-/* Define a macro to use an optional application-layer print function, if
- * one was passed to the library during initialization. If there was no
- * function pointer passed, this protects against referencing a NULL pointer.
- * Also define The global variable that holds the passed pointer.
- */
-#define PRINT if ( app_print ) app_print
-static int (*app_print)(char *,...);
-
-/* Set by call to get_eumbbar during DMA_Initialize.
- * This could be globally available to the library, but there is
- * an advantage to passing it as a parameter: it is already in a register
- * and doesn't have to be loaded from memory. Also, that is the way the
- * library was already implemented and I don't want to change it without
- * a more detailed analysis.
- * It is being set as a global variable during initialization to hide it from
- * the DINK application layer, because it is Kahlua-specific. I think that
- * get_eumbbar, load_runtime_reg, and store_runtime_reg should be defined in
- * a Kahlua-specific library dealing with the embedded utilities memory block.
- * Right now, get_eumbbar is defined in dink32/kahlua.s. The other two are
- * defined in dink32/drivers/i2c/i2c2.s, drivers/dma/dma2.s, etc.
- */
-static unsigned int Global_eumbbar = 0;
-extern unsigned int get_eumbbar();
-
-
-extern unsigned int load_runtime_reg( unsigned int eumbbar, unsigned int reg );
-#pragma Alias( load_runtime_reg, "load_runtime_reg" );
-
-extern void store_runtime_reg( unsigned int eumbbar, unsigned int reg, unsigned int val );
-#pragma Alias( store_runtime_reg, "store_runtime_reg" );
-
-unsigned int dma_reg_tb[][14] = {
- /* local DMA registers */
- {
- /* DMA_0_MR */ 0x00001100,
- /* DMA_0_SR */ 0x00001104,
- /* DMA_0_CDAR */ 0x00001108,
- /* DMA_0_SAR */ 0x00001110,
- /* DMA_0_DAR */ 0x00001118,
- /* DMA_0_BCR */ 0x00001120,
- /* DMA_0_NDAR */ 0x00001124,
- /* DMA_1_MR */ 0x00001200,
- /* DMA_1_SR */ 0x00001204,
- /* DMA_1_CDAR */ 0x00001208,
- /* DMA_1_SAR */ 0x00001210,
- /* DMA_1_DAR */ 0x00001218,
- /* DMA_1_BCR */ 0x00001220,
- /* DMA_1_NDAR */ 0x00001224,
- },
- /* remote DMA registers */
- {
- /* DMA_0_MR */ 0x00000100,
- /* DMA_0_SR */ 0x00000104,
- /* DMA_0_CDAR */ 0x00000108,
- /* DMA_0_SAR */ 0x00000110,
- /* DMA_0_DAR */ 0x00000118,
- /* DMA_0_BCR */ 0x00000120,
- /* DMA_0_NDAR */ 0x00000124,
- /* DMA_1_MR */ 0x00000200,
- /* DMA_1_SR */ 0x00000204,
- /* DMA_1_CDAR */ 0x00000208,
- /* DMA_1_SAR */ 0x00000210,
- /* DMA_1_DAR */ 0x00000218,
- /* DMA_1_BCR */ 0x00000220,
- /* DMA_1_NDAR */ 0x00000224,
- },
-};
-
-/* API functions */
-
-/* Initialize DMA unit with the following:
- * optional pointer to application layer print function
- *
- * These parameters may be added:
- * ???
- * Interrupt enables, modes, etc. are set for each transfer.
- *
- * This function must be called before DMA unit can be used.
- */
-extern
-DMA_Status DMA_Initialize( int (*p)(char *,...))
-{
- DMAStatus status;
- /* establish the pointer, if there is one, to the application's "printf" */
- app_print = p;
-
- /* If this is the first call, get the embedded utilities memory block
- * base address. I'm not sure what to do about error handling here:
- * if a non-zero value is returned, accept it.
- */
- if ( Global_eumbbar == 0)
- Global_eumbbar = get_eumbbar();
- if ( Global_eumbbar == 0)
- {
- PRINT( "DMA_Initialize: can't find EUMBBAR\n" );
- return DMA_ERROR;
- }
-
- return DMA_SUCCESS;
-}
-
-
-/* Perform the DMA transfer, only direct mode is currently implemented.
- * At this point, I think it would be better to define a different
- * function for chaining mode.
- * Also, I'm not sure if it is appropriate to have the "generic" API
- * accept snoop and int_steer parameters. The DINK user interface allows
- * them, so for now I'll leave them.
- *
- * int_steer controls DMA interrupt steering to PCI or local processor
- * type is the type of transfer: M2M, M2P, P2M, P2P
- * source is the source address of the data
- * dest is the destination address of the data
- * len is the length of data to transfer
- * channel is the DMA channel to use for the transfer
- * snoop is the snoop enable control
- */
-extern DMA_Status DMA_direct_transfer( DMA_INTERRUPT_STEER int_steer,
- DMA_TRANSFER_TYPE type,
- unsigned int source,
- unsigned int dest,
- unsigned int len,
- DMA_CHANNEL channel,
- DMA_SNOOP_MODE snoop)
-{
- DMA_MR md;
- DMA_CDAR cdar;
- /* it's inappropriate for curr to be a struct, but I'll leave it */
- DMA_CURR curr;
-
- DMAStatus stat;
-
- /* The rest of this code was moved from device.c test_dma to here.
- * It needs to be cleaned up and validated, but at least it is removed
- * from the application and API. Most of the mode is left hard coded.
- * This should be changed after the final API is defined and the user
- * application has a way to control the transfer.
- *
- */
-
- if ( DMA_Get_Mode( LOCAL, Global_eumbbar, channel, &md ) != DMASUCCESS )
- {
- return DMA_ERROR;
- }
-
- md.irqs = int_steer;
- md.pde = 0;
- md.dahts = 3; /* 8 - byte */
- md.sahts = 3; /* 8 - byte */
- md.dahe = 0;
- md.sahe = 0;
- md.prc = 0;
- /* if steering interrupts to local processor, use polling mode */
- if ( int_steer == DMA_INT_STEER_PCI )
- {
- md.eie = 1;
- md.eotie = 1;
- } else {
- md.eie = 0;
- md.eotie = 0;
- }
- md.dl = 0;
- md.ctm = 1; /* direct mode */
- md.cc = 0;
-
- /* validate the length range */
- if (len > 0x3ffffff )
- {
- PRINT( "dev DMA: length of transfer too large: %d\n", len );
- return DMA_ERROR;
- }
-
- /* inappropriate to use a struct, but leave as is for now */
- curr.src_addr = source;
- curr.dest_addr = dest;
- curr.byte_cnt = len;
-
- (void)DMA_Poke_Desp( LOCAL, Global_eumbbar, channel, &cdar );
- cdar.snen = snoop;
- cdar.ctt = type;
-
- if ( ( stat = DMA_Bld_Desp( LOCAL, Global_eumbbar, channel, cdar ))
- != DMASUCCESS ||
- ( stat = DMA_Bld_Curr( LOCAL, Global_eumbbar, channel, curr ))
- != DMASUCCESS ||
- ( stat = DMA_Set_Mode( LOCAL, Global_eumbbar, channel, md ))
- != DMASUCCESS ||
- ( stat = DMA_Start( LOCAL, Global_eumbbar, channel ))
- != DMASUCCESS )
- {
- if ( stat == DMACHNBUSY )
- {
- PRINT( "dev DMA: channel %d busy.\n", channel );
- }
- else
- {
- PRINT( "dev DMA: invalid channel request.\n", channel );
- }
-
- return DMA_ERROR;
- }
-
-/* Since we are interested at the DMA performace right now,
- we are going to do as less as possible to burden the
- 603e core.
-
- if you have epic enabled or don't care the return from
- DMA operation, you can just return SUCCESS.
-
- if you don't have epic enabled and care the DMA result,
- you can use the polling method below.
-
- Note: I'll attempt to activate the code for handling polling.
- */
-
-#if 0
- /* if steering interrupt to local processor, let it handle results */
- if ( int_steer == DMA_INT_STEER_LOCAL )
- {
- return DMA_SUCCESS;
- }
-
- /* polling since interrupt goes to PCI */
- do
- {
- stat = DMA_ISR( Global_eumbbar, channel, dma_error_func,
- dma_error_func, dma_error_func, dma_error_func );
- }
- while ( stat == DMANOEVENT );
-#endif
-
- return DMA_SUCCESS;
-}
-
-/* DMA library internal functions */
-
-/**
- * Note:
- *
- * In all following functions, the host (KAHLUA) processor has a
- * choice of accessing on board local DMA (LOCAL),
- * or DMA on a distributed KAHLUA (REMOTE). In either case,
- * the caller shall pass the configured embedded utility memory
- * block base address relative to the DMA. If LOCAL DMA is used,
- * this parameter shall be EUMBBAR, if REMOTE is used, the
- * parameter shall be the corresponding PCSRBAR.
- **/
-
-/**************************************************************
- * function: DMA_Get_Stat
- *
- * description: return the content of status register of
- * the given DMA channel
- *
- * if error, reserved0 field all 1s.
- **************************************************************/
-static
-DMAStatus DMA_Get_Stat( LOCATION host, unsigned int eumbbar, unsigned int channel, DMA_SR *stat )
-{
- unsigned int tmp;
-
- if ( channel != 0 && channel != 1 || stat == 0 )
- {
- return DMAINVALID;
- }
-
- tmp = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SR_REG] );
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) stat = 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SR_REG], tmp );
-#endif
-
- stat->reserved0 = ( tmp & 0xffffff00 ) >> 8;
- stat->lme = ( tmp & 0x00000080 ) >> 7;
- stat->reserved1 = ( tmp & 0x00000060 ) >> 5;
- stat->pe = ( tmp & 0x00000010 ) >> 4;
- stat->reserved2 = ( tmp & 0x00000008 ) >> 3;
- stat->cb = ( tmp & 0x00000004 ) >> 2;
- stat->eosi = ( tmp & 0x00000002 ) >> 1;
- stat->eocai = ( tmp & 0x00000001 );
-
- return DMASUCCESS;
-}
-
-/**************************************************************
- * function: DMA_Get_Mode
- *
- * description: return the content of mode register of the
- * given DMA channel
- *
- * if error, return DMAINVALID, otherwise return
- * DMASUCCESS
- **************************************************************/
-static
-DMAStatus DMA_Get_Mode( LOCATION host, unsigned eumbbar, unsigned int channel, DMA_MR *mode )
-{
- unsigned int tmp;
- if ( channel != 0 && channel != 1 || mode == 0 )
- {
- return DMAINVALID;
- }
-
- tmp = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_MR_REG] );
-
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) mode = 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_MR_REG], tmp );
-#endif
-
- mode->reserved0 = (tmp & 0xfff00000) >> 20;
- mode->irqs = (tmp & 0x00080000) >> 19;
- mode->pde = (tmp & 0x00040000) >> 18;
- mode->dahts = (tmp & 0x00030000) >> 16;
- mode->sahts = (tmp & 0x0000c000) >> 14;
- mode->dahe = (tmp & 0x00002000) >> 13;
- mode->sahe = (tmp & 0x00001000) >> 12;
- mode->prc = (tmp & 0x00000c00) >> 10;
- mode->reserved1 = (tmp & 0x00000200) >> 9;
- mode->eie = (tmp & 0x00000100) >> 8;
- mode->eotie = (tmp & 0x00000080) >> 7;
- mode->reserved2 = (tmp & 0x00000070) >> 4;
- mode->dl = (tmp & 0x00000008) >> 3;
- mode->ctm = (tmp & 0x00000004) >> 2;
- mode->cc = (tmp & 0x00000002) >> 1;
- mode->cs = (tmp & 0x00000001);
-
- return DMASUCCESS;
-}
-
-/**************************************************************
- * function: DMA_Set_Mode
- *
- * description: Set a new mode to a given DMA channel
- *
- * note: It is not a good idea of changing the DMA mode during
- * the middle of a transaction.
- **************************************************************/
-static
-DMAStatus DMA_Set_Mode( LOCATION host, unsigned eumbbar, unsigned int channel, DMA_MR mode )
-{
- unsigned int tmp;
- if ( channel != 0 && channel != 1 )
- {
- return DMAINVALID;
- }
-
- tmp = ( mode.reserved0 & 0xfff ) << 20;
- tmp |= ( ( mode.irqs & 0x1 ) << 19);
- tmp |= ( ( mode.pde & 0x1 ) << 18 );
- tmp |= ( ( mode.dahts & 0x3 ) << 16 );
- tmp |= ( ( mode.sahts & 0x3 ) << 14 );
- tmp |= ( ( mode.dahe & 0x1 ) << 13 );
- tmp |= ( ( mode.sahe & 0x1 ) << 12 );
- tmp |= ( ( mode.prc & 0x3 ) << 10 );
- tmp |= ( ( mode.reserved1 & 0x1 ) << 9 );
- tmp |= ( ( mode.eie & 0x1 ) << 8 );
- tmp |= ( ( mode.eotie & 0x1 ) << 7 );
- tmp |= ( ( mode.reserved2 & 0x7 ) << 4 );
- tmp |= ( ( mode.dl & 0x1 ) << 3 );
- tmp |= ( ( mode.ctm & 0x1 ) << 2 );
- tmp |= ( ( mode.cc & 0x1 ) << 1 ) ;
- tmp |= ( mode.cs & 0x1 );
-
- store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], tmp );
- return DMASUCCESS;
-}
-
-/************************************************************
- * function: DMA_Start
- *
- * description: start a given DMA channel transaction
- * return DMASUCCESS if success otherwise return
- * DMAStatus value
- *
- * note: this function will clear DMA_MR(CC) first, then
- * set DMA_MR(CC).
- ***********************************************************/
-static
-DMAStatus DMA_Start( LOCATION host, unsigned int eumbbar, unsigned int channel )
-{
- DMA_SR stat;
- unsigned int mode;
-
- if ( channel != 0 && channel != 1 )
- {
- return DMAINVALID;
- }
-
- if ( DMA_Get_Stat( host, eumbbar, channel, &stat ) != DMASUCCESS )
- {
- return DMAINVALID;
- }
-
- if ( stat.cb == 1 )
- {
- /* DMA is not free */
- return DMACHNBUSY;
- }
-
- mode = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG] );
- /* clear DMA_MR(CS) */
- mode &= 0xfffffffe;
- store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );
-
- /* set DMA_MR(CS) */
- mode |= CS;
- store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );
- return DMASUCCESS;
-}
-
-/***********************************************************
- * function: DMA_Halt
- *
- * description: halt the current dma transaction on the specified
- * channel.
- * return DMASUCCESS if success otherwise return DMAINVALID
- *
- * note: if the specified DMA channel is idle, nothing happens
- *************************************************************/
-static
-DMAStatus DMA_Halt( LOCATION host, unsigned int eumbbar, unsigned int channel )
-{
- unsigned int mode;
- if ( channel != 0 && channel != 1 )
- {
- return DMAINVALID;
- }
-
- mode = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG]);
-
- /* clear DMA_MR(CS) */
- mode &= 0xfffffffe;
- store_runtime_reg(eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );
- return DMASUCCESS;
-}
-
-/*************************************************************
- * function: DMA_Chn_Cnt
- *
- * description: set the DMA_MR(CC) bit for a given channel
- * that is in chaining mode.
- * return DMASUCCESS if successfule, otherwise return
- * DMAINVALID.
- *
- * note: if the given channel is not in chaining mode, nothing
- * happen.
- *
- *************************************************************/
-static
-DMAStatus DMA_Chn_Cnt( LOCATION host, unsigned int eumbbar, unsigned int channel )
-{
- DMA_MR mode;
- if ( channel != 0 && channel != 1 )
- {
- return DMAINVALID;
- }
-
- if ( DMA_Get_Mode( host, eumbbar, channel, &mode ) != DMASUCCESS )
- {
- return DMAINVALID;
- }
-
- if ( mode.ctm == 0 )
- {
- /* either illegal mode or not chaining mode */
- return DMAINVALID;
- }
-
- mode.cc = 1;
- return DMA_Set_Mode( host, eumbbar, channel, mode );
-}
-
-/**************************************************************
- * function: DMA_Bld_Desp
- *
- * description: set current descriptor address register
- * according to the desp for a given channel
- *
- * if the given channel is busy return DMACHNBUSY
- * and no change made, otherwise return DMASUCCESS.
- *
- * note:
- **************************************************************/
-static
-DMAStatus DMA_Bld_Desp( LOCATION host,
- unsigned int eumbbar,
- unsigned int channel,
- DMA_CDAR desp )
-{
- DMA_SR status;
- unsigned int temp;
-
- if ( channel != 0 && channel != 1 )
- {
- /* channel number out of range */
- return DMAINVALID;
- }
-
- if ( DMA_Get_Stat( host, eumbbar, channel, &status ) != DMASUCCESS )
- {
- return DMAINVALID;
- }
-
- if ( status.cb == 1 )
- {
- /* channel busy */
- return DMACHNBUSY;
- }
-
- temp = ( desp.cda & 0x7ffffff ) << 5;
- temp |= (( desp.snen & 0x1 ) << 4 );
- temp |= (( desp.eosie & 0x1 ) << 3 );
- temp |= (( desp.ctt & 0x3 ) << 1 );
- temp |= ( desp.eotd & 0x1 );
-
- store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], temp );
-
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) cdar := 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], temp );
-#endif
-
- return DMASUCCESS;
-}
-
-/**************************************************************
- * function: DMA_Poke_Desp
- *
- * description: poke the current descriptor address register
- * for a given channel
- *
- * return DMASUCCESS if no error
- *
- * note: Due to the undeterministic parallellism of DMA operation,
- * the value returned by this function shall be taken as
- * the most recently used descriptor when the last time
- * DMA starts a chaining mode operation.
- **************************************************************/
-static
-DMAStatus DMA_Poke_Desp( LOCATION host,
- unsigned int eumbbar,
- unsigned int channel,
- DMA_CDAR *desp )
-{
- unsigned int cdar;
- if ( channel != 0 && channel != 1 || desp == 0 )
- {
- return DMAINVALID;
- }
-
- cdar = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG] );
-
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) cdar : 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], cdar );
-#endif
-
-
- desp->cda = ( cdar & 0xffffffe0 ) >> 5;
- desp->snen = ( cdar & 0x00000010 ) >> 4;
- desp->eosie = ( cdar & 0x00000008 ) >> 3;
- desp->ctt = ( cdar & 0x00000006 ) >> 1;
- desp->eotd = ( cdar & 0x00000001 );
-
- return DMASUCCESS;
-}
-
-/**************************************************************
- * function: DMA_Bld_Curr
- *
- * description: set current src, dest, byte count registers
- * according to the desp for a given channel
- * return DMASUCCESS if no error.
- *
- * note:
- **************************************************************/
-static
-DMAStatus DMA_Bld_Curr( LOCATION host,
- unsigned int eumbbar,
- unsigned int channel,
- DMA_CURR desp )
-{
- DMA_SR status;
- if ( channel != 0 && channel != 1 )
- {
- /* channel number out of range */
- return DMAINVALID;
- }
-
- if ( DMA_Get_Stat( host, eumbbar, channel, &status ) != DMASUCCESS )
- {
- return DMAINVALID;
- }
-
- if ( status.cb == 1 )
- {
- /* channel busy */
- return DMACHNBUSY;
- }
-
- desp.byte_cnt &= 0x03ffffff; /* upper 6-bits are 0s */
-
- store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SAR_REG], desp.src_addr );
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) src := 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.src_addr );
-#endif
-
- store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_DAR_REG], desp.dest_addr );
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) dest := 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.dest_addr );
-#endif
-
- store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_BCR_REG], desp.byte_cnt );
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) count := 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.byte_cnt );
-#endif
-
-
- return DMASUCCESS;
-
-}
-
-/**************************************************************
- * function: DMA_Poke_Curr
- *
- * description: poke the current src, dest, byte count registers
- * for a given channel.
- *
- * return DMASUCCESS if no error
- *
- * note: Due to the undeterministic parallelism, in chaining
- * mode, the value returned by this function shall
- * be taken as reference when the query is made rather
- * than the absolute snapshot when the value is returned.
- **************************************************************/
-static
-DMAStatus DMA_Poke_Curr( LOCATION host,
- unsigned int eumbbar,
- unsigned int channel,
- DMA_CURR* desp )
-{
- if ( channel != 0 && channel != 1 || desp == 0 )
- {
- return DMAINVALID;
- }
-
- desp->src_addr = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SAR_REG] );
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) src : 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->src_addr );
-#endif
-
- desp->dest_addr = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_DAR_REG] );
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) dest : 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->dest_addr );
-#endif
-
- desp->byte_cnt = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_BCR_REG] );
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) count : 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->byte_cnt );
-#endif
-
-
- return DMASUCCESS;
-}
-
-/*****************************************************************
- * function: dma_error_func
- *
- * description: display the error information
- *
- * note: This seems like a highly convoluted way to handle messages,
- * but I'll leave it as it was in device.c when I moved it into the
- * DMA library source.
- ****************************************************************/
-static
-DMAStatus dma_error_func( unsigned int eumbbar, unsigned int chn, DMAStatus err)
-{
- unsigned char *msg[] =
- {
- "Local Memory Error",
- "PCI Error",
- "Channel Busy",
- "End-of-Segment Interrupt",
- "End-of-Chain/Direct Interrupt",
- };
-
- if ( err >= DMALMERROR && err <= DMAEOCAINT )
- {
- PRINT( "DMA Status: channel %d %s\n", chn, msg[err-DMASUCCESS-1] );
- }
-
- return err;
-
-}
-
-/*************************************************************
- * function: DMA_ISR
- *
- * description: DMA interrupt service routine
- * return DMAStatus value based on
- * the status
- *
- *************************************************************/
-static
-DMAStatus DMA_ISR( unsigned int eumbbar,
- unsigned int channel,
- DMAStatus (*lme_func)( unsigned int, unsigned int, DMAStatus ),
- DMAStatus (*pe_func) ( unsigned int, unsigned int, DMAStatus ),
- DMAStatus (*eosi_func)( unsigned int, unsigned int, DMAStatus ),
- DMAStatus (*eocai_func)(unsigned int, unsigned int, DMAStatus ))
-{
-
- DMA_SR stat;
- DMAStatus rval = DMANOEVENT;
- unsigned int temp;
-
- if ( channel != 0 && channel != 1 )
- {
- return DMAINVALID;
- }
-
- if ( DMA_Get_Stat( LOCAL, eumbbar, channel, &stat ) != DMASUCCESS )
- {
- return DMAINVALID;
- }
-
- if ( stat.lme == 1 )
- {
- /* local memory error */
- rval = DMALMERROR;
- if ( lme_func != 0 )
- {
- rval = (*lme_func)(eumbbar, channel, DMALMERROR );
- }
-
- }
- else if ( stat.pe == 1 )
- {
- /* PCI error */
- rval = DMAPERROR;
- if ( pe_func != 0 )
- {
- rval = (*pe_func)(eumbbar, channel, DMAPERROR );
- }
-
- }
- else if ( stat.eosi == 1 )
- {
- /* end-of-segment interrupt */
- rval = DMAEOSINT;
- if ( eosi_func != 0 )
- {
- rval = (*eosi_func)(eumbbar, channel, DMAEOSINT );
- }
- }
- else
- {
- /* End-of-chain/direct interrupt */
- rval = DMAEOCAINT;
- if ( eocai_func != 0 )
- {
- rval = (*eocai_func)(eumbbar, channel, DMAEOCAINT );
- }
- }
-
- temp = ( stat.reserved0 & 0xffffff ) << 8;
- temp |= ( ( stat.lme & 0x1 ) << 7 ); /* write one to clear */
- temp |= ( ( stat.reserved1 & 0x3 ) << 5 );
- temp |= ( ( stat.pe & 0x1 ) << 4 ); /* write one to clear */
- temp |= ( ( stat.reserved2 & 0x1 ) << 3 );
- temp |= ( ( stat.cb & 0x1 ) << 2 ); /* write one to clear */
- temp |= ( ( stat.eosi & 0x1 ) << 1 ); /* write one to clear */
- temp |= ( stat.eocai & 0x1 ); /* write one to clear */
-
- store_runtime_reg( eumbbar, dma_reg_tb[LOCAL][channel*NUM_DMA_REG + DMA_SR_REG], temp );
-
-#ifdef DMADBG0
- PRINT( "%s(%d): DMA channel %d SR := 0x%08x\n", __FILE__, __LINE__, channel, temp );
-#endif
-
- return rval;
-}
diff --git a/cpu/mpc824x/drivers/dma/dma2.S b/cpu/mpc824x/drivers/dma/dma2.S
deleted file mode 100644
index ccbc226..0000000
--- a/cpu/mpc824x/drivers/dma/dma2.S
+++ /dev/null
@@ -1,42 +0,0 @@
-/**************************************
- *
- * copyright @ Motorola, 1999
- *
- **************************************/
-
-/**********************************************************
- * function: load_runtime_reg
- *
- * input: r3 - value of eumbbar
- * r4 - register offset in embedded utility space
- *
- * output: r3 - register content
- **********************************************************/
- .text
- .align 2
- .global load_runtime_reg
-
-load_runtime_reg:
-
- lwbrx r3,r4,r3
- sync
-
- bclr 20, 0
-
-/****************************************************************
- * function: store_runtime_reg
- *
- * input: r3 - value of eumbbar
- * r4 - register offset in embedded utility space
- * r5 - new value to be stored
- *
- ****************************************************************/
- .text
- .align 2
- .global store_runtime_reg
-store_runtime_reg:
-
- stwbrx r5, r4, r3
- sync
-
- bclr 20,0
diff --git a/cpu/mpc824x/drivers/dma/dma_export.h b/cpu/mpc824x/drivers/dma/dma_export.h
deleted file mode 100644
index 471e488..0000000
--- a/cpu/mpc824x/drivers/dma/dma_export.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef DMA_EXPORT_H
-#define DMA_EXPORT_H
-
-/****************************************************
- * $Id:
- *
- * Copyright Motorola 1999
- *
- * $Log:
- *
- ****************************************************/
-
-/* These are the defined return values for the DMA_* functions.
- * Any non-zero value indicates failure. Failure modes can be added for
- * more detailed error reporting.
- */
-typedef enum _dma_status
-{
- DMA_SUCCESS = 0,
- DMA_ERROR,
-} DMA_Status;
-
-/* These are the defined channel transfer types. */
-typedef enum _dma_transfer_types
-{
- DMA_M2M = 0, /* local memory to local memory */
- DMA_M2P = 1, /* local memory to PCI */
- DMA_P2M = 2, /* PCI to local memory */
- DMA_P2P = 3, /* PCI to PCI */
-} DMA_TRANSFER_TYPE;
-
-typedef enum _dma_interrupt_steer
-{
- DMA_INT_STEER_LOCAL = 0, /* steer DMA int to local processor */
- DMA_INT_STEER_PCI = 1, /* steer DMA int to PCI bus through INTA_ */
-} DMA_INTERRUPT_STEER;
-
-typedef enum _dma_channel
-{
- DMA_CHN_0 = 0, /* kahlua has two dma channels: 0 and 1 */
- DMA_CHN_1 = 1,
-} DMA_CHANNEL;
-
-typedef enum _dma_snoop_mode
-{
- DMA_SNOOP_DISABLE = 0,
- DMA_SNOOP_ENABLE = 1,
-} DMA_SNOOP_MODE;
-
-/******************** App. API ********************
- * The application API is for user level application
- * to use the functionality provided by DMA driver.
- * This is a "generic" DMA interface, it should contain
- * nothing specific to the Kahlua implementation.
- * Only the generic functions are exported by the library.
- *
- * Note: Its App.s responsibility to swap the data
- * byte. In our API, we currently transfer whatever
- * we are given - Big/Little Endian. This could
- * become part of the DMA config, though.
- **************************************************/
-
-
-/* Initialize DMA unit with the following:
- * optional pointer to application layer print function
- *
- * These parameters may be added:
- * ???
- * Interrupt enables, modes, etc. are set for each transfer.
- *
- * This function must be called before DMA unit can be used.
- */
-extern DMA_Status DMA_Initialize(
- int (*app_print_function)(char *,...)); /* pointer to optional "printf"
- * provided by application
- */
-
-/* Perform the DMA transfer, only direct mode is currently implemented.
- * At this point, I think it would be better to define a different
- * function for chaining mode.
- * Also, I'm not sure if it is appropriate to have the "generic" API
- * accept snoop and int_steer parameters. The DINK user interface allows
- * them, so for now I'll leave them.
- *
- * int_steer controls DMA interrupt steering to PCI or local processor
- * type is the type of transfer: M2M, M2P, P2M, P2P
- * source is the source address of the data
- * dest is the destination address of the data
- * len is the length of data to transfer
- * channel is the DMA channel to use for the transfer
- * snoop is the snoop enable control
- */
-extern DMA_Status DMA_direct_transfer( DMA_INTERRUPT_STEER int_steer,
- DMA_TRANSFER_TYPE type,
- unsigned int source,
- unsigned int dest,
- unsigned int len,
- DMA_CHANNEL channel,
- DMA_SNOOP_MODE snoop);
-#endif
diff --git a/cpu/mpc824x/drivers/dma_export.h b/cpu/mpc824x/drivers/dma_export.h
deleted file mode 100644
index 471e488..0000000
--- a/cpu/mpc824x/drivers/dma_export.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef DMA_EXPORT_H
-#define DMA_EXPORT_H
-
-/****************************************************
- * $Id:
- *
- * Copyright Motorola 1999
- *
- * $Log:
- *
- ****************************************************/
-
-/* These are the defined return values for the DMA_* functions.
- * Any non-zero value indicates failure. Failure modes can be added for
- * more detailed error reporting.
- */
-typedef enum _dma_status
-{
- DMA_SUCCESS = 0,
- DMA_ERROR,
-} DMA_Status;
-
-/* These are the defined channel transfer types. */
-typedef enum _dma_transfer_types
-{
- DMA_M2M = 0, /* local memory to local memory */
- DMA_M2P = 1, /* local memory to PCI */
- DMA_P2M = 2, /* PCI to local memory */
- DMA_P2P = 3, /* PCI to PCI */
-} DMA_TRANSFER_TYPE;
-
-typedef enum _dma_interrupt_steer
-{
- DMA_INT_STEER_LOCAL = 0, /* steer DMA int to local processor */
- DMA_INT_STEER_PCI = 1, /* steer DMA int to PCI bus through INTA_ */
-} DMA_INTERRUPT_STEER;
-
-typedef enum _dma_channel
-{
- DMA_CHN_0 = 0, /* kahlua has two dma channels: 0 and 1 */
- DMA_CHN_1 = 1,
-} DMA_CHANNEL;
-
-typedef enum _dma_snoop_mode
-{
- DMA_SNOOP_DISABLE = 0,
- DMA_SNOOP_ENABLE = 1,
-} DMA_SNOOP_MODE;
-
-/******************** App. API ********************
- * The application API is for user level application
- * to use the functionality provided by DMA driver.
- * This is a "generic" DMA interface, it should contain
- * nothing specific to the Kahlua implementation.
- * Only the generic functions are exported by the library.
- *
- * Note: Its App.s responsibility to swap the data
- * byte. In our API, we currently transfer whatever
- * we are given - Big/Little Endian. This could
- * become part of the DMA config, though.
- **************************************************/
-
-
-/* Initialize DMA unit with the following:
- * optional pointer to application layer print function
- *
- * These parameters may be added:
- * ???
- * Interrupt enables, modes, etc. are set for each transfer.
- *
- * This function must be called before DMA unit can be used.
- */
-extern DMA_Status DMA_Initialize(
- int (*app_print_function)(char *,...)); /* pointer to optional "printf"
- * provided by application
- */
-
-/* Perform the DMA transfer, only direct mode is currently implemented.
- * At this point, I think it would be better to define a different
- * function for chaining mode.
- * Also, I'm not sure if it is appropriate to have the "generic" API
- * accept snoop and int_steer parameters. The DINK user interface allows
- * them, so for now I'll leave them.
- *
- * int_steer controls DMA interrupt steering to PCI or local processor
- * type is the type of transfer: M2M, M2P, P2M, P2P
- * source is the source address of the data
- * dest is the destination address of the data
- * len is the length of data to transfer
- * channel is the DMA channel to use for the transfer
- * snoop is the snoop enable control
- */
-extern DMA_Status DMA_direct_transfer( DMA_INTERRUPT_STEER int_steer,
- DMA_TRANSFER_TYPE type,
- unsigned int source,
- unsigned int dest,
- unsigned int len,
- DMA_CHANNEL channel,
- DMA_SNOOP_MODE snoop);
-#endif
diff --git a/cpu/mpc824x/drivers/i2o.h b/cpu/mpc824x/drivers/i2o.h
deleted file mode 100644
index c47253d..0000000
--- a/cpu/mpc824x/drivers/i2o.h
+++ /dev/null
@@ -1,344 +0,0 @@
-#ifndef I2O_H
-#define I2O_H
-/*********************************************************
- *
- * copyright @ Motorola, 1999
- *********************************************************/
-
-#define I2O_REG_OFFSET 0x0004
-
-#define PCI_CFG_CLA 0x0B
-#define PCI_CFG_SCL 0x0A
-#define PCI_CFG_PIC 0x09
-
-#define I2O_IMR0 0x0050
-#define I2O_IMR1 0x0054
-#define I2O_OMR0 0x0058
-#define I2O_OMR1 0x005C
-
-#define I2O_ODBR 0x0060
-#define I2O_IDBR 0x0068
-
-#define I2O_OMISR 0x0030
-#define I2O_OMIMR 0x0034
-#define I2O_IMISR 0x0100
-#define I2O_IMIMR 0x0104
-
-/* accessable to PCI master but local processor */
-#define I2O_IFQPR 0x0040
-#define I2O_OFQPR 0x0044
-
-/* accessable to local processor */
-#define I2O_IFHPR 0x0120
-#define I2O_IFTPR 0x0128
-#define I2O_IPHPR 0x0130
-#define I2O_IPTPR 0x0138
-#define I2O_OFHPR 0x0140
-#define I2O_OFTPR 0x0148
-#define I2O_OPHPR 0x0150
-#define I2O_OPTPR 0x0158
-#define I2O_MUCR 0x0164
-#define I2O_QBAR 0x0170
-
-#define I2O_NUM_MSG 2
-
-typedef enum _i2o_status
-{
- I2OSUCCESS = 0,
- I2OINVALID,
- I2OMSGINVALID,
- I2ODBINVALID,
- I2OQUEINVALID,
- I2OQUEEMPTY,
- I2OQUEFULL,
- I2ONOEVENT,
-} I2OSTATUS;
-
-typedef enum _queue_size
-{
- QSIZE_4K = 0x02,
- QSIZE_8K = 0x04,
- QSIZE_16K = 0x08,
- QSIZE_32K = 0x10,
- QSIZe_64K = 0x20,
-} QUEUE_SIZE;
-
-typedef enum _location
-{
- LOCAL = 0, /* used by local processor to access its own on board device,
- local processor's eumbbar is required */
- REMOTE, /* used by PCI master to access the devices on its PCI device,
- device's pcsrbar is required */
-} LOCATION;
-
-/* door bell */
-typedef enum _i2o_in_db
-{
- IN_DB = 1,
- MC, /* machine check */
-} I2O_IN_DB;
-
-/* I2O PCI configuration identification */
-typedef struct _i2o_iop
-{
- unsigned int base_class : 8;
- unsigned int sub_class : 8;
- unsigned int prg_code : 8;
-} I2OIOP;
-
-/* I2O Outbound Message Interrupt Status Register */
-typedef struct _i2o_om_stat
-{
- unsigned int rsvd0 : 26;
- unsigned int opqi : 1;
- unsigned int rsvd1 : 1;
- unsigned int odi : 1;
- unsigned int rsvd2 : 1;
- unsigned int om1i : 1;
- unsigned int om0i : 1;
-} I2OOMSTAT;
-
-/* I2O inbound Message Interrupt Status Register */
-typedef struct _i2o_im_stat
-{
- unsigned int rsvd0 : 23;
- unsigned int ofoi : 1;
- unsigned int ipoi : 1;
- unsigned int rsvd1 : 1;
- unsigned int ipqi : 1;
- unsigned int mci : 1;
- unsigned int idi : 1;
- unsigned int rsvd2 : 1;
- unsigned int im1i : 1;
- unsigned int im0i : 1;
-} I2OIMSTAT;
-
-/**
- Enable the interrupt associated with in/out bound msg
-
- Inbound message interrupt generated by PCI master and serviced by local processor
- local processor needs to enable its inbound interrupts it wants to handle (LOCAL)
-
- Outbound message interrupt generated by local processor and serviced by PCI master
- PCI master needs to enable the devices' outbound interrupts it wants to handle (REMOTE)
- **/
-extern I2OSTATUS I2OMsgEnable( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned char n ); /* b'1' - msg 0
- * b'10'- msg 1
- * b'11'- both
- */
-
-/**
- Disable the interrupt associated with in/out bound msg
-
- local processor needs to disable its inbound interrupts it is not interested (LOCAL)
-
- PCI master needs to disable outbound interrupts of devices it is not interested (REMOTE)
- **/
-extern I2OSTATUS I2OMsgDisable( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned char n ); /* b'1' - msg 0
- * b'10'- msg 1
- * b'11'- both
- */
-
-/**
- Read the msg register either from local inbound msg 0/1,
- or an outbound msg 0/1 of devices.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, outbound msg of the device is read.
- Otherwise local inbound msg is read.
- **/
-extern I2OSTATUS I2OMsgGet ( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /*pcsrbar/eumbbar */
- unsigned int n, /* 0 or 1 */
- unsigned int *msg );
-
-/**
- Write to nth Msg register either on local outbound msg 0/1,
- or aninbound msg 0/1 of devices
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, inbound msg on the device is written.
- Otherwise local outbound msg is written.
- **/
-extern I2OSTATUS I2OMsgPost( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /*pcsrbar/eumbbar */
- unsigned int n, /* 0 or 1 */
- unsigned int msg );
-
-/**
- Enable the In/Out DoorBell Interrupt
-
- InDoorBell interrupt is generated by PCI master and serviced by local processor
- local processor needs to enable its inbound doorbell interrupts it wants to handle
-
- OutDoorbell interrupt is generated by local processor and serviced by PCI master
- PCI master needs to enable outbound doorbell interrupts of the devices it wants to handle
- **/
-extern I2OSTATUS I2ODBEnable( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int in_db );/* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-
-/**
- Disable the In/Out DoorBell Interrupt
-
- local processor needs to disable its inbound doorbell interrupts it is not interested
-
- PCI master needs to disable outbound doorbell interrupts of devices it is not interested
-
- **/
-extern I2OSTATUS I2ODBDisable( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int in_db ); /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-
-/**
- Read a local indoorbell register, or an outdoorbell of devices.
- Reading a doorbell register, the register will be cleared.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, outdoorbell register on the device is read.
- Otherwise local in doorbell is read
- **/
-extern unsigned int I2ODBGet( LOCATION, /* REMOTE/LOCAL */
- unsigned int base); /* pcsrbar/eumbbar */
-
-/**
- Write to a local outdoorbell register, or an indoorbell register of devices.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, in doorbell register on the device is written.
- Otherwise local out doorbell is written
- **/
-extern void I2ODBPost( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int msg ); /* in / out */
-
-/**
- Read the outbound msg unit interrupt status of devices. Reading an interrupt status register,
- the register will be cleared.
-
- The outbound interrupt status is AND with the outbound
- interrupt mask. The result is returned.
-
- PCI master must pass the pcsrbar to the function.
- **/
-extern I2OSTATUS I2OOutMsgStatGet( unsigned int pcsrbar, I2OOMSTAT * );
-
-/**
- Read the inbound msg unit interrupt status. Reading an interrupt status register,
- the register will be cleared.
-
- The inbound interrupt status is AND with the inbound
- interrupt mask. The result is returned.
-
- Local process must pass its eumbbar to the function.
-**/
-extern I2OSTATUS I2OInMsgStatGet( unsigned int eumbbar, I2OIMSTAT * );
-
-/**
- Configure the I2O FIFO, including QBAR, IFHPR/IFTPR,IPHPR/IPTPR,OFHPR/OFTPR, OPHPR/OPTPR,
- MUCR.
- **/
-extern I2OSTATUS I2OFIFOInit( unsigned int eumbbar,
- QUEUE_SIZE,
- unsigned int qba);/* queue base address that must be aligned at 1M */
-/**
- Enable the circular queue
- **/
-extern I2OSTATUS I2OFIFOEnable( unsigned int eumbbar );
-
-/**
- Disable the circular queue
- **/
-extern void I2OFIFODisable( unsigned int eumbbar );
-
-/**
- Enable the circular queue interrupt
- PCI master enables outbound FIFO interrupt of device
- Device enables its inbound FIFO interrupt
- **/
-extern void I2OFIFOIntEnable( LOCATION, unsigned int base );
-
-/**
- Disable the circular queue interrupt
- PCI master disables outbound FIFO interrupt of device
- Device disables its inbound FIFO interrupt
- **/
-extern void I2OFIFOIntDisable( LOCATION, unsigned int base );
-
-/**
- Enable the circular queue overflow interrupt
- **/
-extern void I2OFIFOOverflowIntEnable( unsigned int eumbbar );
-
-/**
- Disable the circular queue overflow interrupt
- **/
-extern void I2OFIFOOverflowIntDisable( unsigned int eumbbar );
-
-/**
- Allocate a free msg frame from free FIFO.
-
- PCI Master allocates a free msg frame through inbound queue port of device(IFQPR)
- while local processor allocates a free msg frame from outbound free queue(OFTPR)
-
- Unless both free queues are initialized, allocating a free MF will return 0xffffffff
- **/
-extern I2OSTATUS I2OFIFOAlloc( LOCATION,
- unsigned int base,
- void **pMsg);
-/**
- Free a used msg frame back to free queue
- PCI Master frees a MFA through outbound queue port of device(OFQPR)
- while local processor frees a MFA into its inbound free queue(IFHPR)
-
- Used msg frame does not need to be recycled in the order they
- read
-
- This function has to be called by PCI master to initialize Inbound free queue
- and by device to initialize Outbound free queue before I2OFIFOAlloc can be used.
- **/
-extern I2OSTATUS I2OFIFOFree( LOCATION,
- unsigned int base,
- void *pMsg );
-
-/**
- Post a msg into FIFO
- PCI Master posts a msg through inbound queue port of device(IFQPR)
- while local processor post a msg into its outbound post queue(OPHPR)
-
- The total number of msg must be less than the max size of the queue
- Otherwise queue overflow interrupt will assert.
- **/
-extern I2OSTATUS I2OFIFOPost( LOCATION,
- unsigned int base,
- void *pMsg );
-
-/**
- Read a msg from FIFO
- PCI Master reads a msg through outbound queue port of device(OFQPR)
- while local processor reads a msg from its inbound post queue(IPTPR)
- **/
-extern I2OSTATUS I2OFIFOGet( LOCATION,
- unsigned int base,
- void **pMsg );
-
-/**
- Get the I2O PCI configuration identification register
- **/
-extern I2OSTATUS I2OPCIConfigGet( LOCATION,
- unsigned int base,
- I2OIOP *);
-
-#endif
diff --git a/cpu/mpc824x/drivers/i2o/Makefile b/cpu/mpc824x/drivers/i2o/Makefile
deleted file mode 100644
index 3f5ca26..0000000
--- a/cpu/mpc824x/drivers/i2o/Makefile
+++ /dev/null
@@ -1,84 +0,0 @@
-##########################################################################
-#
-# Copyright Motorola, Inc. 1997
-# ALL RIGHTS RESERVED
-#
-# You are hereby granted a copyright license to use, modify, and
-# distribute the SOFTWARE so long as this entire notice is retained
-# without alteration in any modified and/or redistributed versions,
-# and that such modified versions are clearly identified as such.
-# No licenses are granted by implication, estoppel or otherwise under
-# any patents or trademarks of Motorola, Inc.
-#
-# The SOFTWARE is provided on an "AS IS" basis and without warranty.
-# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-# INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libi2o.a
-
-#DEBUG = -g
-DEBUG =
-LST = -Hanno -S
-OPTIM =
-CC = /risc/tools/pkgs/metaware/bin/hcppc
-CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT = -big_si -c
-ASDEBUG = -l -fm
-AS = /risc/tools/pkgs/metaware/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT = -Bbase=0 -Qn -q -r
-LKCMD =
-LINK = /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL = rm
-COPY = cp
-LIST = ls
-
-OBJECTS = i2o1.o i2o2.o
-
-all: $(TARGET)
-
-$(TARGET): $(OBJECTS)
- $(LINK) $(OBJECTS) -o $@
-
-objects: i2o1.o
-
-clean:
- $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
-# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
- $(CCobj) $<
-
-.c.s:
- $(CCobj) $(LST) $<
-
-i2o1.o: i2o.h i2o1.c
-
-i2o2.o: i2o.h i2o2.s
diff --git a/cpu/mpc824x/drivers/i2o/Makefile_pc b/cpu/mpc824x/drivers/i2o/Makefile_pc
deleted file mode 100644
index 6867f58..0000000
--- a/cpu/mpc824x/drivers/i2o/Makefile_pc
+++ /dev/null
@@ -1,90 +0,0 @@
-##########################################################################
-#
-# makefile_pc for use with PC mksnt tools dink32/drivers/i2o
-#
-# Copyright Motorola, Inc. 1997
-# ALL RIGHTS RESERVED
-#
-# You are hereby granted a copyright license to use, modify, and
-# distribute the SOFTWARE so long as this entire notice is retained
-# without alteration in any modified and/or redistributed versions,
-# and that such modified versions are clearly identified as such.
-# No licenses are granted by implication, estoppel or otherwise under
-# any patents or trademarks of Motorola, Inc.
-#
-# The SOFTWARE is provided on an "AS IS" basis and without warranty.
-# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-# INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libi2o.a
-
-#DEBUG = -g
-DEBUG =
-LST = -Hanno -S
-OPTIM =
-CC = m:/old_tools/tools/hcppc/bin/hcppc
-CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT = -big_si -c
-ASDEBUG = -l -fm
-AS = m:/old_tools/tools/hcppc/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT = -Bbase=0 -Qn -q -r
-LKCMD =
-LINK = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL = rm
-COPY = cp
-LIST = ls
-
-OBJECTS = i2o1.o i2o2.o
-
-all: $(TARGET)
-
-$(TARGET): $(OBJECTS)
- $(LINK) $(OBJECTS) -o $@
-
-objects: i2o1.o
-
-clean:
- $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
-# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
- $(CCobj) $<
-
-.c.s:
- $(CCobj) $(LST) $<
-
-i2o1.o: i2o.h i2o1.c
- $(CCobj) $<
-
-i2o2.o: i2o.h i2o2.s
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
diff --git a/cpu/mpc824x/drivers/i2o/i2o.h b/cpu/mpc824x/drivers/i2o/i2o.h
deleted file mode 100644
index 71572b2..0000000
--- a/cpu/mpc824x/drivers/i2o/i2o.h
+++ /dev/null
@@ -1,345 +0,0 @@
-#ifndef I2O_H
-#define I2O_H
-/*********************************************************
- *
- * copyright @ Motorola, 1999
- *
- *********************************************************/
-
-#define I2O_REG_OFFSET 0x0004
-
-#define PCI_CFG_CLA 0x0B
-#define PCI_CFG_SCL 0x0A
-#define PCI_CFG_PIC 0x09
-
-#define I2O_IMR0 0x0050
-#define I2O_IMR1 0x0054
-#define I2O_OMR0 0x0058
-#define I2O_OMR1 0x005C
-
-#define I2O_ODBR 0x0060
-#define I2O_IDBR 0x0068
-
-#define I2O_OMISR 0x0030
-#define I2O_OMIMR 0x0034
-#define I2O_IMISR 0x0100
-#define I2O_IMIMR 0x0104
-
-/* accessable to PCI master but local processor */
-#define I2O_IFQPR 0x0040
-#define I2O_OFQPR 0x0044
-
-/* accessable to local processor */
-#define I2O_IFHPR 0x0120
-#define I2O_IFTPR 0x0128
-#define I2O_IPHPR 0x0130
-#define I2O_IPTPR 0x0138
-#define I2O_OFHPR 0x0140
-#define I2O_OFTPR 0x0148
-#define I2O_OPHPR 0x0150
-#define I2O_OPTPR 0x0158
-#define I2O_MUCR 0x0164
-#define I2O_QBAR 0x0170
-
-#define I2O_NUM_MSG 2
-
-typedef enum _i2o_status
-{
- I2OSUCCESS = 0,
- I2OINVALID,
- I2OMSGINVALID,
- I2ODBINVALID,
- I2OQUEINVALID,
- I2OQUEEMPTY,
- I2OQUEFULL,
- I2ONOEVENT,
-} I2OSTATUS;
-
-typedef enum _queue_size
-{
- QSIZE_4K = 0x02,
- QSIZE_8K = 0x04,
- QSIZE_16K = 0x08,
- QSIZE_32K = 0x10,
- QSIZe_64K = 0x20,
-} QUEUE_SIZE;
-
-typedef enum _location
-{
- LOCAL = 0, /* used by local processor to access its own on board device,
- local processor's eumbbar is required */
- REMOTE, /* used by PCI master to access the devices on its PCI device,
- device's pcsrbar is required */
-} LOCATION;
-
-/* door bell */
-typedef enum _i2o_in_db
-{
- IN_DB = 1,
- MC, /* machine check */
-} I2O_IN_DB;
-
-/* I2O PCI configuration identification */
-typedef struct _i2o_iop
-{
- unsigned int base_class : 8;
- unsigned int sub_class : 8;
- unsigned int prg_code : 8;
-} I2OIOP;
-
-/* I2O Outbound Message Interrupt Status Register */
-typedef struct _i2o_om_stat
-{
- unsigned int rsvd0 : 26;
- unsigned int opqi : 1;
- unsigned int rsvd1 : 1;
- unsigned int odi : 1;
- unsigned int rsvd2 : 1;
- unsigned int om1i : 1;
- unsigned int om0i : 1;
-} I2OOMSTAT;
-
-/* I2O inbound Message Interrupt Status Register */
-typedef struct _i2o_im_stat
-{
- unsigned int rsvd0 : 23;
- unsigned int ofoi : 1;
- unsigned int ipoi : 1;
- unsigned int rsvd1 : 1;
- unsigned int ipqi : 1;
- unsigned int mci : 1;
- unsigned int idi : 1;
- unsigned int rsvd2 : 1;
- unsigned int im1i : 1;
- unsigned int im0i : 1;
-} I2OIMSTAT;
-
-/**
- Enable the interrupt associated with in/out bound msg
-
- Inbound message interrupt generated by PCI master and serviced by local processor
- local processor needs to enable its inbound interrupts it wants to handle (LOCAL)
-
- Outbound message interrupt generated by local processor and serviced by PCI master
- PCI master needs to enable the devices' outbound interrupts it wants to handle (REMOTE)
- **/
-extern I2OSTATUS I2OMsgEnable( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned char n ); /* b'1' - msg 0
- * b'10'- msg 1
- * b'11'- both
- */
-
-/**
- Disable the interrupt associated with in/out bound msg
-
- local processor needs to disable its inbound interrupts it is not interested (LOCAL)
-
- PCI master needs to disable outbound interrupts of devices it is not interested (REMOTE)
- **/
-extern I2OSTATUS I2OMsgDisable( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned char n ); /* b'1' - msg 0
- * b'10'- msg 1
- * b'11'- both
- */
-
-/**
- Read the msg register either from local inbound msg 0/1,
- or an outbound msg 0/1 of devices.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, outbound msg of the device is read.
- Otherwise local inbound msg is read.
- **/
-extern I2OSTATUS I2OMsgGet ( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /*pcsrbar/eumbbar */
- unsigned int n, /* 0 or 1 */
- unsigned int *msg );
-
-/**
- Write to nth Msg register either on local outbound msg 0/1,
- or aninbound msg 0/1 of devices
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, inbound msg on the device is written.
- Otherwise local outbound msg is written.
- **/
-extern I2OSTATUS I2OMsgPost( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /*pcsrbar/eumbbar */
- unsigned int n, /* 0 or 1 */
- unsigned int msg );
-
-/**
- Enable the In/Out DoorBell Interrupt
-
- InDoorBell interrupt is generated by PCI master and serviced by local processor
- local processor needs to enable its inbound doorbell interrupts it wants to handle
-
- OutDoorbell interrupt is generated by local processor and serviced by PCI master
- PCI master needs to enable outbound doorbell interrupts of the devices it wants to handle
- **/
-extern I2OSTATUS I2ODBEnable( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int in_db );/* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-
-/**
- Disable the In/Out DoorBell Interrupt
-
- local processor needs to disable its inbound doorbell interrupts it is not interested
-
- PCI master needs to disable outbound doorbell interrupts of devices it is not interested
-
- **/
-extern I2OSTATUS I2ODBDisable( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int in_db ); /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-
-/**
- Read a local indoorbell register, or an outdoorbell of devices.
- Reading a doorbell register, the register will be cleared.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, outdoorbell register on the device is read.
- Otherwise local in doorbell is read
- **/
-extern unsigned int I2ODBGet( LOCATION, /* REMOTE/LOCAL */
- unsigned int base); /* pcsrbar/eumbbar */
-
-/**
- Write to a local outdoorbell register, or an indoorbell register of devices.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, in doorbell register on the device is written.
- Otherwise local out doorbell is written
- **/
-extern void I2ODBPost( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int msg ); /* in / out */
-
-/**
- Read the outbound msg unit interrupt status of devices. Reading an interrupt status register,
- the register will be cleared.
-
- The outbound interrupt status is AND with the outbound
- interrupt mask. The result is returned.
-
- PCI master must pass the pcsrbar to the function.
- **/
-extern I2OSTATUS I2OOutMsgStatGet( unsigned int pcsrbar, I2OOMSTAT * );
-
-/**
- Read the inbound msg unit interrupt status. Reading an interrupt status register,
- the register will be cleared.
-
- The inbound interrupt status is AND with the inbound
- interrupt mask. The result is returned.
-
- Local process must pass its eumbbar to the function.
-**/
-extern I2OSTATUS I2OInMsgStatGet( unsigned int eumbbar, I2OIMSTAT * );
-
-/**
- Configure the I2O FIFO, including QBAR, IFHPR/IFTPR,IPHPR/IPTPR,OFHPR/OFTPR, OPHPR/OPTPR,
- MUCR.
- **/
-extern I2OSTATUS I2OFIFOInit( unsigned int eumbbar,
- QUEUE_SIZE,
- unsigned int qba);/* queue base address that must be aligned at 1M */
-/**
- Enable the circular queue
- **/
-extern I2OSTATUS I2OFIFOEnable( unsigned int eumbbar );
-
-/**
- Disable the circular queue
- **/
-extern void I2OFIFODisable( unsigned int eumbbar );
-
-/**
- Enable the circular queue interrupt
- PCI master enables outbound FIFO interrupt of device
- Device enables its inbound FIFO interrupt
- **/
-extern void I2OFIFOIntEnable( LOCATION, unsigned int base );
-
-/**
- Disable the circular queue interrupt
- PCI master disables outbound FIFO interrupt of device
- Device disables its inbound FIFO interrupt
- **/
-extern void I2OFIFOIntDisable( LOCATION, unsigned int base );
-
-/**
- Enable the circular queue overflow interrupt
- **/
-extern void I2OFIFOOverflowIntEnable( unsigned int eumbbar );
-
-/**
- Disable the circular queue overflow interrupt
- **/
-extern void I2OFIFOOverflowIntDisable( unsigned int eumbbar );
-
-/**
- Allocate a free msg frame from free FIFO.
-
- PCI Master allocates a free msg frame through inbound queue port of device(IFQPR)
- while local processor allocates a free msg frame from outbound free queue(OFTPR)
-
- Unless both free queues are initialized, allocating a free MF will return 0xffffffff
- **/
-extern I2OSTATUS I2OFIFOAlloc( LOCATION,
- unsigned int base,
- void **pMsg);
-/**
- Free a used msg frame back to free queue
- PCI Master frees a MFA through outbound queue port of device(OFQPR)
- while local processor frees a MFA into its inbound free queue(IFHPR)
-
- Used msg frame does not need to be recycled in the order they
- read
-
- This function has to be called by PCI master to initialize Inbound free queue
- and by device to initialize Outbound free queue before I2OFIFOAlloc can be used.
- **/
-extern I2OSTATUS I2OFIFOFree( LOCATION,
- unsigned int base,
- void *pMsg );
-
-/**
- Post a msg into FIFO
- PCI Master posts a msg through inbound queue port of device(IFQPR)
- while local processor post a msg into its outbound post queue(OPHPR)
-
- The total number of msg must be less than the max size of the queue
- Otherwise queue overflow interrupt will assert.
- **/
-extern I2OSTATUS I2OFIFOPost( LOCATION,
- unsigned int base,
- void *pMsg );
-
-/**
- Read a msg from FIFO
- PCI Master reads a msg through outbound queue port of device(OFQPR)
- while local processor reads a msg from its inbound post queue(IPTPR)
- **/
-extern I2OSTATUS I2OFIFOGet( LOCATION,
- unsigned int base,
- void **pMsg );
-
-/**
- Get the I2O PCI configuration identification register
- **/
-extern I2OSTATUS I2OPCIConfigGet( LOCATION,
- unsigned int base,
- I2OIOP *);
-
-#endif
diff --git a/cpu/mpc824x/drivers/i2o/i2o1.c b/cpu/mpc824x/drivers/i2o/i2o1.c
deleted file mode 100644
index f058151..0000000
--- a/cpu/mpc824x/drivers/i2o/i2o1.c
+++ /dev/null
@@ -1,890 +0,0 @@
-/*********************************************************
- * $Id
- *
- * copyright @ Motorola, 1999
- *********************************************************/
-#include "i2o.h"
-
-extern unsigned int load_runtime_reg( unsigned int eumbbar, unsigned int reg );
-#pragma Alias( load_runtime_reg, "load_runtime_reg" );
-
-extern void store_runtime_reg( unsigned int eumbbar, unsigned int reg, unsigned int val );
-#pragma Alias( store_runtime_reg, "store_runtime_reg" );
-
-typedef struct _fifo_stat
-{
- QUEUE_SIZE qsz;
- unsigned int qba;
-} FIFOSTAT;
-
-FIFOSTAT fifo_stat = { QSIZE_4K, 0xffffffff };
-
-/**********************************************************************************
- * function: I2OMsgEnable
- *
- * description: Enable the interrupt associated with in/out bound msg
- * return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
- *
- * All previously enabled interrupts are preserved.
- * note:
- * Inbound message interrupt generated by PCI master and serviced by local processor
- * Outbound message interrupt generated by local processor and serviced by PCI master
- *
- * local processor needs to enable its inbound interrupts it wants to handle(LOCAL)
- * PCI master needs to enable the outbound interrupts of devices it wants to handle(REMOTE)
- ************************************************************************************/
-I2OSTATUS I2OMsgEnable ( LOCATION loc, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned char n ) /* b'1' - msg 0
- * b'10'- msg 1
- * b'11'- both
- */
-{
- unsigned int reg, val;
- if ( ( n & 0x3 ) == 0 )
- {
- /* neither msg 0, nor msg 1 */
- return I2OMSGINVALID;
- }
-
- n = (~n) & 0x3;
- /* LOCATION - REMOTE : enable outbound message of device, pcsrbar as base
- * LOCAL : enable local inbound message, eumbbar as base
- */
- reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
- val = load_runtime_reg( base, reg );
-
- val &= 0xfffffffc; /* masked out the msg interrupt bits */
- val |= n; /* LSB are the one we want */
- store_runtime_reg( base, reg, val );
-
- return I2OSUCCESS;
-}
-
-/*********************************************************************************
- * function: I2OMsgDisable
- *
- * description: Disable the interrupt associated with in/out bound msg
- * Other previously enabled interrupts are preserved.
- * return I2OSUCCESS if no error otherwise return I2OMSGINVALID
- *
- * note:
- * local processor needs to disable its inbound interrupts it is not interested(LOCAL)
- * PCI master needs to disable outbound interrupts of devices it is not interested(REMOTE)
- *********************************************************************************/
-I2OSTATUS I2OMsgDisable( LOCATION loc, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned char n ) /* b'1' - msg 0
- * b'10'- msg 1
- * b'11'- both
- */
-{
- unsigned int reg, val;
-
- if ( ( n & 0x3 ) == 0 )
- {
- /* neither msg 0, nor msg 1 */
- return I2OMSGINVALID;
- }
-
- /* LOCATION - REMOTE : disable outbound message interrupt of device, pcsrbar as base
- * LOCAL : disable local inbound message interrupt, eumbbar as base
- */
- reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
- val = load_runtime_reg( base, reg );
-
- val &= 0xfffffffc; /* masked out the msg interrupt bits */
- val |= ( n & 0x3 );
- store_runtime_reg( base, reg, val );
-
- return I2OSUCCESS;
-
-}
-
-/**************************************************************************
- * function: I2OMsgGet
- *
- * description: Local processor reads the nth Msg register from its inbound msg,
- * or a PCI Master reads nth outbound msg from device
- *
- * return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
- *
- * note:
- * If it is not local, pcsrbar must be passed to the function. Otherwise eumbbar is passed.
- * If it is remote, outbound msg on the device is read; otherwise local inbound msg is read
- *************************************************************************/
-I2OSTATUS I2OMsgGet ( LOCATION loc, /* REMOTE/LOCAL */
- unsigned int base, /*pcsrbar/eumbbar */
- unsigned int n, /* 0 or 1 */
- unsigned int *msg )
-{
- if ( n >= I2O_NUM_MSG || msg == 0 )
- {
- return I2OMSGINVALID;
- }
-
- if ( loc == REMOTE )
- {
- /* read the outbound msg of the device, pcsrbar as base */
- *msg = load_runtime_reg( base, I2O_OMR0+n*I2O_REG_OFFSET );
- }
- else
- {
- /* read the inbound msg sent by PCI master, eumbbar as base */
- *msg = load_runtime_reg( base, I2O_IMR0+n*I2O_REG_OFFSET );
- }
-
- return I2OSUCCESS;
-}
-
-/***************************************************************
- * function: I2OMsgPost
- *
- * description: Kahlua writes to its nth outbound msg register
- * PCI master writes to nth inbound msg register of device
- *
- * return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
- *
- * note:
- * If it is not local, pcsrbar must be passed to the function. Otherwise eumbbar is passed.
- *
- * If it is remote, inbound msg on the device is written; otherwise local outbound msg is written
- ***************************************************************/
-I2OSTATUS I2OMsgPost( LOCATION loc, /* REMOTE/LOCAL */
- unsigned int base, /*pcsrbar/eumbbar */
- unsigned int n, /* 0 or 1 */
- unsigned int msg )
-{
- if ( n >= I2O_NUM_MSG )
- {
- return I2OMSGINVALID;
- }
-
- if ( loc == REMOTE )
- {
- /* write to the inbound msg register of the device, pcsrbar as base */
- store_runtime_reg( base, I2O_IMR0+n*I2O_REG_OFFSET, msg );
- }
- else
- {
- /* write to the outbound msg register for PCI master to read, eumbbar as base */
- store_runtime_reg( base, I2O_OMR0+n*I2O_REG_OFFSET, msg );
- }
-
- return I2OSUCCESS;
-}
-
-/***********************************************************************
- * function: I2ODBEnable
- *
- * description: Local processor enables it's inbound doorbell interrupt
- * PCI master enables outbound doorbell interrupt of devices
- * Other previously enabled interrupts are preserved.
- * Return I2OSUCCESS if no error otherwise return I2ODBINVALID
- *
- * note:
- * In DoorBell interrupt is generated by PCI master and serviced by local processor
- * Out Doorbell interrupt is generated by local processor and serviced by PCI master
- *
- * Out Doorbell interrupt is generated by local processor and serviced by PCI master
- * PCI master needs to enable the outbound doorbell interrupts of device it wants to handle
- **********************************************************************/
-I2OSTATUS I2ODBEnable( LOCATION loc, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int in_db ) /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-{
-
- /* LOCATION - REMOTE : PCI master initializes outbound doorbell message of device
- * LOCAL : Kahlua initializes its inbound doorbell message
- */
- unsigned int val;
-
- if ( loc == LOCAL && ( in_db & 0x3 ) == 0 )
- {
- return I2ODBINVALID;
- }
-
- if ( loc == REMOTE )
- {
- /* pcsrbar is base */
- val = load_runtime_reg( base, I2O_OMIMR );
- val &= 0xfffffff7;
- store_runtime_reg( base, I2O_OMIMR , val );
- }
- else
- {
- /* eumbbar is base */
- val = load_runtime_reg( base, I2O_IMIMR);
- in_db = ( (~in_db) & 0x3 ) << 3;
- val = ( val & 0xffffffe7) | in_db;
- store_runtime_reg( base, I2O_IMIMR, val );
- }
-
- return I2OSUCCESS;
-}
-
-/**********************************************************************************
- * function: I2ODBDisable
- *
- * description: local processor disables its inbound DoorBell Interrupt
- * PCI master disables outbound DoorBell interrupt of device
- * Other previously enabled interrupts are preserved.
- * return I2OSUCCESS if no error.Otherwise return I2ODBINVALID
- *
- * note:
- * local processor needs to disable its inbound doorbell interrupts it is not interested
- *
- * PCI master needs to disable outbound doorbell interrupts of device it is not interested
- ************************************************************************************/
-I2OSTATUS I2ODBDisable( LOCATION loc, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int in_db ) /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-{
- /* LOCATION - REMOTE : handle device's out bound message initialization
- * LOCAL : handle local in bound message initialization
- */
- unsigned int val;
-
- if ( loc == LOCAL && ( in_db & 0x3 ) == 0 )
- {
- return I2ODBINVALID;
- }
-
- if ( loc == REMOTE )
- {
- /* pcsrbar is the base */
- val = load_runtime_reg( base, I2O_OMIMR );
- val |= 0x8;
- store_runtime_reg( base, I2O_OMIMR, val );
- }
- else
- {
- val = load_runtime_reg( base, I2O_IMIMR);
- in_db = ( in_db & 0x3 ) << 3;
- val |= in_db;
- store_runtime_reg( base, I2O_IMIMR, val );
- }
-
- return I2OSUCCESS;
-}
-
-/**********************************************************************************
- * function: I2ODBGet
- *
- * description: Local processor reads its in doorbell register,
- * PCI master reads the outdoorbell register of device.
- * After a doorbell register is read, the whole register will be cleared.
- * Otherwise, HW keeps generating interrupt.
- *
- * note:
- * If it is not local, pcsrbar must be passed to the function.
- * Otherwise eumbbar is passed.
- *
- * If it is remote, out doorbell register on the device is read.
- * Otherwise local in doorbell is read
- *
- * If the register is not cleared by write to it, any remaining bit of b'1's
- * will cause interrupt pending.
- *********************************************************************************/
-unsigned int I2ODBGet( LOCATION loc, /* REMOTE/LOCAL */
- unsigned int base) /* pcsrbar/eumbbar */
-{
- unsigned int msg, val;
-
- if ( loc == REMOTE )
- {
- /* read outbound doorbell register of device, pcsrbar is the base */
- val = load_runtime_reg( base, I2O_ODBR );
- msg = val & 0xe0000000;
- store_runtime_reg( base, I2O_ODBR, val ); /* clear the register */
- }
- else
- {
- /* read the inbound doorbell register, eumbbar is the base */
- val = load_runtime_reg( base, I2O_IDBR );
- store_runtime_reg( base, I2O_IDBR, val ); /* clear the register */
- msg = val;
- }
-
- return msg;
-}
-
-/**********************************************************************
- * function: I2ODBPost
- *
- * description: local processor writes to a outbound doorbell register,
- * PCI master writes to the inbound doorbell register of device
- *
- * note:
- * If it is not local, pcsrbar must be passed to the function.
- * Otherwise eumbbar is passed.
- *
- * If it is remote, in doorbell register on the device is written.
- * Otherwise local out doorbell is written
- *********************************************************************/
-void I2ODBPost( LOCATION loc, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int msg ) /* in / out */
-{
- if ( loc == REMOTE )
- {
- /* write to inbound doorbell register of device, pcsrbar is the base */
- store_runtime_reg( base, I2O_IDBR, msg );
- }
- else
- {
- /* write to local outbound doorbell register, eumbbar is the base */
- store_runtime_reg( base, I2O_ODBR, msg & 0x1fffffff );
- }
-
-}
-
-/********************************************************************
- * function: I2OOutMsgStatGet
- *
- * description: PCI master reads device's outbound msg unit interrupt status.
- * Reading an interrupt status register,
- * the register will be cleared.
- *
- * The value of the status register is AND with the outbound
- * interrupt mask and result is returned.
- *
- * note:
- * pcsrbar must be passed to the function.
- ********************************************************************/
-I2OSTATUS I2OOutMsgStatGet( unsigned int pcsrbar, I2OOMSTAT *val )
-{
- unsigned int stat;
- unsigned int mask;
-
- if ( val == 0 )
- {
- return I2OINVALID;
- }
-
- /* read device's outbound status */
- stat = load_runtime_reg( pcsrbar, I2O_OMISR );
- mask = load_runtime_reg( pcsrbar, I2O_OMIMR );
- store_runtime_reg( pcsrbar, I2O_OMISR, stat & 0xffffffd7);
-
- stat &= mask;
- val->rsvd0 = ( stat & 0xffffffc0 ) >> 6;
- val->opqi = ( stat & 0x00000020 ) >> 5;
- val->rsvd1 = ( stat & 0x00000010 ) >> 4;
- val->odi = ( stat & 0x00000008 ) >> 3;
- val->rsvd2 = ( stat & 0x00000004 ) >> 2;
- val->om1i = ( stat & 0x00000002 ) >> 1;
- val->om0i = ( stat & 0x00000001 );
-
- return I2OSUCCESS;
-}
-
-/********************************************************************
- * function: I2OInMsgStatGet
- *
- * description: Local processor reads its inbound msg unit interrupt status.
- * Reading an interrupt status register,
- * the register will be cleared.
- *
- * The inbound msg interrupt status is AND with the inbound
- * msg interrupt mask and result is returned.
- *
- * note:
- * eumbbar must be passed to the function.
- ********************************************************************/
-I2OSTATUS I2OInMsgStatGet(unsigned int eumbbar, I2OIMSTAT *val)
-{
- unsigned int stat;
- unsigned int mask;
-
- if ( val == 0 )
- {
- return I2OINVALID;
- }
-
- /* read device's outbound status */
- stat = load_runtime_reg( eumbbar, I2O_OMISR );
- mask = load_runtime_reg( eumbbar, I2O_OMIMR );
- store_runtime_reg( eumbbar, I2O_OMISR, stat & 0xffffffe7 );
-
- stat &= mask;
- val->rsvd0 = ( stat & 0xfffffe00 ) >> 9;
- val->ofoi = ( stat & 0x00000100 ) >> 8;
- val->ipoi = ( stat & 0x00000080 ) >> 7;
- val->rsvd1 = ( stat & 0x00000040 ) >> 6;
- val->ipqi = ( stat & 0x00000020 ) >> 5;
- val->mci = ( stat & 0x00000010 ) >> 4;
- val->idi = ( stat & 0x00000008 ) >> 3;
- val->rsvd2 = ( stat & 0x00000004 ) >> 2;
- val->im1i = ( stat & 0x00000002 ) >> 1;
- val->im0i = ( stat & 0x00000001 );
-
- return I2OSUCCESS;
-
-}
-
-/***********************************************************
- * function: I2OFIFOInit
- *
- * description: Configure the I2O FIFO, including QBAR,
- * IFHPR/IFTPR, IPHPR/IPTPR, OFHPR/OFTPR,
- * OPHPR/OPTPR, MUCR.
- *
- * return I2OSUCCESS if no error,
- * otherwise return I2OQUEINVALID
- *
- * note: It is NOT this driver's responsibility of initializing
- * MFA blocks, i.e., FIFO queue itself. The MFA blocks
- * must be initialized before I2O unit can be used.
- ***********************************************************/
-I2OSTATUS I2OFIFOInit( unsigned int eumbbar,
- QUEUE_SIZE sz, /* value of CQS of MUCR */
- unsigned int qba) /* queue base address that must be aligned at 1M */
-{
-
- if ( ( qba & 0xfffff ) != 0 )
- {
- /* QBA must be aligned at 1Mbyte boundary */
- return I2OQUEINVALID;
- }
-
- store_runtime_reg( eumbbar, I2O_QBAR, qba );
- store_runtime_reg( eumbbar, I2O_MUCR, (unsigned int)sz );
- store_runtime_reg( eumbbar, I2O_IFHPR, qba );
- store_runtime_reg( eumbbar, I2O_IFTPR, qba );
- store_runtime_reg( eumbbar, I2O_IPHPR, qba + 1 * ( sz << 11 ));
- store_runtime_reg( eumbbar, I2O_IPTPR, qba + 1 * ( sz << 11 ));
- store_runtime_reg( eumbbar, I2O_OFHPR, qba + 2 * ( sz << 11 ));
- store_runtime_reg( eumbbar, I2O_OFTPR, qba + 2 * ( sz << 11 ));
- store_runtime_reg( eumbbar, I2O_OPHPR, qba + 3 * ( sz << 11 ));
- store_runtime_reg( eumbbar, I2O_OPTPR, qba + 3 * ( sz << 11 ));
-
- fifo_stat.qsz = sz;
- fifo_stat.qba = qba;
-
- return I2OSUCCESS;
-}
-
-/**************************************************
- * function: I2OFIFOEnable
- *
- * description: Enable the circular queue
- * return I2OSUCCESS if no error.
- * Otherwise I2OQUEINVALID is returned.
- *
- * note:
- *************************************************/
-I2OSTATUS I2OFIFOEnable( unsigned int eumbbar )
-{
- unsigned int val;
-
- if ( fifo_stat.qba == 0xfffffff )
- {
- return I2OQUEINVALID;
- }
-
- val = load_runtime_reg( eumbbar, I2O_MUCR );
- store_runtime_reg( eumbbar, I2O_MUCR, val | 0x1 );
-
- return I2OSUCCESS;
-}
-
-/**************************************************
- * function: I2OFIFODisable
- *
- * description: Disable the circular queue
- *
- * note:
- *************************************************/
-void I2OFIFODisable( unsigned int eumbbar )
-{
- if ( fifo_stat.qba == 0xffffffff )
- {
- /* not enabled */
- return;
- }
-
- unsigned int val = load_runtime_reg( eumbbar, I2O_MUCR );
- store_runtime_reg( eumbbar, I2O_MUCR, val & 0xfffffffe );
-}
-
-/****************************************************
- * function: I2OFIFOAlloc
- *
- * description: Allocate a free MFA from free FIFO.
- * return I2OSUCCESS if no error.
- * return I2OQUEEMPTY if no more free MFA.
- * return I2OINVALID on other errors.
- *
- * A free MFA must be allocated before a
- * message can be posted.
- *
- * note:
- * PCI Master allocates a free MFA from inbound queue of device
- * (pcsrbar is the base,) through the inbound queue port of device
- * while local processor allocates a free MFA from its outbound
- * queue (eumbbar is the base.)
- *
- ****************************************************/
-I2OSTATUS I2OFIFOAlloc( LOCATION loc,
- unsigned int base,
- void **pMsg )
-{
- I2OSTATUS stat = I2OSUCCESS;
- void *pHdr, *pTil;
-
- if ( pMsg == 0 || *pMsg == 0 || fifo_stat.qba == 0xffffffff )
- {
- /* not configured */
- return I2OQUEINVALID;
- }
-
- if ( loc == REMOTE )
- {
- /* pcsrbar is the base and read the inbound free tail ptr */
- pTil = (void *)load_runtime_reg( base, I2O_IFQPR );
- if ( ( (unsigned int)pTil & 0xFFFFFFF ) == 0xFFFFFFFF )
- {
- stat = I2OQUEEMPTY;
- }
- else
- {
- *pMsg = pTil;
- }
- }
- else
- {
- /* eumbbar is the base and read the outbound free tail ptr */
- pHdr = (void *)load_runtime_reg( base, I2O_OFHPR ); /* queue head */
- pTil = (void *)load_runtime_reg( base, I2O_OFTPR ); /* queue tail */
-
- /* check underflow */
- if ( pHdr == pTil )
- {
- /* hdr and til point to the same fifo item, no free MFA */
- stat = I2OQUEEMPTY;
- }
- else
- {
- /* update OFTPR */
- *pMsg = (void *)(*(unsigned char *)pTil);
- pTil = (void *)((unsigned int)pTil + 4);
- if ( (unsigned int)pTil == fifo_stat.qba + ( 4 * ( fifo_stat.qsz << 11 ) ) )
- {
- /* reach the upper limit */
- pTil = (void *)(fifo_stat.qba + ( 3 * (fifo_stat.qsz << 11) ));
- }
- store_runtime_reg( base, I2O_OFTPR, (unsigned int)pTil );
- }
- }
-
- return stat;
-}
-
-/******************************************************
- * function: I2OFIFOFree
- *
- * description: Free a used MFA back to free queue after
- * use.
- * return I2OSUCCESS if no error.
- * return I2OQUEFULL if inbound free queue
- * overflow
- *
- * note: PCI Master frees a MFA into device's outbound queue
- * (OFQPR) while local processor frees a MFA into its
- * inbound queue (IFHPR).
- *****************************************************/
-I2OSTATUS I2OFIFOFree( LOCATION loc,
- unsigned int base,
- void *pMsg )
-{
- void **pHdr, **pTil;
- I2OSTATUS stat = I2OSUCCESS;
-
- if ( fifo_stat.qba == 0xffffffff || pMsg == 0 )
- {
- return I2OQUEINVALID;
- }
-
- if ( loc == REMOTE )
- {
- /* pcsrbar is the base */
- store_runtime_reg( base, I2O_OFQPR, (unsigned int)pMsg );
- }
- else
- {
- /* eumbbar is the base */
- pHdr = (void **)load_runtime_reg( base, I2O_IFHPR );
- pTil = (void **)load_runtime_reg( base, I2O_IFTPR );
-
- /* store MFA */
- *pHdr = pMsg;
-
- /* update IFHPR */
- pHdr += 4;
-
- if ( (unsigned int)pHdr == fifo_stat.qba + ( fifo_stat.qsz << 11 ) )
- {
- /* reach the upper limit */
- pHdr = (void **)fifo_stat.qba;
- }
-
- /* check inbound free queue overflow */
- if ( pHdr != pTil )
- {
- store_runtime_reg( base, I2O_OPHPR, (unsigned int)pHdr);
- }
- else
- {
- stat = I2OQUEFULL;
- }
-
- }
-
- return stat;
-
-}
-
-/*********************************************
- * function: I2OFIFOPost
- *
- * description: Post a msg into FIFO post queue
- * the value of msg must be the one
- * returned by I2OFIFOAlloc
- *
- * note: PCI Master posts a msg into device's inbound queue
- * (IFQPR) while local processor post a msg into device's
- * outbound queue (OPHPR)
- *********************************************/
-I2OSTATUS I2OFIFOPost( LOCATION loc,
- unsigned int base,
- void *pMsg )
-{
- void **pHdr, **pTil;
- I2OSTATUS stat = I2OSUCCESS;
-
- if ( fifo_stat.qba == 0xffffffff || pMsg == 0 )
- {
- return I2OQUEINVALID;
- }
-
- if ( loc == REMOTE )
- {
- /* pcsrbar is the base */
- store_runtime_reg( base, I2O_IFQPR, (unsigned int)pMsg );
- }
- else
- {
- /* eumbbar is the base */
- pHdr = (void **)load_runtime_reg( base, I2O_OPHPR );
- pTil = (void **)load_runtime_reg( base, I2O_OPTPR );
-
- /* store MFA */
- *pHdr = pMsg;
-
- /* update IFHPR */
- pHdr += 4;
-
- if ( (unsigned int)pHdr == fifo_stat.qba + 3 * ( fifo_stat.qsz << 11 ) )
- {
- /* reach the upper limit */
- pHdr = (void **)(fifo_stat.qba + 2 * ( fifo_stat.qsz << 11 ) );
- }
-
- /* check post queue overflow */
- if ( pHdr != pTil )
- {
- store_runtime_reg( base, I2O_OPHPR, (unsigned int)pHdr);
- }
- else
- {
- stat = I2OQUEFULL;
- }
- }
-
- return stat;
-}
-
-/************************************************
- * function: I2OFIFOGet
- *
- * description: Read a msg from FIFO
- * This function should be called
- * only when there is a corresponding
- * msg interrupt.
- *
- * note: PCI Master reads a msg from device's outbound queue
- * (OFQPR) while local processor reads a msg from device's
- * inbound queue (IPTPR)
- ************************************************/
-I2OSTATUS I2OFIFOGet( LOCATION loc,
- unsigned int base,
- void **pMsg )
-{
- I2OSTATUS stat = I2OSUCCESS;
- void *pHdr, *pTil;
-
- if ( pMsg == 0 || *pMsg == 0 || fifo_stat.qba == 0xffffffff )
- {
- /* not configured */
- return I2OQUEINVALID;
- }
-
- if ( loc == REMOTE )
- {
- /* pcsrbar is the base */
- pTil = (void *)load_runtime_reg( base, I2O_OFQPR );
- if ( ( (unsigned int)pTil & 0xFFFFFFF ) == 0xFFFFFFFF )
- {
- stat = I2OQUEEMPTY;
- }
- else
- {
- *pMsg = pTil;
- }
- }
- else
- {
- /* eumbbar is the base and read the outbound free tail ptr */
- pHdr = (void *)load_runtime_reg( base, I2O_IPHPR ); /* queue head */
- pTil = (void *)load_runtime_reg( base, I2O_IPTPR ); /* queue tail */
-
- /* check underflow */
- if ( pHdr == pTil )
- {
- /* no free MFA */
- stat = I2OQUEEMPTY;
- }
- else
- {
- /* update OFTPR */
- *pMsg = (void *)(*(unsigned char *)pTil);
- pTil = (void *)((unsigned int)pTil + 4);
- if ( (unsigned int)pTil == fifo_stat.qba + 2 * ( fifo_stat.qsz << 11 ) )
- {
- /* reach the upper limit */
- pTil = (void *)(fifo_stat.qba + 1 * (fifo_stat.qsz << 11) );
- }
-
- store_runtime_reg( base, I2O_IPTPR, (unsigned int)pTil );
- }
- }
-
- return stat;
-}
-
-/********************************************************
- * function: I2OIOP
- *
- * description: Get the I2O PCI configuration identification
- * register.
- *
- * note: PCI master should pass pcsrbar while local processor
- * should pass eumbbar.
- *********************************************************/
-I2OSTATUS I2OPCIConfigGet( LOCATION loc,
- unsigned int base,
- I2OIOP * val)
-{
- unsigned int tmp;
- if ( val == 0 )
- {
- return I2OINVALID;
- }
- tmp = load_runtime_reg( base, PCI_CFG_CLA );
- val->base_class = ( tmp & 0xFF) << 16;
- tmp = load_runtime_reg( base, PCI_CFG_SCL );
- val->sub_class= ( (tmp & 0xFF) << 8 );
- tmp = load_runtime_reg( base, PCI_CFG_PIC );
- val->prg_code = (tmp & 0xFF);
- return I2OSUCCESS;
-}
-
-/*********************************************************
- * function: I2OFIFOIntEnable
- *
- * description: Enable the circular post queue interrupt
- *
- * note:
- * PCI master enables outbound FIFO interrupt of device
- * pscrbar is the base
- * Device enables its inbound FIFO interrupt
- * eumbbar is the base
- *******************************************************/
-void I2OFIFOIntEnable( LOCATION loc, unsigned int base )
-{
- unsigned int reg, val;
-
- /* LOCATION - REMOTE : enable outbound message of device, pcsrbar as base
- * LOCAL : enable local inbound message, eumbbar as base
- */
- reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
- val = load_runtime_reg( base, reg );
-
- val &= 0xffffffdf; /* clear the msg interrupt bits */
- store_runtime_reg( base, reg, val );
-
-}
-
-/****************************************************
- * function: I2OFIFOIntDisable
- *
- * description: Disable the circular post queue interrupt
- *
- * note:
- * PCI master disables outbound FIFO interrupt of device
- * (pscrbar is the base)
- * Device disables its inbound FIFO interrupt
- * (eumbbar is the base)
- *****************************************************/
-void I2OFIFOIntDisable( LOCATION loc, unsigned int base )
-{
-
- /* LOCATION - REMOTE : disable outbound message interrupt of device, pcsrbar as base
- * LOCAL : disable local inbound message interrupt, eumbbar as base
- */
- unsigned int reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
- unsigned int val = load_runtime_reg( base, reg );
-
- val |= 0x00000020; /* masked out the msg interrupt bits */
- store_runtime_reg( base, reg, val );
-
-}
-
-/*********************************************************
- * function: I2OFIFOOverflowIntEnable
- *
- * description: Enable the circular queue overflow interrupt
- *
- * note:
- * Device enables its inbound FIFO post overflow interrupt
- * and outbound free overflow interrupt.
- * eumbbar is the base
- *******************************************************/
-void I2OFIFOOverflowIntEnable( unsigned int eumbbar )
-{
- unsigned int val = load_runtime_reg( eumbbar, I2O_IMIMR );
-
- val &= 0xfffffe7f; /* clear the two overflow interrupt bits */
- store_runtime_reg( eumbbar, I2O_IMIMR, val );
-
-}
-
-/****************************************************
- * function: I2OFIFOOverflowIntDisable
- *
- * description: Disable the circular queue overflow interrupt
- *
- * note:
- * Device disables its inbound post FIFO overflow interrupt
- * and outbound free FIFO overflow interrupt
- * (eumbbar is the base)
- *****************************************************/
-void I2OFIFOOverflowIntDisable( unsigned int eumbbar )
-{
-
- unsigned int val = load_runtime_reg( eumbbar, I2O_IMIMR );
-
- val |= 0x00000180; /* masked out the msg overflow interrupt bits */
- store_runtime_reg( eumbbar, I2O_IMIMR, val );
-}
diff --git a/cpu/mpc824x/drivers/i2o/i2o2.S b/cpu/mpc824x/drivers/i2o/i2o2.S
deleted file mode 100644
index 990f9ef..0000000
--- a/cpu/mpc824x/drivers/i2o/i2o2.S
+++ /dev/null
@@ -1,47 +0,0 @@
-/**************************************
- *
- * copyright @ Motorola, 1999
- *
- **************************************/
-
-/**********************************************************
- * function: load_runtime_reg
- *
- * input: r3 - value of eumbbar
- * r4 - register offset in embedded utility space
- *
- * output: r3 - register content
- **********************************************************/
- .text
- .align 2
- .global load_runtime_reg
-
-load_runtime_reg:
-
- xor r5,r5,r5
- or r5,r5,r3 /* save eumbbar */
-
- lwbrx r3,r4,r5
- sync
-
- bclr 20, 0
-
-/****************************************************************
- * function: store_runtime_reg
- *
- * input: r3 - value of eumbbar
- * r4 - register offset in embedded utility space
- * r5 - new value to be stored
- *
- ****************************************************************/
- .text
- .align 2
- .global store_runtime_reg
-store_runtime_reg:
-
- xor r0,r0,r0
-
- stwbrx r5, r4, r3
- sync
-
- bclr 20,0
diff --git a/cpu/mpc8260/Makefile b/cpu/mpc8260/Makefile
index b4c269f..b1f1c18 100644
--- a/cpu/mpc8260/Makefile
+++ b/cpu/mpc8260/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,23 +23,27 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o kgdb.o
-OBJS = traps.o serial_smc.o serial_scc.o cpu.o cpu_init.o speed.o \
+COBJS = traps.o serial_smc.o serial_scc.o cpu.o cpu_init.o speed.o \
interrupts.o ether_scc.o ether_fcc.o i2c.o commproc.o \
bedbug_603e.o pci.o spi.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS) kgdb.o
+ $(AR) crv $@ $(OBJS) $(obj)kgdb.o
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mpc8260/pci.c b/cpu/mpc8260/pci.c
index ea5514f..b14fc15 100644
--- a/cpu/mpc8260/pci.c
+++ b/cpu/mpc8260/pci.c
@@ -34,7 +34,7 @@
#include <asm/m8260_pci.h>
#include <asm/io.h>
-#if defined CONFIG_MPC8266ADS || defined CONFIG_MPC8272
+#if defined CONFIG_MPC8266ADS || defined CONFIG_MPC8272 || defined CONFIG_PM826
DECLARE_GLOBAL_DATA_PTR;
#endif
@@ -401,7 +401,7 @@ void pci_mpc8250_init (struct pci_controller *hose)
hose->last_busno = 0xff;
/* System memory space */
-#if defined CONFIG_MPC8266ADS || defined CONFIG_MPC8272
+#if defined CONFIG_MPC8266ADS || defined CONFIG_MPC8272 || defined CONFIG_PM826
pci_set_region (hose->regions + 0,
PCI_SLV_MEM_BUS,
PCI_SLV_MEM_LOCAL,
diff --git a/cpu/mpc83xx/Makefile b/cpu/mpc83xx/Makefile
index 60df4cd..f3fa6fd 100644
--- a/cpu/mpc83xx/Makefile
+++ b/cpu/mpc83xx/Makefile
@@ -1,4 +1,7 @@
#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
# Copyright 2004 Freescale Semiconductor, Inc.
#
# See file CREDITS for list of people who contributed to this
@@ -22,31 +25,26 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
-START = start.o \
- resetvec.o
+START = start.o resetvec.o
+COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \
+ i2c.o spd_sdram.o
-COBJS = traps.o \
- cpu.o \
- cpu_init.o \
- speed.o \
- interrupts.o \
- i2c.o \
- spd_sdram.o
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-OBJS = $(COBJS)
-
-all: .depend $(START) $(LIB)
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(COBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mpc83xx/i2c.c b/cpu/mpc83xx/i2c.c
index 4e70f80..70450f9 100644
--- a/cpu/mpc83xx/i2c.c
+++ b/cpu/mpc83xx/i2c.c
@@ -41,7 +41,7 @@
#include <i2c.h>
#include <asm/i2c.h>
-#if defined(CONFIG_MPC8349ADS) || defined(CONFIG_TQM834X)
+#if defined(CONFIG_MPC8349EMDS) || defined(CONFIG_TQM834X)
i2c_t * mpc8349_i2c = (i2c_t*)(CFG_IMMRBAR + CFG_I2C_OFFSET);
#endif
diff --git a/cpu/mpc85xx/Makefile b/cpu/mpc85xx/Makefile
index 5298dc1..bbc5084 100644
--- a/cpu/mpc85xx/Makefile
+++ b/cpu/mpc85xx/Makefile
@@ -1,4 +1,7 @@
#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
# (C) Copyright 2002,2003 Motorola Inc.
# Xianghua Xiao,X.Xiao@motorola.com
#
@@ -23,23 +26,26 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o resetvec.o
COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \
pci.o serial_scc.o commproc.o ether_fcc.o i2c.o spd_sdram.o
-OBJS = $(COBJS)
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c
index f7fe22e..0507c47 100644
--- a/cpu/mpc85xx/cpu.c
+++ b/cpu/mpc85xx/cpu.c
@@ -30,7 +30,10 @@
#include <command.h>
#include <asm/cache.h>
-/* ------------------------------------------------------------------------- */
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
int checkcpu (void)
{
@@ -227,3 +230,48 @@ int dma_xfer(void *dest, uint count, void *src) {
return dma_check();
}
#endif
+
+
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_cpu_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ ulong clock;
+ int len;
+
+ clock = bd->bi_busfreq;
+ p = ft_get_prop(blob, "/cpus/" OF_CPU "/bus-frequency", &len);
+ if (p != NULL)
+ *p = cpu_to_be32(clock);
+
+ p = ft_get_prop(blob, "/" OF_SOC "/serial@4500/clock-frequency", &len);
+ if (p != NULL)
+ *p = cpu_to_be32(clock);
+
+ p = ft_get_prop(blob, "/" OF_SOC "/serial@4600/clock-frequency", &len);
+ if (p != NULL)
+ *p = cpu_to_be32(clock);
+
+#if defined(CONFIG_MPC85XX_TSEC1)
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/mac-address", &len);
+ memcpy(p, bd->bi_enetaddr, 6);
+#endif
+
+#if defined(CONFIG_HAS_ETH1)
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/mac-address", &len);
+ memcpy(p, bd->bi_enet1addr, 6);
+#endif
+
+#if defined(CONFIG_HAS_ETH2)
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@26000/mac-address", &len);
+ memcpy(p, bd->bi_enet2addr, 6);
+#endif
+
+#if defined(CONFIG_HAS_ETH3)
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@27000/mac-address", &len);
+ memcpy(p, bd->bi_enet3addr, 6);
+#endif
+
+}
+#endif
diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c
index c12b47b..9f4d36c 100644
--- a/cpu/mpc85xx/cpu_init.c
+++ b/cpu/mpc85xx/cpu_init.c
@@ -32,6 +32,7 @@
DECLARE_GLOBAL_DATA_PTR;
+
#ifdef CONFIG_CPM2
static void config_8560_ioports (volatile immap_t * immr)
{
diff --git a/cpu/mpc85xx/pci.c b/cpu/mpc85xx/pci.c
index a94493e..cfb7dcd 100644
--- a/cpu/mpc85xx/pci.c
+++ b/cpu/mpc85xx/pci.c
@@ -32,66 +32,93 @@
#if defined(CONFIG_PCI)
+static struct pci_controller *pci_hose;
+
void
-pci_mpc85xx_init(struct pci_controller *hose)
+pci_mpc85xx_init(struct pci_controller *board_hose)
{
+ u16 reg16;
+ u32 dev;
+
volatile immap_t *immap = (immap_t *)CFG_CCSRBAR;
volatile ccsr_pcix_t *pcix = &immap->im_pcix;
+ volatile ccsr_pcix_t *pcix2 = &immap->im_pcix2;
+ volatile ccsr_gur_t *gur = &immap->im_gur;
+ struct pci_controller * hose;
- u16 reg16;
+ pci_hose = board_hose;
+
+ hose = &pci_hose[0];
hose->first_busno = 0;
hose->last_busno = 0xff;
- pci_set_region(hose->regions + 0,
- CFG_PCI1_MEM_BASE,
- CFG_PCI1_MEM_PHYS,
- CFG_PCI1_MEM_SIZE,
- PCI_REGION_MEM);
-
- pci_set_region(hose->regions + 1,
- CFG_PCI1_IO_BASE,
- CFG_PCI1_IO_PHYS,
- CFG_PCI1_IO_SIZE,
- PCI_REGION_IO);
-
- hose->region_count = 2;
-
pci_setup_indirect(hose,
(CFG_IMMR+0x8000),
(CFG_IMMR+0x8004));
+ /*
+ * Hose scan.
+ */
+ dev = PCI_BDF(hose->first_busno, 0, 0);
+ pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
+
+ if (!(gur->pordevsr & PORDEVSR_PCI)) {
+ /* PCI-X init */
+ if (CONFIG_SYS_CLK_FREQ < 66000000)
+ printf("PCI-X will only work at 66 MHz\n");
+
+ reg16 = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ
+ | PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E;
+ pci_hose_write_config_word(hose, dev, PCIX_COMMAND, reg16);
+ }
+
pcix->potar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
pcix->potear1 = 0x00000000;
- pcix->powbar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
+ pcix->powbar1 = (CFG_PCI1_MEM_PHYS >> 12) & 0x000fffff;
pcix->powbear1 = 0x00000000;
- pcix->powar1 = 0x8004401c; /* 512M MEM space */
+ pcix->powar1 = (POWAR_EN | POWAR_MEM_READ |
+ POWAR_MEM_WRITE | POWAR_MEM_512M);
- pcix->potar2 = 0x00000000;
+ pcix->potar2 = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
pcix->potear2 = 0x00000000;
- pcix->powbar2 = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
+ pcix->powbar2 = (CFG_PCI1_IO_PHYS >> 12) & 0x000fffff;
pcix->powbear2 = 0x00000000;
- pcix->powar2 = 0x80088017; /* 16M IO space */
+ pcix->powar2 = (POWAR_EN | POWAR_IO_READ |
+ POWAR_IO_WRITE | POWAR_IO_1M);
pcix->pitar1 = 0x00000000;
pcix->piwbar1 = 0x00000000;
- pcix->piwar1 = 0xa0f5501e; /* Enable, Prefetch, Local Mem,
- * Snoop R/W, 2G */
+ pcix->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
+ PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G);
- /*
- * Hose scan.
- */
- pci_register_hose(hose);
+ pcix->powar3 = 0;
+ pcix->powar4 = 0;
+ pcix->piwar2 = 0;
+ pcix->piwar3 = 0;
- pci_read_config_word (PCI_BDF(0,0,0), PCI_COMMAND, &reg16);
- reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
- pci_write_config_word(PCI_BDF(0,0,0), PCI_COMMAND, reg16);
+ pci_set_region(hose->regions + 0,
+ CFG_PCI1_MEM_BASE,
+ CFG_PCI1_MEM_PHYS,
+ CFG_PCI1_MEM_SIZE,
+ PCI_REGION_MEM);
- /*
- * Clear non-reserved bits in status register.
- */
- pci_write_config_word(PCI_BDF(0,0,0), PCI_STATUS, 0xffff);
- pci_write_config_byte(PCI_BDF(0,0,0), PCI_LATENCY_TIMER,0x80);
+ pci_set_region(hose->regions + 1,
+ CFG_PCI1_IO_BASE,
+ CFG_PCI1_IO_PHYS,
+ CFG_PCI1_IO_SIZE,
+ PCI_REGION_IO);
+
+ hose->region_count = 2;
+
+ pci_register_hose(hose);
#if defined(CONFIG_MPC8555CDS) || defined(CONFIG_MPC8541CDS)
/*
@@ -117,6 +144,94 @@ pci_mpc85xx_init(struct pci_controller *hose)
#endif
hose->last_busno = pci_hose_scan(hose);
+
+#ifdef CONFIG_MPC85XX_PCI2
+ hose = &pci_hose[1];
+
+ hose->first_busno = pci_hose[0].last_busno + 1;
+ hose->last_busno = 0xff;
+
+ pci_setup_indirect(hose,
+ (CFG_IMMR+0x9000),
+ (CFG_IMMR+0x9004));
+
+ dev = PCI_BDF(hose->first_busno, 0, 0);
+ pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
+
+ pcix2->potar1 = (CFG_PCI2_MEM_BASE >> 12) & 0x000fffff;
+ pcix2->potear1 = 0x00000000;
+ pcix2->powbar1 = (CFG_PCI2_MEM_PHYS >> 12) & 0x000fffff;
+ pcix2->powbear1 = 0x00000000;
+ pcix2->powar1 = (POWAR_EN | POWAR_MEM_READ |
+ POWAR_MEM_WRITE | POWAR_MEM_512M);
+
+ pcix2->potar2 = (CFG_PCI2_IO_BASE >> 12) & 0x000fffff;
+ pcix2->potear2 = 0x00000000;
+ pcix2->powbar2 = (CFG_PCI2_IO_PHYS >> 12) & 0x000fffff;
+ pcix2->powbear2 = 0x00000000;
+ pcix2->powar2 = (POWAR_EN | POWAR_IO_READ |
+ POWAR_IO_WRITE | POWAR_IO_1M);
+
+ pcix2->pitar1 = 0x00000000;
+ pcix2->piwbar1 = 0x00000000;
+ pcix2->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
+ PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G);
+
+ pcix2->powar3 = 0;
+ pcix2->powar4 = 0;
+ pcix2->piwar2 = 0;
+ pcix2->piwar3 = 0;
+
+ pci_set_region(hose->regions + 0,
+ CFG_PCI2_MEM_BASE,
+ CFG_PCI2_MEM_PHYS,
+ CFG_PCI2_MEM_SIZE,
+ PCI_REGION_MEM);
+
+ pci_set_region(hose->regions + 1,
+ CFG_PCI2_IO_BASE,
+ CFG_PCI2_IO_PHYS,
+ CFG_PCI2_IO_SIZE,
+ PCI_REGION_IO);
+
+ hose->region_count = 2;
+
+ /*
+ * Hose scan.
+ */
+ pci_register_hose(hose);
+
+ hose->last_busno = pci_hose_scan(hose);
+#endif
}
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_pci_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ int len;
+
+ p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8000/bus-range", &len);
+ if (p != NULL) {
+ p[0] = pci_hose[0].first_busno;
+ p[1] = pci_hose[0].last_busno;
+ }
+
+#ifdef CONFIG_MPC85XX_PCI2
+ p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@9000/bus-range", &len);
+ if (p != NULL) {
+ p[0] = pci_hose[1].first_busno;
+ p[1] = pci_hose[1].last_busno;
+ }
+#endif
+}
+#endif /* CONFIG_OF_FLAT_TREE */
#endif /* CONFIG_PCI */
diff --git a/cpu/mpc86xx/Makefile b/cpu/mpc86xx/Makefile
index 7995945..ad5b36d 100644
--- a/cpu/mpc86xx/Makefile
+++ b/cpu/mpc86xx/Makefile
@@ -25,24 +25,27 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o #resetvec.o
-ASOBJS = cache.o
+SOBJS = cache.o
COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \
pci.o pcie_indirect.o i2c.o spd_sdram.o
-OBJS = $(COBJS)
-all: .depend $(START) $(ASOBJS) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(ASOBJS) $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(ASOBJS:.o=.S) $(COBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(ASOBJS:.o=.S) $(COBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mpc8xx/Makefile b/cpu/mpc8xx/Makefile
index de75fad..6451e05 100644
--- a/cpu/mpc8xx/Makefile
+++ b/cpu/mpc8xx/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -25,25 +25,29 @@ include $(TOPDIR)/config.mk
# CFLAGS += -DET_DEBUG
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o kgdb.o
-OBJS = bedbug_860.o commproc.o cpu.o cpu_init.o \
+COBJS = bedbug_860.o commproc.o cpu.o cpu_init.o \
fec.o i2c.o interrupts.o lcd.o scc.o \
serial.o speed.o spi.o \
traps.o upatch.o video.o
SOBJS = plprcr_write.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-$(LIB): $(OBJS) $(SOBJS)
- $(AR) crv $@ $(OBJS) $(SOBJS) kgdb.o
+all: $(obj).depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS) $(obj)kgdb.o
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c) $(SOBJS:.o=.S)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) $(SOBJS:.o=.S) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mpc8xx/cpu_init.c b/cpu/mpc8xx/cpu_init.c
index 1a7111f..c79e578 100644
--- a/cpu/mpc8xx/cpu_init.c
+++ b/cpu/mpc8xx/cpu_init.c
@@ -161,6 +161,7 @@ void cpu_init_f (volatile immap_t * immr)
defined(CONFIG_RMU) || \
defined(CONFIG_RPXCLASSIC) || \
defined(CONFIG_RPXLITE) || \
+ defined(CONFIG_SPC1920) || \
defined(CONFIG_SPD823TS)
memctl->memc_br0 = CFG_BR0_PRELIM;
diff --git a/cpu/mpc8xx/fec.c b/cpu/mpc8xx/fec.c
index 6006478..6d2755e 100644
--- a/cpu/mpc8xx/fec.c
+++ b/cpu/mpc8xx/fec.c
@@ -396,8 +396,10 @@ static void fec_pin_init(int fecidx)
* * to 2.5 MHz.
* * This MDC frequency is equal to system clock / (2 * MII_SPEED).
* * Then MII_SPEED = system_clock / 2 * 2,5 Mhz.
+ *
+ * All MII configuration is done via FEC1 registers:
*/
- fecp->fec_mii_speed = ((bd->bi_intfreq + 4999999) / 5000000) << 1;
+ immr->im_cpm.cp_fec1.fec_mii_speed = ((bd->bi_intfreq + 4999999) / 5000000) << 1;
#if defined(CONFIG_NETTA) || defined(CONFIG_NETPHONE) || defined(CONFIG_NETTA2)
/* our PHYs are the limit at 2.5 MHz */
@@ -508,8 +510,6 @@ static void fec_pin_init(int fecidx)
#if defined(CONFIG_MPC885_FAMILY) /* MPC87x/88x have got 2 FECs and different pinout */
#if !defined(CONFIG_RMII)
-
-#warning this configuration is not tested; please report if it works
immr->im_cpm.cp_pepar |= 0x0003fffc;
immr->im_cpm.cp_pedir |= 0x0003fffc;
immr->im_cpm.cp_peso &= ~0x000087fc;
@@ -822,6 +822,7 @@ static void fec_halt(struct eth_device* dev)
#define PHY_ID_LSI80225 0x0016f870 /* LSI 80225 */
#define PHY_ID_LSI80225B 0x0016f880 /* LSI 80225/B */
#define PHY_ID_DM9161 0x0181B880 /* Davicom DM9161 */
+#define PHY_ID_KSM8995M 0x00221450 /* MICREL KS8995MA */
/* send command to phy using mii, wait for result */
static uint
@@ -907,6 +908,9 @@ static int mii_discover_phy(struct eth_device *dev)
case PHY_ID_DM9161:
printf("Davicom DM9161\n");
break;
+ case PHY_ID_KSM8995M:
+ printf("MICREL KS8995M\n");
+ break;
default:
printf("0x%08x\n", phytype);
break;
diff --git a/cpu/mpc8xx/serial.c b/cpu/mpc8xx/serial.c
index 26a82cc..8ae584f 100644
--- a/cpu/mpc8xx/serial.c
+++ b/cpu/mpc8xx/serial.c
@@ -227,9 +227,12 @@ static int smc_init (void)
sp->smc_smcm = 0;
sp->smc_smce = 0xff;
- /* Set up the baud rate generator.
- */
+#ifdef CFG_SPC1920_SMC1_CLK4 /* clock source is PLD */
+ *((volatile uchar *) CFG_SPC1920_PLD_BASE+6) = 0xff;
+#else
+ /* Set up the baud rate generator */
smc_setbrg ();
+#endif
/* Make the first buffer the only buffer.
*/
diff --git a/cpu/mpc8xx/speed.c b/cpu/mpc8xx/speed.c
index 57f91c0..101d5f9 100644
--- a/cpu/mpc8xx/speed.c
+++ b/cpu/mpc8xx/speed.c
@@ -259,7 +259,11 @@ int get_clocks_866 (void)
*/
sccr_reg = immr->im_clkrst.car_sccr;
sccr_reg &= ~SCCR_EBDF11;
+#if defined(CONFIG_TQM885D)
+ if (gd->cpu_clk <= 80000000) {
+#else
if (gd->cpu_clk <= 66000000) {
+#endif
sccr_reg |= SCCR_EBDF00; /* bus division factor = 1 */
gd->bus_clk = gd->cpu_clk;
} else {
@@ -360,7 +364,8 @@ static long init_pll_866 (long clk)
#endif /* CONFIG_8xx_CPUCLK_DEFAULT */
-#if defined(CONFIG_TQM8xxL) && !defined(CONFIG_TQM866M)
+#if defined(CONFIG_TQM8xxL) && !defined(CONFIG_TQM866M) \
+ && !defined(CONFIG_TQM885D)
/*
* Adjust sdram refresh rate to actual CPU clock
* and set timebase source according to actual CPU clock
@@ -384,6 +389,6 @@ int adjust_sdram_tbs_8xx (void)
return (0);
}
-#endif /* CONFIG_TQM8xxL/M, !TQM866M */
+#endif /* CONFIG_TQM8xxL/M, !TQM866M, !TQM885D */
/* ------------------------------------------------------------------------- */
diff --git a/cpu/nios/Makefile b/cpu/nios/Makefile
index 7855325..cdab7b0 100644
--- a/cpu/nios/Makefile
+++ b/cpu/nios/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,22 +23,26 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-AOBJS = traps.o
-OBJS = cpu.o interrupts.o serial.o asmi.o spi.o
+SOBJS = traps.o
+COBJS = cpu.o interrupts.o serial.o asmi.o spi.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-$(LIB): $(OBJS) $(AOBJS)
- $(AR) crv $@ $(OBJS) $(AOBJS)
+all: $(obj).depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/nios2/Makefile b/cpu/nios2/Makefile
index 11fda50..f903129 100644
--- a/cpu/nios2/Makefile
+++ b/cpu/nios2/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,22 +23,26 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-AOBJS = exceptions.o
-OBJS = cpu.o interrupts.o serial.o sysid.o traps.o epcs.o
+SOBJS = exceptions.o
+COBJS = cpu.o interrupts.o serial.o sysid.o traps.o epcs.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-$(LIB): $(OBJS) $(AOBJS)
- $(AR) crv $@ $(OBJS) $(AOBJS)
+all: $(obj).depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/nios2/epcs.c b/cpu/nios2/epcs.c
index a8851e9..414c38c 100644
--- a/cpu/nios2/epcs.c
+++ b/cpu/nios2/epcs.c
@@ -25,7 +25,7 @@
#if defined(CFG_NIOS_EPCSBASE)
#include <command.h>
-#include <nios2.h>
+#include <asm/io.h>
#include <nios2-io.h>
#include <nios2-epcs.h>
@@ -72,8 +72,7 @@
*/
#define EPCS_TIMEOUT 100 /* 100 msec timeout */
-static nios_spi_t *epcs =
- (nios_spi_t *)CACHE_BYPASS(CFG_NIOS_EPCSBASE);
+static nios_spi_t *epcs = (nios_spi_t *)CFG_NIOS_EPCSBASE;
/***********************************************************************
* Device access
@@ -81,16 +80,20 @@ static nios_spi_t *epcs =
static int epcs_cs (int assert)
{
ulong start;
+ unsigned tmp;
+
if (assert) {
- epcs->control |= NIOS_SPI_SSO;
+ tmp = readl (&epcs->control);
+ writel (&epcs->control, tmp | NIOS_SPI_SSO);
} else {
/* Let all bits shift out */
start = get_timer (0);
- while ((epcs->status & NIOS_SPI_TMT) == 0)
+ while ((readl (&epcs->status) & NIOS_SPI_TMT) == 0)
if (get_timer (start) > EPCS_TIMEOUT)
return (-1);
- epcs->control &= ~NIOS_SPI_SSO;
+ tmp = readl (&epcs->control);
+ writel (&epcs->control, tmp & ~NIOS_SPI_SSO);
}
return (0);
}
@@ -100,10 +103,10 @@ static int epcs_tx (unsigned char c)
ulong start;
start = get_timer (0);
- while ((epcs->status & NIOS_SPI_TRDY) == 0)
+ while ((readl (&epcs->status) & NIOS_SPI_TRDY) == 0)
if (get_timer (start) > EPCS_TIMEOUT)
return (-1);
- epcs->txdata = c;
+ writel (&epcs->txdata, c);
return (0);
}
@@ -112,10 +115,10 @@ static int epcs_rx (void)
ulong start;
start = get_timer (0);
- while ((epcs->status & NIOS_SPI_RRDY) == 0)
+ while ((readl (&epcs->status) & NIOS_SPI_RRDY) == 0)
if (get_timer (start) > EPCS_TIMEOUT)
return (-1);
- return (epcs->rxdata);
+ return (readl (&epcs->rxdata));
}
static unsigned char bitrev[] = {
@@ -207,6 +210,21 @@ static struct epcs_devinfo_t devinfo[] = {
{ 0, 0, 0, 0, 0, 0 }
};
+int epcs_reset (void)
+{
+ /* When booting from an epcs controller, the epcs bootrom
+ * code may leave the slave select in an asserted state.
+ * This causes two problems: (1) The initial epcs access
+ * will fail -- not a big deal, and (2) a software reset
+ * will cause the bootrom code to hang since it does not
+ * ensure the select is negated prior to first access -- a
+ * big deal. Here we just negate chip select and everything
+ * gets better :-)
+ */
+ epcs_cs (0); /* Negate chip select */
+ return (0);
+}
+
epcs_devinfo_t *epcs_dev_find (void)
{
unsigned char buf[4];
diff --git a/cpu/nios2/exceptions.S b/cpu/nios2/exceptions.S
index d3b95cf..b9c7a58 100644
--- a/cpu/nios2/exceptions.S
+++ b/cpu/nios2/exceptions.S
@@ -30,6 +30,9 @@
.global _exception
+ .set noat
+ .set nobreak
+
_exception:
/* SAVE ALL REGS -- this allows trap and unimplemented
* instruction handlers to be coded conveniently in C
diff --git a/cpu/nios2/interrupts.c b/cpu/nios2/interrupts.c
index 4a6da58..4685161 100644
--- a/cpu/nios2/interrupts.c
+++ b/cpu/nios2/interrupts.c
@@ -27,6 +27,7 @@
#include <nios2.h>
#include <nios2-io.h>
+#include <asm/io.h>
#include <asm/ptrace.h>
#include <common.h>
#include <command.h>
@@ -79,7 +80,7 @@ void tmr_isr (void *arg)
/* Interrupt is cleared by writing anything to the
* status register.
*/
- tmr->status = 0;
+ writel (&tmr->status, 0);
timestamp += CFG_NIOS_TMRMS;
#ifdef CONFIG_STATUS_LED
status_led_tick(timestamp);
@@ -88,16 +89,17 @@ void tmr_isr (void *arg)
static void tmr_init (void)
{
- nios_timer_t *tmr =(nios_timer_t *)CACHE_BYPASS(CFG_NIOS_TMRBASE);
+ nios_timer_t *tmr =(nios_timer_t *)CFG_NIOS_TMRBASE;
+
+ writel (&tmr->status, 0);
+ writel (&tmr->control, 0);
+ writel (&tmr->control, NIOS_TIMER_STOP);
- tmr->control &= ~(NIOS_TIMER_START | NIOS_TIMER_ITO);
- tmr->control |= NIOS_TIMER_STOP;
#if defined(CFG_NIOS_TMRCNT)
- tmr->periodl = CFG_NIOS_TMRCNT & 0xffff;
- tmr->periodh = (CFG_NIOS_TMRCNT >> 16) & 0xffff;
+ writel (&tmr->periodl, CFG_NIOS_TMRCNT & 0xffff);
+ writel (&tmr->periodh, (CFG_NIOS_TMRCNT >> 16) & 0xffff);
#endif
- tmr->control |= ( NIOS_TIMER_ITO |
- NIOS_TIMER_CONT |
+ writel (&tmr->control, NIOS_TIMER_ITO | NIOS_TIMER_CONT |
NIOS_TIMER_START );
irq_install_handler (CFG_NIOS_TMRIRQ, tmr_isr, (void *)tmr);
}
diff --git a/cpu/nios2/serial.c b/cpu/nios2/serial.c
index 3d76603..0bd3821 100644
--- a/cpu/nios2/serial.c
+++ b/cpu/nios2/serial.c
@@ -24,7 +24,7 @@
#include <common.h>
#include <watchdog.h>
-#include <nios2.h>
+#include <asm/io.h>
#include <nios2-io.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -34,8 +34,7 @@ DECLARE_GLOBAL_DATA_PTR;
*-----------------------------------------------------------------*/
#if defined(CONFIG_CONSOLE_JTAG)
-static nios_jtag_t *jtag =
- (nios_jtag_t *)CACHE_BYPASS(CFG_NIOS_CONSOLE);
+static nios_jtag_t *jtag = (nios_jtag_t *)CFG_NIOS_CONSOLE;
void serial_setbrg( void ){ return; }
int serial_init( void ) { return(0);}
@@ -44,9 +43,9 @@ void serial_putc (char c)
{
unsigned val;
- while (NIOS_JTAG_WSPACE (jtag->control) == 0)
+ while (NIOS_JTAG_WSPACE ( readl (&jtag->control)) == 0)
WATCHDOG_RESET ();
- jtag->data = (unsigned char)c;
+ writel (&jtag->data, (unsigned char)c);
}
void serial_puts (const char *s)
@@ -57,7 +56,7 @@ void serial_puts (const char *s)
int serial_tstc (void)
{
- return (jtag->control & NIOS_JTAG_RRDY);
+ return ( readl (&jtag->control) & NIOS_JTAG_RRDY);
}
int serial_getc (void)
@@ -67,7 +66,7 @@ int serial_getc (void)
while (1) {
WATCHDOG_RESET ();
- val = jtag->data;
+ val = readl (&jtag->data);
if (val & NIOS_JTAG_RVALID)
break;
}
@@ -80,8 +79,7 @@ int serial_getc (void)
*-----------------------------------------------------------------*/
#else
-static nios_uart_t *uart = (nios_uart_t *)
- CACHE_BYPASS(CFG_NIOS_CONSOLE);
+static nios_uart_t *uart = (nios_uart_t *) CFG_NIOS_CONSOLE;
#if defined(CFG_NIOS_FIXEDBAUD)
@@ -98,7 +96,7 @@ void serial_setbrg (void)
unsigned div;
div = (CONFIG_SYS_CLK_FREQ/gd->baudrate)-1;
- uart->divisor = div;
+ writel (&uart->divisor,div);
return;
}
@@ -118,9 +116,9 @@ void serial_putc (char c)
{
if (c == '\n')
serial_putc ('\r');
- while ((uart->status & NIOS_UART_TRDY) == 0)
+ while ((readl (&uart->status) & NIOS_UART_TRDY) == 0)
WATCHDOG_RESET ();
- uart->txdata = (unsigned char)c;
+ writel (&uart->txdata,(unsigned char)c);
}
void serial_puts (const char *s)
@@ -132,14 +130,14 @@ void serial_puts (const char *s)
int serial_tstc (void)
{
- return (uart->status & NIOS_UART_RRDY);
+ return (readl (&uart->status) & NIOS_UART_RRDY);
}
int serial_getc (void)
{
while (serial_tstc () == 0)
WATCHDOG_RESET ();
- return( uart->rxdata & 0x00ff );
+ return (readl (&uart->rxdata) & 0x00ff );
}
#endif /* CONFIG_JTAG_CONSOLE */
diff --git a/cpu/nios2/sysid.c b/cpu/nios2/sysid.c
index 2b7a569..b5a2959 100644
--- a/cpu/nios2/sysid.c
+++ b/cpu/nios2/sysid.c
@@ -26,20 +26,21 @@
#if defined (CFG_NIOS_SYSID_BASE)
#include <command.h>
-#include <nios2.h>
+#include <asm/io.h>
#include <nios2-io.h>
#include <linux/time.h>
void display_sysid (void)
{
- struct nios_sysid_t *sysid =
- (struct nios_sysid_t *)CACHE_BYPASS(CFG_NIOS_SYSID_BASE);
+ struct nios_sysid_t *sysid = (struct nios_sysid_t *)CFG_NIOS_SYSID_BASE;
struct tm t;
char asc[32];
+ time_t stamp;
- localtime_r ((time_t *)&sysid->timestamp, &t);
+ stamp = readl (&sysid->timestamp);
+ localtime_r (&stamp, &t);
asctime_r (&t, asc);
- printf ("SYSID : %08x, %s", sysid->id, asc);
+ printf ("SYSID : %08x, %s", readl (&sysid->id), asc);
}
diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/405gp_pci.c
index fad895b..03128d3 100644
--- a/cpu/ppc4xx/405gp_pci.c
+++ b/cpu/ppc4xx/405gp_pci.c
@@ -315,7 +315,6 @@ void pci_405gp_init(struct pci_controller *hose)
#ifdef CONFIG_PCI_SCAN_SHOW
printf("PCI: Bus Dev VenId DevId Class Int\n");
#endif
-
hose->last_busno = pci_hose_scan(hose);
}
#endif /* CONFIG_PCI_PNP */
@@ -438,7 +437,7 @@ void pci_440_init (struct pci_controller *hose)
* The PCI initialization sequence enable bit must be set ... if not abort
* pci setup since updating the bit requires chip reset.
*--------------------------------------------------------------------------*/
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
unsigned long strap;
mfsdr(sdr_sdstp1,strap);
@@ -465,17 +464,30 @@ void pci_440_init (struct pci_controller *hose)
hose->first_busno = 0;
hose->last_busno = 0xff;
+ /* PCI I/O space */
pci_set_region(hose->regions + reg_num++,
0x00000000,
PCIX0_IOBASE,
0x10000,
PCI_REGION_IO);
+ /* PCI memory space */
pci_set_region(hose->regions + reg_num++,
CFG_PCI_TARGBASE,
CFG_PCI_MEMBASE,
0x10000000,
PCI_REGION_MEM );
+
+#if defined(CONFIG_PCI_SYS_MEM_BUS) && defined(CONFIG_PCI_SYS_MEM_PHYS) && \
+ defined(CONFIG_PCI_SYS_MEM_SIZE)
+ /* System memory space */
+ pci_set_region(hose->regions + reg_num++,
+ CONFIG_PCI_SYS_MEM_BUS,
+ CONFIG_PCI_SYS_MEM_PHYS,
+ CONFIG_PCI_SYS_MEM_SIZE,
+ PCI_REGION_MEM | PCI_REGION_MEMORY );
+#endif
+
hose->region_count = reg_num;
pci_setup_indirect(hose, PCIX0_CFGADR, PCIX0_CFGDATA);
@@ -502,7 +514,7 @@ void pci_440_init (struct pci_controller *hose)
out16r( PCIX0_CLS, 0x00060000 ); /* Bridge, host bridge */
#endif
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
out32r( PCIX0_BRDGOPT1, 0x04000060 ); /* PLB Rq pri highest */
out32r( PCIX0_BRDGOPT2, in32(PCIX0_BRDGOPT2) | 0x83 ); /* Enable host config, clear Timeout, ensure int src1 */
#elif defined(PCIX0_BRDGOPT1)
@@ -520,8 +532,13 @@ void pci_440_init (struct pci_controller *hose)
out32r( PCIX0_POM0SA, 0 ); /* disable */
out32r( PCIX0_POM1SA, 0 ); /* disable */
out32r( PCIX0_POM2SA, 0 ); /* disable */
+#if defined(CONFIG_440SPE)
+ out32r( PCIX0_POM0LAL, 0x10000000 );
+ out32r( PCIX0_POM0LAH, 0x0000000c );
+#else
out32r( PCIX0_POM0LAL, 0x00000000 );
out32r( PCIX0_POM0LAH, 0x00000003 );
+#endif
out32r( PCIX0_POM0PCIAL, CFG_PCI_MEMBASE );
out32r( PCIX0_POM0PCIAH, 0x00000000 );
out32r( PCIX0_POM0SA, 0xf0000001 ); /* 256MB, enabled */
@@ -538,17 +555,20 @@ void pci_440_init (struct pci_controller *hose)
#ifdef CONFIG_PCI_SCAN_SHOW
printf("PCI: Bus Dev VenId DevId Class Int\n");
#endif
-#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR)
+#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR) && \
+ !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
out16r( PCIX0_CMD, in16r( PCIX0_CMD ) | PCI_COMMAND_MASTER);
#endif
hose->last_busno = pci_hose_scan(hose);
}
}
-
void pci_init_board(void)
{
pci_440_init (&ppc440_hose);
+#if defined(CONFIG_440SPE)
+ pcie_setup_hoses();
+#endif
}
#endif /* CONFIG_440 & CONFIG_PCI */
diff --git a/cpu/ppc4xx/440spe_pcie.c b/cpu/ppc4xx/440spe_pcie.c
new file mode 100644
index 0000000..6130cd2
--- /dev/null
+++ b/cpu/ppc4xx/440spe_pcie.c
@@ -0,0 +1,962 @@
+/*
+ * (C) Copyright 2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ * Roland Dreier <rolandd@cisco.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <asm/processor.h>
+#include <asm-ppc/io.h>
+#include <ppc4xx.h>
+#include <common.h>
+#include <pci.h>
+
+#include "440spe_pcie.h"
+
+#if defined(CONFIG_440SPE)
+#if defined(CONFIG_PCI)
+
+enum {
+ PTYPE_ENDPOINT = 0x0,
+ PTYPE_LEGACY_ENDPOINT = 0x1,
+ PTYPE_ROOT_PORT = 0x4,
+
+ LNKW_X1 = 0x1,
+ LNKW_X4 = 0x4,
+ LNKW_X8 = 0x8
+};
+
+static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,
+ int offset, int len, u32 *val) {
+
+ *val = 0;
+ /*
+ * 440SPE implements only one function per port
+ */
+ if (!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 1)))
+ return 0;
+
+ devfn = PCI_BDF(0,0,0);
+ offset += devfn << 4;
+
+ switch (len) {
+ case 1:
+ *val = in_8(hose->cfg_data + offset);
+ break;
+ case 2:
+ *val = in_le16((u16 *)(hose->cfg_data + offset));
+ break;
+ default:
+ *val = in_le32((u32 *)(hose->cfg_data + offset));
+ break;
+ }
+ return 0;
+}
+
+static int pcie_write_config(struct pci_controller *hose, unsigned int devfn,
+ int offset, int len, u32 val) {
+
+ /*
+ * 440SPE implements only one function per port
+ */
+ if (!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 1)))
+ return 0;
+
+ devfn = PCI_BDF(0,0,0);
+ offset += devfn << 4;
+
+ switch (len) {
+ case 1:
+ out_8(hose->cfg_data + offset, val);
+ break;
+ case 2:
+ out_le16((u16 *)(hose->cfg_data + offset), val);
+ break;
+ default:
+ out_le32((u32 *)(hose->cfg_data + offset), val);
+ break;
+ }
+ return 0;
+}
+
+int pcie_read_config_byte(struct pci_controller *hose,pci_dev_t dev,int offset,u8 *val)
+{
+ u32 v;
+ int rv;
+
+ rv = pcie_read_config(hose, dev, offset, 1, &v);
+ *val = (u8)v;
+ return rv;
+}
+
+int pcie_read_config_word(struct pci_controller *hose,pci_dev_t dev,int offset,u16 *val)
+{
+ u32 v;
+ int rv;
+
+ rv = pcie_read_config(hose, dev, offset, 2, &v);
+ *val = (u16)v;
+ return rv;
+}
+
+int pcie_read_config_dword(struct pci_controller *hose,pci_dev_t dev,int offset,u32 *val)
+{
+ u32 v;
+ int rv;
+
+ rv = pcie_read_config(hose, dev, offset, 3, &v);
+ *val = (u32)v;
+ return rv;
+}
+
+int pcie_write_config_byte(struct pci_controller *hose,pci_dev_t dev,int offset,u8 val)
+{
+ return pcie_write_config(hose,(u32)dev,offset,1,val);
+}
+
+int pcie_write_config_word(struct pci_controller *hose,pci_dev_t dev,int offset,u16 val)
+{
+ return pcie_write_config(hose,(u32)dev,offset,2,(u32 )val);
+}
+
+int pcie_write_config_dword(struct pci_controller *hose,pci_dev_t dev,int offset,u32 val)
+{
+ return pcie_write_config(hose,(u32)dev,offset,3,(u32 )val);
+}
+
+static void ppc440spe_setup_utl(u32 port) {
+
+ volatile void *utl_base = NULL;
+
+ /*
+ * Map UTL registers
+ */
+ switch (port) {
+ case 0:
+ mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x0000000c);
+ mtdcr(DCRN_PEGPL_REGBAL(PCIE0), 0x20000000);
+ mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001);
+ mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0x68782800);
+ break;
+
+ case 1:
+ mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x0000000c);
+ mtdcr(DCRN_PEGPL_REGBAL(PCIE1), 0x20001000);
+ mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001);
+ mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0x68782800);
+ break;
+
+ case 2:
+ mtdcr(DCRN_PEGPL_REGBAH(PCIE2), 0x0000000c);
+ mtdcr(DCRN_PEGPL_REGBAL(PCIE2), 0x20002000);
+ mtdcr(DCRN_PEGPL_REGMSK(PCIE2), 0x00007001);
+ mtdcr(DCRN_PEGPL_SPECIAL(PCIE2), 0x68782800);
+ break;
+ }
+ utl_base = (unsigned int *)(CFG_PCIE_BASE + 0x1000 * port);
+
+ /*
+ * Set buffer allocations and then assert VRB and TXE.
+ */
+ out_be32(utl_base + PEUTL_OUTTR, 0x08000000);
+ out_be32(utl_base + PEUTL_INTR, 0x02000000);
+ out_be32(utl_base + PEUTL_OPDBSZ, 0x10000000);
+ out_be32(utl_base + PEUTL_PBBSZ, 0x53000000);
+ out_be32(utl_base + PEUTL_IPHBSZ, 0x08000000);
+ out_be32(utl_base + PEUTL_IPDBSZ, 0x10000000);
+ out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000);
+ out_be32(utl_base + PEUTL_PCTL, 0x80800066);
+}
+
+static int check_error(void)
+{
+ u32 valPE0, valPE1, valPE2;
+ int err = 0;
+
+ /* SDR0_PEGPLLLCT1 reset */
+ if (!(valPE0 = SDR_READ(PESDR0_PLLLCT1) & 0x01000000)) {
+ printf("PCIE: SDR0_PEGPLLLCT1 reset error 0x%x\n", valPE0);
+ }
+
+ valPE0 = SDR_READ(PESDR0_RCSSET);
+ valPE1 = SDR_READ(PESDR1_RCSSET);
+ valPE2 = SDR_READ(PESDR2_RCSSET);
+
+ /* SDR0_PExRCSSET rstgu */
+ if (!(valPE0 & 0x01000000) ||
+ !(valPE1 & 0x01000000) ||
+ !(valPE2 & 0x01000000)) {
+ printf("PCIE: SDR0_PExRCSSET rstgu error\n");
+ err = -1;
+ }
+
+ /* SDR0_PExRCSSET rstdl */
+ if (!(valPE0 & 0x00010000) ||
+ !(valPE1 & 0x00010000) ||
+ !(valPE2 & 0x00010000)) {
+ printf("PCIE: SDR0_PExRCSSET rstdl error\n");
+ err = -1;
+ }
+
+ /* SDR0_PExRCSSET rstpyn */
+ if ((valPE0 & 0x00001000) ||
+ (valPE1 & 0x00001000) ||
+ (valPE2 & 0x00001000)) {
+ printf("PCIE: SDR0_PExRCSSET rstpyn error\n");
+ err = -1;
+ }
+
+ /* SDR0_PExRCSSET hldplb */
+ if ((valPE0 & 0x10000000) ||
+ (valPE1 & 0x10000000) ||
+ (valPE2 & 0x10000000)) {
+ printf("PCIE: SDR0_PExRCSSET hldplb error\n");
+ err = -1;
+ }
+
+ /* SDR0_PExRCSSET rdy */
+ if ((valPE0 & 0x00100000) ||
+ (valPE1 & 0x00100000) ||
+ (valPE2 & 0x00100000)) {
+ printf("PCIE: SDR0_PExRCSSET rdy error\n");
+ err = -1;
+ }
+
+ /* SDR0_PExRCSSET shutdown */
+ if ((valPE0 & 0x00000100) ||
+ (valPE1 & 0x00000100) ||
+ (valPE2 & 0x00000100)) {
+ printf("PCIE: SDR0_PExRCSSET shutdown error\n");
+ err = -1;
+ }
+ return err;
+}
+
+/*
+ * Initialize PCI Express core
+ */
+int ppc440spe_init_pcie(void)
+{
+ int time_out = 20;
+
+ /* Set PLL clock receiver to LVPECL */
+ SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) | 1 << 28);
+
+ if (check_error())
+ return -1;
+
+ if (!(SDR_READ(PESDR0_PLLLCT2) & 0x10000))
+ {
+ printf("PCIE: PESDR_PLLCT2 resistance calibration failed (0x%08x)\n",
+ SDR_READ(PESDR0_PLLLCT2));
+ return -1;
+ }
+ /* De-assert reset of PCIe PLL, wait for lock */
+ SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) & ~(1 << 24));
+ udelay(3);
+
+ while (time_out) {
+ if (!(SDR_READ(PESDR0_PLLLCT3) & 0x10000000)) {
+ time_out--;
+ udelay(1);
+ } else
+ break;
+ }
+ if (!time_out) {
+ printf("PCIE: VCO output not locked\n");
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Yucca board as End point and root point setup
+ * and
+ * testing inbound and out bound windows
+ *
+ * YUCCA board can be plugged into another yucca board or you can get PCI-E
+ * cable which can be used to setup loop back from one port to another port.
+ * Please rememeber that unless there is a endpoint plugged in to root port it
+ * will not initialize. It is the same in case of endpoint , unless there is
+ * root port attached it will not initialize.
+ *
+ * In this release of software all the PCI-E ports are configured as either
+ * endpoint or rootpoint.In future we will have support for selective ports
+ * setup as endpoint and root point in single board.
+ *
+ * Once your board came up as root point , you can verify by reading
+ * /proc/bus/pci/devices. Where you can see the configuration registers
+ * of end point device attached to the port.
+ *
+ * Enpoint cofiguration can be verified by connecting Yucca board to any
+ * host or another yucca board. Then try to scan the device. In case of
+ * linux use "lspci" or appripriate os command.
+ *
+ * How do I verify the inbound and out bound windows ?(yucca to yucca)
+ * in this configuration inbound and outbound windows are setup to access
+ * sram memroy area. SRAM is at 0x4 0000 0000 , on PLB bus. This address
+ * is mapped at 0x90000000. From u-boot prompt write data 0xb000 0000,
+ * This is waere your POM(PLB out bound memory window) mapped. then
+ * read the data from other yucca board's u-boot prompt at address
+ * 0x9000 0000(SRAM). Data should match.
+ * In case of inbound , write data to u-boot command prompt at 0xb000 0000
+ * which is mapped to 0x4 0000 0000. Now on rootpoint yucca u-boot prompt check
+ * data at 0x9000 0000(SRAM).Data should match.
+ */
+int ppc440spe_init_pcie_rootport(int port)
+{
+ static int core_init;
+ volatile u32 val = 0;
+ int attempts;
+
+ if (!core_init) {
+ ++core_init;
+ if (ppc440spe_init_pcie())
+ return -1;
+ }
+
+ /*
+ * Initialize various parts of the PCI Express core for our port:
+ *
+ * - Set as a root port and enable max width
+ * (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
+ * - Set up UTL configuration.
+ * - Increase SERDES drive strength to levels suggested by AMCC.
+ * - De-assert RSTPYN, RSTDL and RSTGU.
+ *
+ * NOTICE for revB chip: PESDRn_UTLSET2 is not set - we leave it with
+ * default setting 0x11310000. The register has new fields,
+ * PESDRn_UTLSET2[LKINE] in particular: clearing it leads to PCIE core
+ * hang.
+ */
+ switch (port) {
+ case 0:
+ SDR_WRITE(PESDR0_DLPSET, 1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X8 << 12);
+
+ SDR_WRITE(PESDR0_UTLSET1, 0x21222222);
+ if (!ppc440spe_revB())
+ SDR_WRITE(PESDR0_UTLSET2, 0x11000000);
+ SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL2SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL3SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
+ SDR_WRITE(PESDR0_RCSSET,
+ (SDR_READ(PESDR0_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+ break;
+
+ case 1:
+ SDR_WRITE(PESDR1_DLPSET, 1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
+ SDR_WRITE(PESDR1_UTLSET1, 0x21222222);
+ if (!ppc440spe_revB())
+ SDR_WRITE(PESDR1_UTLSET2, 0x11000000);
+ SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000);
+ SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000);
+ SDR_WRITE(PESDR1_HSSL2SET1, 0x35000000);
+ SDR_WRITE(PESDR1_HSSL3SET1, 0x35000000);
+ SDR_WRITE(PESDR1_RCSSET,
+ (SDR_READ(PESDR1_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+ break;
+
+ case 2:
+ SDR_WRITE(PESDR2_DLPSET, 1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
+ SDR_WRITE(PESDR2_UTLSET1, 0x21222222);
+ if (!ppc440spe_revB())
+ SDR_WRITE(PESDR2_UTLSET2, 0x11000000);
+ SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000);
+ SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000);
+ SDR_WRITE(PESDR2_HSSL2SET1, 0x35000000);
+ SDR_WRITE(PESDR2_HSSL3SET1, 0x35000000);
+ SDR_WRITE(PESDR2_RCSSET,
+ (SDR_READ(PESDR2_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+ break;
+ }
+ /*
+ * Notice: the following delay has critical impact on device
+ * initialization - if too short (<50ms) the link doesn't get up.
+ */
+ mdelay(100);
+
+ switch (port) {
+ case 0:
+ val = SDR_READ(PESDR0_RCSSTS);
+ break;
+ case 1:
+ val = SDR_READ(PESDR1_RCSSTS);
+ break;
+ case 2:
+ val = SDR_READ(PESDR2_RCSSTS);
+ break;
+ }
+
+ if (val & (1 << 20)) {
+ printf("PCIE%d: PGRST failed %08x\n", port, val);
+ return -1;
+ }
+
+ /*
+ * Verify link is up
+ */
+ val = 0;
+ switch (port) {
+ case 0:
+ val = SDR_READ(PESDR0_LOOP);
+ break;
+ case 1:
+ val = SDR_READ(PESDR1_LOOP);
+ break;
+ case 2:
+ val = SDR_READ(PESDR2_LOOP);
+ break;
+ }
+ if (!(val & 0x00001000)) {
+ printf("PCIE%d: link is not up.\n", port);
+ return -1;
+ }
+
+ /*
+ * Setup UTL registers - but only on revA!
+ * We use default settings for revB chip.
+ */
+ if (!ppc440spe_revB())
+ ppc440spe_setup_utl(port);
+
+ /*
+ * We map PCI Express configuration access into the 512MB regions
+ *
+ * NOTICE: revB is very strict about PLB real addressess and ranges to
+ * be mapped for config space; it seems to only work with d_nnnn_nnnn
+ * range (hangs the core upon config transaction attempts when set
+ * otherwise) while revA uses c_nnnn_nnnn.
+ *
+ * For revA:
+ * PCIE0: 0xc_4000_0000
+ * PCIE1: 0xc_8000_0000
+ * PCIE2: 0xc_c000_0000
+ *
+ * For revB:
+ * PCIE0: 0xd_0000_0000
+ * PCIE1: 0xd_2000_0000
+ * PCIE2: 0xd_4000_0000
+ */
+
+ switch (port) {
+ case 0:
+ if (ppc440spe_revB()) {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000d);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x00000000);
+ } else {
+ /* revA */
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000);
+ }
+ mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
+ break;
+
+ case 1:
+ if (ppc440spe_revB()) {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000d);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x20000000);
+ } else {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000);
+ }
+ mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
+ break;
+
+ case 2:
+ if (ppc440spe_revB()) {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000d);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0x40000000);
+ } else {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000);
+ }
+ mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
+ break;
+ }
+
+ /*
+ * Check for VC0 active and assert RDY.
+ */
+ attempts = 10;
+ switch (port) {
+ case 0:
+ while(!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) {
+ if (!(attempts--)) {
+ printf("PCIE0: VC0 not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+ SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
+ break;
+ case 1:
+ while(!(SDR_READ(PESDR1_RCSSTS) & (1 << 16))) {
+ if (!(attempts--)) {
+ printf("PCIE1: VC0 not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+
+ SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
+ break;
+ case 2:
+ while(!(SDR_READ(PESDR2_RCSSTS) & (1 << 16))) {
+ if (!(attempts--)) {
+ printf("PCIE2: VC0 not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+
+ SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
+ break;
+ }
+ mdelay(100);
+
+ return 0;
+}
+
+int ppc440spe_init_pcie_endport(int port)
+{
+ static int core_init;
+ volatile u32 val = 0;
+ int attempts;
+
+ if (!core_init) {
+ ++core_init;
+ if (ppc440spe_init_pcie())
+ return -1;
+ }
+
+ /*
+ * Initialize various parts of the PCI Express core for our port:
+ *
+ * - Set as a end port and enable max width
+ * (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
+ * - Set up UTL configuration.
+ * - Increase SERDES drive strength to levels suggested by AMCC.
+ * - De-assert RSTPYN, RSTDL and RSTGU.
+ *
+ * NOTICE for revB chip: PESDRn_UTLSET2 is not set - we leave it with
+ * default setting 0x11310000. The register has new fields,
+ * PESDRn_UTLSET2[LKINE] in particular: clearing it leads to PCIE core
+ * hang.
+ */
+ switch (port) {
+ case 0:
+ SDR_WRITE(PESDR0_DLPSET, 1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X8 << 12);
+
+ SDR_WRITE(PESDR0_UTLSET1, 0x20222222);
+ if (!ppc440spe_revB())
+ SDR_WRITE(PESDR0_UTLSET2, 0x11000000);
+ SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL2SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL3SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
+ SDR_WRITE(PESDR0_RCSSET,
+ (SDR_READ(PESDR0_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+ break;
+
+ case 1:
+ SDR_WRITE(PESDR1_DLPSET, 1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X4 << 12);
+ SDR_WRITE(PESDR1_UTLSET1, 0x20222222);
+ if (!ppc440spe_revB())
+ SDR_WRITE(PESDR1_UTLSET2, 0x11000000);
+ SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000);
+ SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000);
+ SDR_WRITE(PESDR1_HSSL2SET1, 0x35000000);
+ SDR_WRITE(PESDR1_HSSL3SET1, 0x35000000);
+ SDR_WRITE(PESDR1_RCSSET,
+ (SDR_READ(PESDR1_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+ break;
+
+ case 2:
+ SDR_WRITE(PESDR2_DLPSET, 1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X4 << 12);
+ SDR_WRITE(PESDR2_UTLSET1, 0x20222222);
+ if (!ppc440spe_revB())
+ SDR_WRITE(PESDR2_UTLSET2, 0x11000000);
+ SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000);
+ SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000);
+ SDR_WRITE(PESDR2_HSSL2SET1, 0x35000000);
+ SDR_WRITE(PESDR2_HSSL3SET1, 0x35000000);
+ SDR_WRITE(PESDR2_RCSSET,
+ (SDR_READ(PESDR2_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+ break;
+ }
+ /*
+ * Notice: the following delay has critical impact on device
+ * initialization - if too short (<50ms) the link doesn't get up.
+ */
+ mdelay(100);
+
+ switch (port) {
+ case 0: val = SDR_READ(PESDR0_RCSSTS); break;
+ case 1: val = SDR_READ(PESDR1_RCSSTS); break;
+ case 2: val = SDR_READ(PESDR2_RCSSTS); break;
+ }
+
+ if (val & (1 << 20)) {
+ printf("PCIE%d: PGRST failed %08x\n", port, val);
+ return -1;
+ }
+
+ /*
+ * Verify link is up
+ */
+ val = 0;
+ switch (port)
+ {
+ case 0:
+ val = SDR_READ(PESDR0_LOOP);
+ break;
+ case 1:
+ val = SDR_READ(PESDR1_LOOP);
+ break;
+ case 2:
+ val = SDR_READ(PESDR2_LOOP);
+ break;
+ }
+ if (!(val & 0x00001000)) {
+ printf("PCIE%d: link is not up.\n", port);
+ return -1;
+ }
+
+ /*
+ * Setup UTL registers - but only on revA!
+ * We use default settings for revB chip.
+ */
+ if (!ppc440spe_revB())
+ ppc440spe_setup_utl(port);
+
+ /*
+ * We map PCI Express configuration access into the 512MB regions
+ *
+ * NOTICE: revB is very strict about PLB real addressess and ranges to
+ * be mapped for config space; it seems to only work with d_nnnn_nnnn
+ * range (hangs the core upon config transaction attempts when set
+ * otherwise) while revA uses c_nnnn_nnnn.
+ *
+ * For revA:
+ * PCIE0: 0xc_4000_0000
+ * PCIE1: 0xc_8000_0000
+ * PCIE2: 0xc_c000_0000
+ *
+ * For revB:
+ * PCIE0: 0xd_0000_0000
+ * PCIE1: 0xd_2000_0000
+ * PCIE2: 0xd_4000_0000
+ */
+ switch (port) {
+ case 0:
+ if (ppc440spe_revB()) {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000d);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x00000000);
+ } else {
+ /* revA */
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000);
+ }
+ mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
+ break;
+
+ case 1:
+ if (ppc440spe_revB()) {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000d);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x20000000);
+ } else {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000);
+ }
+ mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
+ break;
+
+ case 2:
+ if (ppc440spe_revB()) {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000d);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0x40000000);
+ } else {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000);
+ }
+ mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
+ break;
+ }
+
+ /*
+ * Check for VC0 active and assert RDY.
+ */
+ attempts = 10;
+ switch (port) {
+ case 0:
+ while(!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) {
+ if (!(attempts--)) {
+ printf("PCIE0: VC0 not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+ SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
+ break;
+ case 1:
+ while(!(SDR_READ(PESDR1_RCSSTS) & (1 << 16))) {
+ if (!(attempts--)) {
+ printf("PCIE1: VC0 not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+
+ SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
+ break;
+ case 2:
+ while(!(SDR_READ(PESDR2_RCSSTS) & (1 << 16))) {
+ if (!(attempts--)) {
+ printf("PCIE2: VC0 not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+
+ SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
+ break;
+ }
+ mdelay(100);
+
+ return 0;
+}
+
+void ppc440spe_setup_pcie_rootpoint(struct pci_controller *hose, int port)
+{
+ volatile void *mbase = NULL;
+ volatile void *rmbase = NULL;
+
+ pci_set_ops(hose,
+ pcie_read_config_byte,
+ pcie_read_config_word,
+ pcie_read_config_dword,
+ pcie_write_config_byte,
+ pcie_write_config_word,
+ pcie_write_config_dword);
+
+ switch (port) {
+ case 0:
+ mbase = (u32 *)CFG_PCIE0_XCFGBASE;
+ rmbase = (u32 *)CFG_PCIE0_CFGBASE;
+ hose->cfg_data = (u8 *)CFG_PCIE0_CFGBASE;
+ break;
+ case 1:
+ mbase = (u32 *)CFG_PCIE1_XCFGBASE;
+ rmbase = (u32 *)CFG_PCIE1_CFGBASE;
+ hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE;
+ break;
+ case 2:
+ mbase = (u32 *)CFG_PCIE2_XCFGBASE;
+ rmbase = (u32 *)CFG_PCIE2_CFGBASE;
+ hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE;
+ break;
+ }
+
+ /*
+ * Set bus numbers on our root port
+ */
+ out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0);
+ out_8((u8 *)mbase + PCI_SECONDARY_BUS, 1);
+ out_8((u8 *)mbase + PCI_SUBORDINATE_BUS, 1);
+
+ /*
+ * Set up outbound translation to hose->mem_space from PLB
+ * addresses at an offset of 0xd_0000_0000. We set the low
+ * bits of the mask to 11 to turn off splitting into 8
+ * subregions and to enable the outbound translation.
+ */
+ out_le32(mbase + PECFG_POM0LAH, 0x00000000);
+ out_le32(mbase + PECFG_POM0LAL, 0x00000000);
+
+ switch (port) {
+ case 0:
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE);
+ mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
+ mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ break;
+ case 1:
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), (CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE));
+ mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
+ mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ break;
+ case 2:
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), (CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE));
+ mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
+ mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ break;
+ }
+
+ /* Set up 16GB inbound memory window at 0 */
+ out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
+ out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
+ out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
+ out_le32(mbase + PECFG_BAR0LMPA, 0);
+
+ out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
+ out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
+ out_le32(mbase + PECFG_PIM0LAL, 0);
+ out_le32(mbase + PECFG_PIM0LAH, 0);
+ out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
+ out_le32(mbase + PECFG_PIM1LAH, 0x00000004);
+ out_le32(mbase + PECFG_PIMEN, 0x1);
+
+ /* Enable I/O, Mem, and Busmaster cycles */
+ out_le16((u16 *)(mbase + PCI_COMMAND),
+ in_le16((u16 *)(mbase + PCI_COMMAND)) |
+ PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+ printf("PCIE:%d successfully set as rootpoint\n",port);
+}
+
+int ppc440spe_setup_pcie_endpoint(struct pci_controller *hose, int port)
+{
+ volatile void *mbase = NULL;
+ int attempts = 0;
+
+ pci_set_ops(hose,
+ pcie_read_config_byte,
+ pcie_read_config_word,
+ pcie_read_config_dword,
+ pcie_write_config_byte,
+ pcie_write_config_word,
+ pcie_write_config_dword);
+
+ switch (port) {
+ case 0:
+ mbase = (u32 *)CFG_PCIE0_XCFGBASE;
+ hose->cfg_data = (u8 *)CFG_PCIE0_CFGBASE;
+ break;
+ case 1:
+ mbase = (u32 *)CFG_PCIE1_XCFGBASE;
+ hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE;
+ break;
+ case 2:
+ mbase = (u32 *)CFG_PCIE2_XCFGBASE;
+ hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE;
+ break;
+ }
+
+ /*
+ * Set up outbound translation to hose->mem_space from PLB
+ * addresses at an offset of 0xd_0000_0000. We set the low
+ * bits of the mask to 11 to turn off splitting into 8
+ * subregions and to enable the outbound translation.
+ */
+ out_le32(mbase + PECFG_POM0LAH, 0x00001ff8);
+ out_le32(mbase + PECFG_POM0LAL, 0x00001000);
+
+ switch (port) {
+ case 0:
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE);
+ mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
+ mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ break;
+ case 1:
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), (CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE));
+ mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
+ mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ break;
+ case 2:
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), (CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE));
+ mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
+ mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ break;
+ }
+
+ /* Set up 16GB inbound memory window at 0 */
+ out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
+ out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
+ out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
+ out_le32(mbase + PECFG_BAR0LMPA, 0);
+ out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
+ out_le32(mbase + PECFG_PIM0LAH, 0x00000004); /* pointing to SRAM */
+ out_le32(mbase + PECFG_PIMEN, 0x1);
+
+ /* Enable I/O, Mem, and Busmaster cycles */
+ out_le16((u16 *)(mbase + PCI_COMMAND),
+ in_le16((u16 *)(mbase + PCI_COMMAND)) |
+ PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+ out_le16(mbase + 0x200,0xcaad); /* Setting vendor ID */
+ out_le16(mbase + 0x202,0xfeed); /* Setting device ID */
+ attempts = 10;
+ switch (port) {
+ case 0:
+ while (!(SDR_READ(PESDR0_RCSSTS) & (1 << 8))) {
+ if (!(attempts--)) {
+ printf("PCIE0: BMEN is not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+ break;
+ case 1:
+ while (!(SDR_READ(PESDR1_RCSSTS) & (1 << 8))) {
+ if (!(attempts--)) {
+ printf("PCIE1: BMEN is not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+ break;
+ case 2:
+ while (!(SDR_READ(PESDR2_RCSSTS) & (1 << 8))) {
+ if (!(attempts--)) {
+ printf("PCIE2: BMEN is not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+ break;
+ }
+ printf("PCIE:%d successfully set as endpoint\n",port);
+
+ return 0;
+}
+#endif /* CONFIG_PCI */
+#endif /* CONFIG_440SPE */
diff --git a/cpu/ppc4xx/440spe_pcie.h b/cpu/ppc4xx/440spe_pcie.h
new file mode 100644
index 0000000..2becc77
--- /dev/null
+++ b/cpu/ppc4xx/440spe_pcie.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ * Roland Dreier <rolandd@cisco.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <ppc4xx.h>
+#ifndef __440SPE_PCIE_H
+#define __440SPE_PCIE_H
+
+#define mdelay(n) ({unsigned long __ms=(n); while (__ms--) udelay(1000);})
+
+#define DCRN_SDR0_CFGADDR 0x00e
+#define DCRN_SDR0_CFGDATA 0x00f
+
+#define DCRN_PCIE0_BASE 0x100
+#define DCRN_PCIE1_BASE 0x120
+#define DCRN_PCIE2_BASE 0x140
+#define PCIE0 DCRN_PCIE0_BASE
+#define PCIE1 DCRN_PCIE1_BASE
+#define PCIE2 DCRN_PCIE2_BASE
+
+#define DCRN_PEGPL_CFGBAH(base) (base + 0x00)
+#define DCRN_PEGPL_CFGBAL(base) (base + 0x01)
+#define DCRN_PEGPL_CFGMSK(base) (base + 0x02)
+#define DCRN_PEGPL_MSGBAH(base) (base + 0x03)
+#define DCRN_PEGPL_MSGBAL(base) (base + 0x04)
+#define DCRN_PEGPL_MSGMSK(base) (base + 0x05)
+#define DCRN_PEGPL_OMR1BAH(base) (base + 0x06)
+#define DCRN_PEGPL_OMR1BAL(base) (base + 0x07)
+#define DCRN_PEGPL_OMR1MSKH(base) (base + 0x08)
+#define DCRN_PEGPL_OMR1MSKL(base) (base + 0x09)
+#define DCRN_PEGPL_REGBAH(base) (base + 0x12)
+#define DCRN_PEGPL_REGBAL(base) (base + 0x13)
+#define DCRN_PEGPL_REGMSK(base) (base + 0x14)
+#define DCRN_PEGPL_SPECIAL(base) (base + 0x15)
+
+/*
+ * System DCRs (SDRs)
+ */
+#define PESDR0_PLLLCT1 0x03a0
+#define PESDR0_PLLLCT2 0x03a1
+#define PESDR0_PLLLCT3 0x03a2
+
+#define PESDR0_UTLSET1 0x0300
+#define PESDR0_UTLSET2 0x0301
+#define PESDR0_DLPSET 0x0302
+#define PESDR0_LOOP 0x0303
+#define PESDR0_RCSSET 0x0304
+#define PESDR0_RCSSTS 0x0305
+#define PESDR0_HSSL0SET1 0x0306
+#define PESDR0_HSSL0SET2 0x0307
+#define PESDR0_HSSL0STS 0x0308
+#define PESDR0_HSSL1SET1 0x0309
+#define PESDR0_HSSL1SET2 0x030a
+#define PESDR0_HSSL1STS 0x030b
+#define PESDR0_HSSL2SET1 0x030c
+#define PESDR0_HSSL2SET2 0x030d
+#define PESDR0_HSSL2STS 0x030e
+#define PESDR0_HSSL3SET1 0x030f
+#define PESDR0_HSSL3SET2 0x0310
+#define PESDR0_HSSL3STS 0x0311
+#define PESDR0_HSSL4SET1 0x0312
+#define PESDR0_HSSL4SET2 0x0313
+#define PESDR0_HSSL4STS 0x0314
+#define PESDR0_HSSL5SET1 0x0315
+#define PESDR0_HSSL5SET2 0x0316
+#define PESDR0_HSSL5STS 0x0317
+#define PESDR0_HSSL6SET1 0x0318
+#define PESDR0_HSSL6SET2 0x0319
+#define PESDR0_HSSL6STS 0x031a
+#define PESDR0_HSSL7SET1 0x031b
+#define PESDR0_HSSL7SET2 0x031c
+#define PESDR0_HSSL7STS 0x031d
+#define PESDR0_HSSCTLSET 0x031e
+#define PESDR0_LANE_ABCD 0x031f
+#define PESDR0_LANE_EFGH 0x0320
+
+#define PESDR1_UTLSET1 0x0340
+#define PESDR1_UTLSET2 0x0341
+#define PESDR1_DLPSET 0x0342
+#define PESDR1_LOOP 0x0343
+#define PESDR1_RCSSET 0x0344
+#define PESDR1_RCSSTS 0x0345
+#define PESDR1_HSSL0SET1 0x0346
+#define PESDR1_HSSL0SET2 0x0347
+#define PESDR1_HSSL0STS 0x0348
+#define PESDR1_HSSL1SET1 0x0349
+#define PESDR1_HSSL1SET2 0x034a
+#define PESDR1_HSSL1STS 0x034b
+#define PESDR1_HSSL2SET1 0x034c
+#define PESDR1_HSSL2SET2 0x034d
+#define PESDR1_HSSL2STS 0x034e
+#define PESDR1_HSSL3SET1 0x034f
+#define PESDR1_HSSL3SET2 0x0350
+#define PESDR1_HSSL3STS 0x0351
+#define PESDR1_HSSCTLSET 0x0352
+#define PESDR1_LANE_ABCD 0x0353
+
+#define PESDR2_UTLSET1 0x0370
+#define PESDR2_UTLSET2 0x0371
+#define PESDR2_DLPSET 0x0372
+#define PESDR2_LOOP 0x0373
+#define PESDR2_RCSSET 0x0374
+#define PESDR2_RCSSTS 0x0375
+#define PESDR2_HSSL0SET1 0x0376
+#define PESDR2_HSSL0SET2 0x0377
+#define PESDR2_HSSL0STS 0x0378
+#define PESDR2_HSSL1SET1 0x0379
+#define PESDR2_HSSL1SET2 0x037a
+#define PESDR2_HSSL1STS 0x037b
+#define PESDR2_HSSL2SET1 0x037c
+#define PESDR2_HSSL2SET2 0x037d
+#define PESDR2_HSSL2STS 0x037e
+#define PESDR2_HSSL3SET1 0x037f
+#define PESDR2_HSSL3SET2 0x0380
+#define PESDR2_HSSL3STS 0x0381
+#define PESDR2_HSSCTLSET 0x0382
+#define PESDR2_LANE_ABCD 0x0383
+
+/*
+ * UTL register offsets
+ */
+#define PEUTL_PBBSZ 0x20
+#define PEUTL_OPDBSZ 0x68
+#define PEUTL_IPHBSZ 0x70
+#define PEUTL_IPDBSZ 0x78
+#define PEUTL_OUTTR 0x90
+#define PEUTL_INTR 0x98
+#define PEUTL_PCTL 0xa0
+#define PEUTL_RCIRQEN 0xb8
+
+/*
+ * Config space register offsets
+ */
+#define PECFG_BAR0LMPA 0x210
+#define PECFG_BAR0HMPA 0x214
+#define PECFG_BAR1MPA 0x218
+#define PECFG_BAR2MPA 0x220
+
+#define PECFG_PIMEN 0x33c
+#define PECFG_PIM0LAL 0x340
+#define PECFG_PIM0LAH 0x344
+#define PECFG_PIM1LAL 0x348
+#define PECFG_PIM1LAH 0x34c
+#define PECFG_PIM01SAL 0x350
+#define PECFG_PIM01SAH 0x354
+
+#define PECFG_POM0LAL 0x380
+#define PECFG_POM0LAH 0x384
+
+#define SDR_READ(offset) ({\
+ mtdcr(DCRN_SDR0_CFGADDR, offset); \
+ mfdcr(DCRN_SDR0_CFGDATA);})
+
+#define SDR_WRITE(offset, data) ({\
+ mtdcr(DCRN_SDR0_CFGADDR, offset); \
+ mtdcr(DCRN_SDR0_CFGDATA,data);})
+
+int ppc440spe_init_pcie(void);
+int ppc440spe_init_pcie_rootport(int port);
+void yucca_setup_pcie_fpga_rootpoint(int port);
+void ppc440spe_setup_pcie_rootpoint(struct pci_controller *hose, int port);
+int ppc440spe_setup_pcie_endpoint(struct pci_controller *hose, int port);
+int yucca_pcie_card_present(int port);
+int pcie_hose_scan(struct pci_controller *hose, int bus);
+#endif /* __440SPE_PCIE_H */
diff --git a/cpu/ppc4xx/4xx_enet.c b/cpu/ppc4xx/4xx_enet.c
index 86dc2d0..5b1c17c 100644
--- a/cpu/ppc4xx/4xx_enet.c
+++ b/cpu/ppc4xx/4xx_enet.c
@@ -130,7 +130,17 @@
#define BI_PHYMODE_NONE 0
#define BI_PHYMODE_ZMII 1
#define BI_PHYMODE_RGMII 2
+#define BI_PHYMODE_GMII 3
+#define BI_PHYMODE_RTBI 4
+#define BI_PHYMODE_TBI 5
+#if defined (CONFIG_440EPX)
+#define BI_PHYMODE_SMII 6
+#define BI_PHYMODE_MII 7
+#endif
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#define SDR0_MFR_ETH_CLK_SEL_V(n) ((0x01<<27) / (n+1))
+#endif
/*-----------------------------------------------------------------------------+
* Global variables. TX and RX descriptors and buffers.
@@ -181,6 +191,9 @@ static void ppc_4xx_eth_halt (struct eth_device *dev)
{
EMAC_4XX_HW_PST hw_p = dev->priv;
uint32_t failsafe = 10000;
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ unsigned long mfr;
+#endif
out32 (EMAC_IER + hw_p->hw_addr, 0x00000000); /* disable emac interrupts */
@@ -202,8 +215,23 @@ static void ppc_4xx_eth_halt (struct eth_device *dev)
}
/* EMAC RESET */
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ /* provide clocks for EMAC internal loopback */
+ mfsdr (sdr_mfr, mfr);
+ mfr |= SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum);
+ mtsdr(sdr_mfr, mfr);
+#endif
+
out32 (EMAC_M0 + hw_p->hw_addr, EMAC_M0_SRST);
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ /* remove clocks for EMAC internal loopback */
+ mfsdr (sdr_mfr, mfr);
+ mfr &= ~SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum);
+ mtsdr(sdr_mfr, mfr);
+#endif
+
+
#ifndef CONFIG_NETCONSOLE
hw_p->print_speed = 1; /* print speed message again next time */
#endif
@@ -299,9 +327,49 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
out32 (RGMII_FER, rmiifer);
return ((int)pfc1);
+}
+#endif /* CONFIG_440_GX */
+
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
+{
+ unsigned long zmiifer=0x0;
+
+ /*
+ * Right now only 2*RGMII is supported. Please extend when needed.
+ * sr - 2006-08-29
+ */
+ switch (1) {
+ case 0:
+ /* 1 x GMII port */
+ out32 (ZMII_FER, 0x00);
+ out32 (RGMII_FER, 0x00000037);
+ bis->bi_phymode[0] = BI_PHYMODE_GMII;
+ bis->bi_phymode[1] = BI_PHYMODE_NONE;
+ break;
+ case 1:
+ /* 2 x RGMII ports */
+ out32 (ZMII_FER, 0x00);
+ out32 (RGMII_FER, 0x00000055);
+ bis->bi_phymode[0] = BI_PHYMODE_RGMII;
+ bis->bi_phymode[1] = BI_PHYMODE_RGMII;
+ break;
+ case 2:
+ /* 2 x SMII ports */
+
+ break;
+ default:
+ break;
+ }
+ /* Ensure we setup mdio for this devnum and ONLY this devnum */
+ zmiifer = in32 (ZMII_FER);
+ zmiifer |= (ZMII_FER_MDI) << ZMII_FER_V(devnum);
+ out32 (ZMII_FER, zmiifer);
+
+ return ((int)0x0);
}
-#endif
+#endif /* CONFIG_440EPX */
static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
{
@@ -314,12 +382,19 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
unsigned mode_reg;
unsigned short devnum;
unsigned short reg_short;
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP)
+#if defined(CONFIG_440GX) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE)
sys_info_t sysinfo;
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
int ethgroup = -1;
#endif
#endif
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || defined(CONFIG_440SPE)
+ unsigned long mfr;
+#endif
+
EMAC_4XX_HW_PST hw_p = dev->priv;
@@ -330,7 +405,9 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
return -1;
}
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP)
+#if defined(CONFIG_440GX) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE)
/* Need to get the OPB frequency so we can access the PHY */
get_sys_info (&sysinfo);
#endif
@@ -360,6 +437,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
hw_p->stats.pkts_tx = 0;
hw_p->stats.pkts_rx = 0;
hw_p->stats.pkts_handled = 0;
+ hw_p->print_speed = 1; /* print speed message again next time */
#endif
hw_p->tx_err_index = 0; /* Transmit Error Index for tx_err_log */
@@ -373,7 +451,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
hw_p->tx_i_index = 0; /* Transmit Interrupt Queue Index */
hw_p->tx_u_index = 0; /* Transmit User Queue Index */
-#if defined(CONFIG_440) && !defined(CONFIG_440SP)
+#if defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE)
/* set RMII mode */
/* NOTE: 440GX spec states that mode is mutually exclusive */
/* NOTE: Therefore, disable all other EMACS, since we handle */
@@ -384,7 +462,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
out32 (ZMII_FER, (ZMII_FER_RMII | ZMII_FER_MDI) << ZMII_FER_V (devnum));
-#elif defined(CONFIG_440GX)
+#elif defined(CONFIG_440GX) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
ethgroup = ppc_4xx_eth_setup_bridge(devnum, bis);
#elif defined(CONFIG_440GP)
/* set RMII mode */
@@ -406,6 +484,12 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
__asm__ volatile ("eieio");
/* reset emac so we have access to the phy */
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ /* provide clocks for EMAC internal loopback */
+ mfsdr (sdr_mfr, mfr);
+ mfr |= SDR0_MFR_ETH_CLK_SEL_V(devnum);
+ mtsdr(sdr_mfr, mfr);
+#endif
out32 (EMAC_M0 + hw_p->hw_addr, EMAC_M0_SRST);
__asm__ volatile ("eieio");
@@ -415,8 +499,19 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
udelay (1000);
failsafe--;
}
+ if (failsafe <= 0)
+ printf("\nProblem resetting EMAC!\n");
+
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ /* remove clocks for EMAC internal loopback */
+ mfsdr (sdr_mfr, mfr);
+ mfr &= ~SDR0_MFR_ETH_CLK_SEL_V(devnum);
+ mtsdr(sdr_mfr, mfr);
+#endif
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP)
+#if defined(CONFIG_440GX) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE)
/* Whack the M1 register */
mode_reg = 0x0;
mode_reg &= ~0x00000038;
@@ -466,15 +561,39 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
* otherwise, just check the speeds & feeds
*/
if (hw_p->first_init == 0) {
+#if defined(CONFIG_88E1111_CLK_DELAY)
+ /*
+ * On some boards (e.g. ALPR) the Marvell 88E1111 PHY needs
+ * the "RGMII transmit timing control" and "RGMII receive
+ * timing control" bits set, so that Gbit communication works
+ * without problems.
+ * Also set the "Transmitter disable" to 1 to enable the
+ * transmitter.
+ * After setting these bits a soft-reset must occur for this
+ * change to become active.
+ */
+ miiphy_read (dev->name, reg, 0x14, &reg_short);
+ reg_short |= (1 << 7) | (1 << 1) | (1 << 0);
+ miiphy_write (dev->name, reg, 0x14, reg_short);
+#endif
+#if defined(CONFIG_M88E1111_PHY) /* test-only: merge with CONFIG_88E1111_CLK_DELAY !!! */
+ miiphy_write (dev->name, reg, 0x14, 0x0ce3);
+ miiphy_write (dev->name, reg, 0x18, 0x4101);
+ miiphy_write (dev->name, reg, 0x09, 0x0e00);
+ miiphy_write (dev->name, reg, 0x04, 0x01e1);
+#endif
miiphy_reset (dev->name, reg);
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP)
+#if defined(CONFIG_440GX) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+
#if defined(CONFIG_CIS8201_PHY)
/*
* Cicada 8201 PHY needs to have an extended register whacked
* for RGMII mode.
*/
- if ( ((devnum == 2) || (devnum ==3)) && (4 == ethgroup) ) {
+ if (((devnum == 2) || (devnum == 3)) && (4 == ethgroup)) {
#if defined(CONFIG_CIS8201_SHORT_ETCH)
miiphy_write (dev->name, reg, 23, 0x1300);
#else
@@ -544,7 +663,8 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
(int) speed, (duplex == HALF) ? "HALF" : "FULL");
}
-#if defined(CONFIG_440) && !defined(CONFIG_440SP)
+#if defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
+ !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
mfsdr(sdr_mfr, reg);
if (speed == 100) {
@@ -567,15 +687,34 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
reg = (RGMII_SSR_SP_1000MBPS << RGMII_SSR_V (devnum));
else if (speed == 100)
reg = (RGMII_SSR_SP_100MBPS << RGMII_SSR_V (devnum));
- else
+ else if (speed == 10)
reg = (RGMII_SSR_SP_10MBPS << RGMII_SSR_V (devnum));
-
+ else {
+ printf("Error in RGMII Speed\n");
+ return -1;
+ }
out32 (RGMII_SSR, reg);
}
#endif /* defined(CONFIG_440) && !defined(CONFIG_440SP) */
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ if (speed == 1000)
+ reg = (RGMII_SSR_SP_1000MBPS << RGMII_SSR_V (devnum));
+ else if (speed == 100)
+ reg = (RGMII_SSR_SP_100MBPS << RGMII_SSR_V (devnum));
+ else if (speed == 10)
+ reg = (RGMII_SSR_SP_10MBPS << RGMII_SSR_V (devnum));
+ else {
+ printf("Error in RGMII Speed\n");
+ return -1;
+ }
+ out32 (RGMII_SSR, reg);
+#endif
+
/* set the Mal configuration reg */
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP)
+#if defined(CONFIG_440GX) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE)
mtdcr (malmcr, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA |
MAL_CR_PLBLT_DEFAULT | MAL_CR_EOPIE | 0x00330000);
#else
@@ -759,9 +898,10 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
/* set speed */
if (speed == _1000BASET) {
-#if defined(CONFIG_440SP)
-#define SDR0_PFC1_EM_1000 0x00200000
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
unsigned long pfc1;
+
mfsdr (sdr_pfc1, pfc1);
pfc1 |= SDR0_PFC1_EM_1000;
mtsdr (sdr_pfc1, pfc1);
@@ -787,7 +927,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
/* set receive low/high water mark register */
#if defined(CONFIG_440)
- /* 440GP has a 64 byte burst length */
+ /* 440s has a 64 byte burst length */
out32 (EMAC_RX_HI_LO_WMARK + hw_p->hw_addr, 0x80009000);
#else
/* 405s have a 16 byte burst length */
@@ -895,7 +1035,7 @@ static int ppc_4xx_eth_send (struct eth_device *dev, volatile void *ptr,
#if defined (CONFIG_440)
-#if defined(CONFIG_440SP)
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
/*
* Hack: On 440SP all enet irq sources are located on UIC1
* Needs some cleanup. --sr
@@ -907,6 +1047,14 @@ static int ppc_4xx_eth_send (struct eth_device *dev, volatile void *ptr,
#define UIC0SR uic0sr
#endif
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#define UICMSR_ETHX uic0msr
+#define UICSR_ETHX uic0sr
+#else
+#define UICMSR_ETHX uic1msr
+#define UICSR_ETHX uic1sr
+#endif
+
int enetInt (struct eth_device *dev)
{
int serviced;
@@ -915,6 +1063,7 @@ int enetInt (struct eth_device *dev)
unsigned long emac_isr = 0;
unsigned long mal_rx_eob;
unsigned long my_uic0msr, my_uic1msr;
+ unsigned long my_uicmsr_ethx;
#if defined(CONFIG_440GX)
unsigned long my_uic2msr;
@@ -942,8 +1091,11 @@ int enetInt (struct eth_device *dev)
#if defined(CONFIG_440GX)
my_uic2msr = mfdcr (uic2msr);
#endif
+ my_uicmsr_ethx = mfdcr (UICMSR_ETHX);
+
if (!(my_uic0msr & (UIC_MRE | UIC_MTE))
- && !(my_uic1msr & (UIC_ETH0 | UIC_ETH1 | UIC_MS | UIC_MTDE | UIC_MRDE))) {
+ && !(my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))
+ && !(my_uicmsr_ethx & (UIC_ETH0 | UIC_ETH1))) {
/* not for us */
return (rc);
}
@@ -962,8 +1114,7 @@ int enetInt (struct eth_device *dev)
mal_isr = mfdcr (malesr);
/* look for mal error */
if (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE)) {
- mal_err (dev, mal_isr, my_uic0msr,
- MAL_UIC_DEF, MAL_UIC_ERR);
+ mal_err (dev, mal_isr, my_uic1msr, MAL_UIC_DEF, MAL_UIC_ERR);
serviced = 1;
rc = 0;
}
@@ -971,7 +1122,7 @@ int enetInt (struct eth_device *dev)
/* port by port dispatch of emac interrupts */
if (hw_p->devnum == 0) {
- if (UIC_ETH0 & my_uic1msr) { /* look for EMAC errors */
+ if (UIC_ETH0 & my_uicmsr_ethx) { /* look for EMAC errors */
emac_isr = in32 (EMAC_ISR + hw_p->hw_addr);
if ((hw_p->emac_ier & emac_isr) != 0) {
emac_err (dev, emac_isr);
@@ -982,14 +1133,15 @@ int enetInt (struct eth_device *dev)
if ((hw_p->emac_ier & emac_isr)
|| (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {
mtdcr (UIC0SR, UIC_MRE | UIC_MTE); /* Clear */
- mtdcr (uic1sr, UIC_ETH0 | UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */
+ mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */
+ mtdcr (UICSR_ETHX, UIC_ETH0); /* Clear */
return (rc); /* we had errors so get out */
}
}
#if !defined(CONFIG_440SP)
if (hw_p->devnum == 1) {
- if (UIC_ETH1 & my_uic1msr) { /* look for EMAC errors */
+ if (UIC_ETH1 & my_uicmsr_ethx) { /* look for EMAC errors */
emac_isr = in32 (EMAC_ISR + hw_p->hw_addr);
if ((hw_p->emac_ier & emac_isr) != 0) {
emac_err (dev, emac_isr);
@@ -1000,7 +1152,8 @@ int enetInt (struct eth_device *dev)
if ((hw_p->emac_ier & emac_isr)
|| (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {
mtdcr (UIC0SR, UIC_MRE | UIC_MTE); /* Clear */
- mtdcr (uic1sr, UIC_ETH1 | UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */
+ mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */
+ mtdcr (UICSR_ETHX, UIC_ETH1); /* Clear */
return (rc); /* we had errors so get out */
}
}
@@ -1067,10 +1220,10 @@ int enetInt (struct eth_device *dev)
mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */
switch (hw_p->devnum) {
case 0:
- mtdcr (uic1sr, UIC_ETH0);
+ mtdcr (UICSR_ETHX, UIC_ETH0);
break;
case 1:
- mtdcr (uic1sr, UIC_ETH1);
+ mtdcr (UICSR_ETHX, UIC_ETH1);
break;
#if defined (CONFIG_440GX)
case 2:
@@ -1367,21 +1520,20 @@ int ppc_4xx_eth_initialize (bd_t * bis)
#endif
/* set phy num and mode */
bis->bi_phynum[0] = CONFIG_PHY_ADDR;
+ bis->bi_phymode[0] = 0;
+
#if defined(CONFIG_PHY1_ADDR)
bis->bi_phynum[1] = CONFIG_PHY1_ADDR;
+ bis->bi_phymode[1] = 0;
#endif
#if defined(CONFIG_440GX)
bis->bi_phynum[2] = CONFIG_PHY2_ADDR;
bis->bi_phynum[3] = CONFIG_PHY3_ADDR;
- bis->bi_phymode[0] = 0;
- bis->bi_phymode[1] = 0;
bis->bi_phymode[2] = 2;
bis->bi_phymode[3] = 2;
-#if defined (CONFIG_440GX)
ppc_4xx_eth_setup_bridge(0, bis);
#endif
-#endif
for (eth_num = 0; eth_num < LAST_EMAC_NUM; eth_num++) {
@@ -1478,9 +1630,15 @@ int ppc_4xx_eth_initialize (bd_t * bis)
if (0 == virgin) {
/* set the MAL IER ??? names may change with new spec ??? */
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ mal_ier =
+ MAL_IER_PT | MAL_IER_PRE | MAL_IER_PWE |
+ MAL_IER_DE | MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE ;
+#else
mal_ier =
MAL_IER_DE | MAL_IER_NE | MAL_IER_TE |
MAL_IER_OPBE | MAL_IER_PLBE;
+#endif
mtdcr (malesr, 0xffffffff); /* clear pending interrupts */
mtdcr (maltxdeir, 0xffffffff); /* clear pending interrupts */
mtdcr (malrxdeir, 0xffffffff); /* clear pending interrupts */
@@ -1510,11 +1668,13 @@ int ppc_4xx_eth_initialize (bd_t * bis)
#else
emac0_dev = dev;
#endif
+
+#if defined(CONFIG_NET_MULTI)
#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
miiphy_register (dev->name,
emac4xx_miiphy_read, emac4xx_miiphy_write);
#endif
-
+#endif
} /* end for each supported device */
return (1);
}
diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile
index c563457..16dc8d6 100644
--- a/cpu/ppc4xx/Makefile
+++ b/cpu/ppc4xx/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,28 +23,31 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o resetvec.o kgdb.o
-AOBJS = dcr.o
+SOBJS = dcr.o
COBJS = 405gp_pci.o 4xx_enet.o \
bedbug_405.o commproc.o \
cpu.o cpu_init.o i2c.o interrupts.o \
- miiphy.o sdram.o serial.o \
- spd_sdram.o speed.o traps.o usb_ohci.o usbdev.o
+ miiphy.o ndfc.o sdram.o serial.o \
+ spd_sdram.o speed.o traps.o usb_ohci.o usbdev.o \
+ 440spe_pcie.o
-OBJS = $(AOBJS) $(COBJS)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-all: .depend $(START) $(LIB)
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c
index 0cd72b0..94478db 100644
--- a/cpu/ppc4xx/cpu.c
+++ b/cpu/ppc4xx/cpu.c
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2000-2003
+ * (C) Copyright 2000-2006
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
@@ -41,14 +41,15 @@
DECLARE_GLOBAL_DATA_PTR;
#endif
-
#if defined(CONFIG_440)
#define FREQ_EBC (sys_info.freqEPB)
#else
#define FREQ_EBC (sys_info.freqPLB / sys_info.pllExtBusDiv)
#endif
-#if defined(CONFIG_405GP) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#if defined(CONFIG_405GP) || \
+ defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
#define PCI_ASYNC
@@ -58,7 +59,8 @@ int pci_async_enabled(void)
return (mfdcr(strap) & PSR_PCI_ASYNC_EN);
#endif
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
unsigned long val;
mfsdr(sdr_sdstp1, val);
@@ -82,7 +84,10 @@ int pci_arbiter_enabled(void)
return (mfdcr(cpc0_strp1) & CPC0_STRP1_PAE_MASK);
#endif
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP)
+#if defined(CONFIG_440GX) || \
+ defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE)
unsigned long val;
mfsdr(sdr_sdstp1, val);
@@ -91,8 +96,10 @@ int pci_arbiter_enabled(void)
}
#endif
-#if defined(CONFIG_405EP)|| defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
- defined(CONFIG_440GX) || defined(CONFIG_440SP)
+#if defined(CONFIG_405EP) || defined(CONFIG_440GX) || \
+ defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE)
#define I2C_BOOTROM
@@ -100,15 +107,75 @@ int i2c_bootrom_enabled(void)
{
#if defined(CONFIG_405EP)
return (mfdcr(cpc0_boot) & CPC0_BOOT_SEP);
-#endif
-
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP)
+#else
unsigned long val;
mfsdr(sdr_sdcs, val);
return (val & SDR0_SDCS_SDD);
#endif
}
+
+#if defined(CONFIG_440GX)
+#define SDR0_PINSTP_SHIFT 29
+static char *bootstrap_str[] = {
+ "EBC (16 bits)",
+ "EBC (8 bits)",
+ "EBC (32 bits)",
+ "EBC (8 bits)",
+ "PCI",
+ "I2C (Addr 0x54)",
+ "Reserved",
+ "I2C (Addr 0x50)",
+};
+#endif
+
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#define SDR0_PINSTP_SHIFT 30
+static char *bootstrap_str[] = {
+ "EBC (8 bits)",
+ "PCI",
+ "I2C (Addr 0x54)",
+ "I2C (Addr 0x50)",
+};
+#endif
+
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#define SDR0_PINSTP_SHIFT 29
+static char *bootstrap_str[] = {
+ "EBC (8 bits)",
+ "PCI",
+ "NAND (8 bits)",
+ "EBC (16 bits)",
+ "EBC (16 bits)",
+ "I2C (Addr 0x54)",
+ "PCI",
+ "I2C (Addr 0x52)",
+};
+#endif
+
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#define SDR0_PINSTP_SHIFT 29
+static char *bootstrap_str[] = {
+ "EBC (8 bits)",
+ "EBC (16 bits)",
+ "EBC (16 bits)",
+ "NAND (8 bits)",
+ "PCI",
+ "I2C (Addr 0x54)",
+ "PCI",
+ "I2C (Addr 0x52)",
+};
+#endif
+
+#if defined(SDR0_PINSTP_SHIFT)
+static int bootstrap_option(void)
+{
+ unsigned long val;
+
+ mfsdr(sdr_pinstp, val);
+ return ((val & 0xe0000000) >> SDR0_PINSTP_SHIFT);
+}
+#endif /* SDR0_PINSTP_SHIFT */
#endif
@@ -223,15 +290,39 @@ int checkcpu (void)
case PVR_440EP_RB: /* 440EP rev B and 440GR rev A have same PVR */
puts("EP Rev. B");
break;
+
+ case PVR_440EP_RC: /* 440EP rev C and 440GR rev B have same PVR */
+ puts("EP Rev. C");
+ break;
#endif /* CONFIG_440EP */
#ifdef CONFIG_440GR
case PVR_440GR_RA: /* 440EP rev B and 440GR rev A have same PVR */
puts("GR Rev. A");
break;
+
+ case PVR_440GR_RB: /* 440EP rev C and 440GR rev B have same PVR */
+ puts("GR Rev. B");
+ break;
#endif /* CONFIG_440GR */
#endif /* CONFIG_440 */
+ case PVR_440EPX1_RA:
+ puts("EPx Rev. A - Security/Kasumi support");
+ break;
+
+ case PVR_440EPX2_RA:
+ puts("EPx Rev. A - No Security/Kasumi support");
+ break;
+
+ case PVR_440GRX1_RA:
+ puts("GRx Rev. A - Security/Kasumi support");
+ break;
+
+ case PVR_440GRX2_RA:
+ puts("GRx Rev. A - No Security/Kasumi support");
+ break;
+
case PVR_440SP_RA:
puts("SP Rev. A");
break;
@@ -240,6 +331,14 @@ int checkcpu (void)
puts("SP Rev. B");
break;
+ case PVR_440SPe_RA:
+ puts("SPe Rev. A");
+ break;
+
+ case PVR_440SPe_RB:
+ puts("SPe Rev. B");
+ break;
+
default:
printf (" UNKNOWN (PVR=%08x)", pvr);
break;
@@ -252,6 +351,10 @@ int checkcpu (void)
#if defined(I2C_BOOTROM)
printf (" I2C boot EEPROM %sabled\n", i2c_bootrom_enabled() ? "en" : "dis");
+#if defined(SDR0_PINSTP_SHIFT)
+ printf (" Bootstrap Option %c - ", (char)bootstrap_option() + 'A');
+ printf ("Boot ROM Location %s\n", bootstrap_str[bootstrap_option()]);
+#endif
#endif
#if defined(CONFIG_PCI)
@@ -295,6 +398,17 @@ int checkcpu (void)
return 0;
}
+#if defined (CONFIG_440SPE)
+int ppc440spe_revB() {
+ unsigned int pvr;
+
+ pvr = get_pvr();
+ if (pvr == PVR_440SPe_RB)
+ return 1;
+ else
+ return 0;
+}
+#endif
/* ------------------------------------------------------------------------- */
diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c
index 1a139d7..b27567f 100644
--- a/cpu/ppc4xx/cpu_init.c
+++ b/cpu/ppc4xx/cpu_init.c
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2000
+ * (C) Copyright 2000-2006
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
@@ -101,6 +101,117 @@ DECLARE_GLOBAL_DATA_PTR;
# endif
#endif /* CFG_INIT_DCACHE_CS */
+#if defined(CFG_440_GPIO_TABLE)
+gpio_param_s gpio_tab[GPIO_GROUP_MAX][GPIO_MAX] = CFG_440_GPIO_TABLE;
+
+void set_chip_gpio_configuration(gpio_param_s (*gpio_tab)[GPIO_GROUP_MAX][GPIO_MAX])
+{
+ unsigned char i=0, j=0, reg_offset = 0, gpio_core;
+ unsigned long gpio_reg, gpio_core_add;
+
+ for (gpio_core=0; gpio_core<GPIO_GROUP_MAX; gpio_core++) {
+ j = 0;
+ reg_offset = 0;
+ /* GPIO config of the GPIOs 0 to 31 */
+ for (i=0; i<GPIO_MAX; i++, j++) {
+ if (i == GPIO_MAX/2) {
+ reg_offset = 4;
+ j = i-16;
+ }
+
+ gpio_core_add = (*gpio_tab)[gpio_core][i].add;
+
+ if (((*gpio_tab)[gpio_core][i].in_out == GPIO_IN) ||
+ ((*gpio_tab)[gpio_core][i].in_out == GPIO_BI)) {
+
+ switch ((*gpio_tab)[gpio_core][i].alt_nb) {
+ case GPIO_SEL:
+ break;
+
+ case GPIO_ALT1:
+ gpio_reg = in32(GPIO_IS1(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_IN_SEL >> (j*2));
+ out32(GPIO_IS1(gpio_core_add+reg_offset), gpio_reg);
+ break;
+
+ case GPIO_ALT2:
+ gpio_reg = in32(GPIO_IS2(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_IN_SEL >> (j*2));
+ out32(GPIO_IS2(gpio_core_add+reg_offset), gpio_reg);
+ break;
+
+ case GPIO_ALT3:
+ gpio_reg = in32(GPIO_IS3(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_IN_SEL >> (j*2));
+ out32(GPIO_IS3(gpio_core_add+reg_offset), gpio_reg);
+ break;
+ }
+ }
+
+ if (((*gpio_tab)[gpio_core][i].in_out == GPIO_OUT) ||
+ ((*gpio_tab)[gpio_core][i].in_out == GPIO_BI)) {
+
+ switch ((*gpio_tab)[gpio_core][i].alt_nb) {
+ case GPIO_SEL:
+ if (gpio_core == GPIO0) {
+ gpio_reg = in32(GPIO0_TCR) | (0x80000000 >> (j));
+ out32(GPIO0_TCR, gpio_reg);
+ }
+
+ if (gpio_core == GPIO1) {
+ gpio_reg = in32(GPIO1_TCR) | (0x80000000 >> (j));
+ out32(GPIO1_TCR, gpio_reg);
+ }
+
+ gpio_reg = in32(GPIO_OS(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ out32(GPIO_OS(gpio_core_add+reg_offset), gpio_reg);
+ gpio_reg = in32(GPIO_TS(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ out32(GPIO_TS(gpio_core_add+reg_offset), gpio_reg);
+ break;
+
+ case GPIO_ALT1:
+ gpio_reg = in32(GPIO_OS(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_ALT1_SEL >> (j*2));
+ out32(GPIO_OS(gpio_core_add+reg_offset), gpio_reg);
+ gpio_reg = in32(GPIO_TS(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_ALT1_SEL >> (j*2));
+ out32(GPIO_TS(gpio_core_add+reg_offset), gpio_reg);
+ break;
+
+ case GPIO_ALT2:
+ gpio_reg = in32(GPIO_OS(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_ALT2_SEL >> (j*2));
+ out32(GPIO_OS(gpio_core_add+reg_offset), gpio_reg);
+ gpio_reg = in32(GPIO_TS(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_ALT2_SEL >> (j*2));
+ out32(GPIO_TS(gpio_core_add+reg_offset), gpio_reg);
+ break;
+
+ case GPIO_ALT3:
+ gpio_reg = in32(GPIO_OS(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_ALT3_SEL >> (j*2));
+ out32(GPIO_OS(gpio_core_add+reg_offset), gpio_reg);
+ gpio_reg = in32(GPIO_TS(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_ALT3_SEL >> (j*2));
+ out32(GPIO_TS(gpio_core_add+reg_offset), gpio_reg);
+ break;
+ }
+ }
+ }
+ }
+}
+#endif /* CFG_440_GPIO_TABLE */
/*
* Breath some life into the CPU...
@@ -129,10 +240,16 @@ cpu_init_f (void)
mtdcr(cpc0_epctl, CPC0_EPRCSR_E0NFE | CPC0_EPRCSR_E1NFE);
#endif /* CONFIG_405EP */
+#if defined(CFG_440_GPIO_TABLE)
+ set_chip_gpio_configuration(&gpio_tab);
+#endif /* CFG_440_GPIO_TABLE */
+
/*
* External Bus Controller (EBC) Setup
*/
#if (defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
+#if (defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
+ defined(CONFIG_405EP) || defined(CONFIG_405))
/*
* Move the next instructions into icache, since these modify the flash
* we are running from!
@@ -148,6 +265,7 @@ cpu_init_f (void)
asm volatile(" ori 3, 3, 0xA000" ::: "r3");
asm volatile(" mtctr 3" ::: "ctr");
asm volatile("2: bdnz 2b" ::: "ctr", "cr0");
+#endif
mtebc(pb0ap, CFG_EBC_PB0AP);
mtebc(pb0cr, CFG_EBC_PB0CR);
diff --git a/cpu/ppc4xx/interrupts.c b/cpu/ppc4xx/interrupts.c
index 3aae4ce..c5a9f02 100644
--- a/cpu/ppc4xx/interrupts.c
+++ b/cpu/ppc4xx/interrupts.c
@@ -50,18 +50,23 @@ struct irq_action {
};
static struct irq_action irq_vecs[32];
+void uic0_interrupt( void * parms); /* UIC0 handler */
#if defined(CONFIG_440)
static struct irq_action irq_vecs1[32]; /* For UIC1 */
void uic1_interrupt( void * parms); /* UIC1 handler */
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
static struct irq_action irq_vecs2[32]; /* For UIC2 */
-
-void uic0_interrupt( void * parms); /* UIC0 handler */
void uic2_interrupt( void * parms); /* UIC2 handler */
-#endif /* CONFIG_440GX */
+#endif /* CONFIG_440GX CONFIG_440SPE */
+
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+static struct irq_action irq_vecs3[32]; /* For UIC3 */
+void uic3_interrupt( void * parms); /* UIC3 handler */
+#endif /* CONFIG_440SPE */
#endif /* CONFIG_440 */
@@ -115,11 +120,17 @@ int interrupt_init_cpu (unsigned *decrementer_count)
irq_vecs1[vec].handler = NULL;
irq_vecs1[vec].arg = NULL;
irq_vecs1[vec].count = 0;
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
irq_vecs2[vec].handler = NULL;
irq_vecs2[vec].arg = NULL;
irq_vecs2[vec].count = 0;
#endif /* CONFIG_440GX */
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ irq_vecs3[vec].handler = NULL;
+ irq_vecs3[vec].arg = NULL;
+ irq_vecs3[vec].count = 0;
+#endif /* CONFIG_440SPE */
#endif
}
@@ -221,6 +232,60 @@ void external_interrupt(struct pt_regs *regs)
} /* external_interrupt CONFIG_440GX */
+#elif defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+void external_interrupt(struct pt_regs *regs)
+{
+ ulong uic_msr;
+
+ /*
+ * Read masked interrupt status register to determine interrupt source
+ */
+ /* 440 SPe uses base uic register */
+ uic_msr = mfdcr(uic0msr);
+
+ if ( (UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr) )
+ uic1_interrupt(0);
+
+ if ( (UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr) )
+ uic2_interrupt(0);
+
+ if (uic_msr & ~(UICB0_ALL))
+ uic0_interrupt(0);
+
+ mtdcr(uic0sr, uic_msr);
+
+ return;
+
+} /* external_interrupt CONFIG_440EPX & CONFIG_440GRX */
+
+#elif defined(CONFIG_440SPE)
+void external_interrupt(struct pt_regs *regs)
+{
+ ulong uic_msr;
+
+ /*
+ * Read masked interrupt status register to determine interrupt source
+ */
+ /* 440 SPe uses base uic register */
+ uic_msr = mfdcr(uic0msr);
+
+ if ( (UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr) )
+ uic1_interrupt(0);
+
+ if ( (UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr) )
+ uic2_interrupt(0);
+
+ if ( (UICB0_UIC3CI & uic_msr) || (UICB0_UIC3NCI & uic_msr) )
+ uic3_interrupt(0);
+
+ if (uic_msr & ~(UICB0_ALL))
+ uic0_interrupt(0);
+
+ mtdcr(uic0sr, uic_msr);
+
+ return;
+} /* external_interrupt CONFIG_440SPE */
+
#else
void external_interrupt(struct pt_regs *regs)
@@ -266,7 +331,8 @@ void external_interrupt(struct pt_regs *regs)
}
#endif
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
/* Handler for UIC0 interrupt */
void uic0_interrupt( void * parms)
{
@@ -357,8 +423,9 @@ void uic1_interrupt( void * parms)
}
#endif /* defined(CONFIG_440) */
-#if defined(CONFIG_440GX)
-/* Handler for UIC1 interrupt */
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+/* Handler for UIC2 interrupt */
void uic2_interrupt( void * parms)
{
ulong uic2_msr;
@@ -384,7 +451,7 @@ void uic2_interrupt( void * parms)
(*irq_vecs2[vec].handler)(irq_vecs2[vec].arg);
} else {
mtdcr(uic2er, mfdcr(uic2er) & ~(0x80000000 >> vec));
- printf ("Masking bogus interrupt vector (uic1) 0x%x\n", vec);
+ printf ("Masking bogus interrupt vector (uic2) 0x%x\n", vec);
}
/*
@@ -402,6 +469,51 @@ void uic2_interrupt( void * parms)
}
#endif /* defined(CONFIG_440GX) */
+#if defined(CONFIG_440SPE)
+/* Handler for UIC3 interrupt */
+void uic3_interrupt( void * parms)
+{
+ ulong uic3_msr;
+ ulong msr_shift;
+ int vec;
+
+ /*
+ * Read masked interrupt status register to determine interrupt source
+ */
+ uic3_msr = mfdcr(uic3msr);
+ msr_shift = uic3_msr;
+ vec = 0;
+
+ while (msr_shift != 0) {
+ if (msr_shift & 0x80000000) {
+ /*
+ * Increment irq counter (for debug purpose only)
+ */
+ irq_vecs3[vec].count++;
+
+ if (irq_vecs3[vec].handler != NULL) {
+ /* call isr */
+ (*irq_vecs3[vec].handler)(irq_vecs3[vec].arg);
+ } else {
+ mtdcr(uic3er, mfdcr(uic3er) & ~(0x80000000 >> vec));
+ printf ("Masking bogus interrupt vector (uic3) 0x%x\n", vec);
+ }
+
+ /*
+ * After servicing the interrupt, we have to remove the status indicator.
+ */
+ mtdcr(uic3sr, (0x80000000 >> vec));
+ }
+
+ /*
+ * Shift msr to next position and increment vector
+ */
+ msr_shift <<= 1;
+ vec++;
+ }
+}
+#endif /* defined(CONFIG_440SPE) */
+
/****************************************************************************/
/*
@@ -414,7 +526,8 @@ void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg)
int i = vec;
#if defined(CONFIG_440)
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
if ((vec > 31) && (vec < 64)) {
i = vec - 32;
irqa = irq_vecs1;
@@ -441,7 +554,8 @@ void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg)
irqa[i].arg = arg;
#if defined(CONFIG_440)
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
if ((vec > 31) && (vec < 64))
mtdcr (uic1er, mfdcr (uic1er) | (0x80000000 >> i));
else if (vec > 63)
@@ -464,7 +578,8 @@ void irq_free_handler (int vec)
int i = vec;
#if defined(CONFIG_440)
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
if ((vec > 31) && (vec < 64)) {
irqa = irq_vecs1;
i = vec - 32;
@@ -485,7 +600,8 @@ void irq_free_handler (int vec)
#endif
#if defined(CONFIG_440)
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
if ((vec > 31) && (vec < 64))
mtdcr (uic1er, mfdcr (uic1er) & ~(0x80000000 >> i));
else if (vec > 63)
@@ -553,7 +669,8 @@ do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
printf("\n");
#endif
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
printf ("\nUIC 2\n");
printf ("Nr Routine Arg Count\n");
@@ -566,6 +683,19 @@ do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
printf("\n");
#endif
+#if defined(CONFIG_440SPE)
+ printf ("\nUIC 3\n");
+ printf ("Nr Routine Arg Count\n");
+
+ for (vec=0; vec<32; vec++) {
+ if (irq_vecs3[vec].handler != NULL)
+ printf ("%02d %08lx %08lx %d\n",
+ vec+63, (ulong)irq_vecs3[vec].handler,
+ (ulong)irq_vecs3[vec].arg, irq_vecs3[vec].count);
+ }
+ printf("\n");
+#endif
+
return 0;
}
#endif /* CONFIG_COMMANDS & CFG_CMD_IRQ */
diff --git a/cpu/ppc4xx/miiphy.c b/cpu/ppc4xx/miiphy.c
index f26f2a2..6b98025 100644
--- a/cpu/ppc4xx/miiphy.c
+++ b/cpu/ppc4xx/miiphy.c
@@ -50,7 +50,7 @@
#include <405_mal.h>
#include <miiphy.h>
-
+#undef ET_DEBUG
/***********************************************************/
/* Dump out to the screen PHY regs */
/***********************************************************/
@@ -90,6 +90,10 @@ int phy_setup_aneg (char *devname, unsigned char addr)
PHY_ANLPAR_10);
miiphy_write (devname, addr, PHY_ANAR, adv);
+ miiphy_read (devname, addr, PHY_1000BTCR, &adv);
+ adv |= (0x0300);
+ miiphy_write (devname, addr, PHY_1000BTCR, adv);
+
/* Start/Restart aneg */
miiphy_read (devname, addr, PHY_BMCR, &ctl);
ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
@@ -104,7 +108,7 @@ int phy_setup_aneg (char *devname, unsigned char addr)
/***********************************************************/
unsigned int miiphy_getemac_offset (void)
{
-#if (defined(CONFIG_440) && !defined(CONFIG_440SP)) && defined(CONFIG_NET_MULTI)
+#if (defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE)) && defined(CONFIG_NET_MULTI)
unsigned long zmii;
unsigned long eoffset;
@@ -155,10 +159,12 @@ int emac4xx_miiphy_read (char *devname, unsigned char addr,
i = 0;
/* see if it is ready for sec */
- while ((in32 (EMAC_STACR + emac_reg) & EMAC_STACR_OC) == 0) {
+ while ((in32 (EMAC_STACR + emac_reg) & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) {
udelay (7);
if (i > 5) {
-#if 0
+#ifdef ET_DEBUG
+ sta_reg = in32 (EMAC_STACR + emac_reg);
+ printf ("read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */
printf ("read err 1\n");
#endif
return -1;
@@ -167,31 +173,44 @@ int emac4xx_miiphy_read (char *devname, unsigned char addr,
}
sta_reg = reg; /* reg address */
/* set clock (50Mhz) and read flags */
-#if defined(CONFIG_440GX)
- sta_reg |= EMAC_STACR_READ;
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#if defined(CONFIG_IBM_EMAC4_V4) /* EMAC4 V4 changed bit setting */
+ sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_READ;
+#else
+ sta_reg |= EMAC_STACR_READ;
+#endif
#else
sta_reg = (sta_reg | EMAC_STACR_READ) & ~EMAC_STACR_CLK_100MHZ;
#endif
-#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX)
+#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && \
+ !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
+ !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ;
#endif
sta_reg = sta_reg | (addr << 5); /* Phy address */
-
+ sta_reg = sta_reg | EMAC_STACR_OC_MASK; /* new IBM emac v4 */
out32 (EMAC_STACR + emac_reg, sta_reg);
-#if 0 /* test-only */
+#ifdef ET_DEBUG
printf ("a2: write: EMAC_STACR=0x%0x\n", sta_reg); /* test-only */
#endif
sta_reg = in32 (EMAC_STACR + emac_reg);
+#ifdef ET_DEBUG
+ printf ("a21: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */
+#endif
i = 0;
- while ((sta_reg & EMAC_STACR_OC) == 0) {
+ while ((sta_reg & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) {
udelay (7);
if (i > 5) {
return -1;
}
i++;
sta_reg = in32 (EMAC_STACR + emac_reg);
+#ifdef ET_DEBUG
+ printf ("a22: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */
+#endif
}
if ((sta_reg & EMAC_STACR_PHYE) != 0) {
return -1;
@@ -219,7 +238,7 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr,
/* see if it is ready for 1000 nsec */
i = 0;
- while ((in32 (EMAC_STACR + emac_reg) & EMAC_STACR_OC) == 0) {
+ while ((in32 (EMAC_STACR + emac_reg) & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) {
if (i > 5)
return -1;
udelay (7);
@@ -228,16 +247,24 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr,
sta_reg = 0;
sta_reg = reg; /* reg address */
/* set clock (50Mhz) and read flags */
-#if defined(CONFIG_440GX)
- sta_reg |= EMAC_STACR_WRITE;
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#if defined(CONFIG_IBM_EMAC4_V4) /* EMAC4 V4 changed bit setting */
+ sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_WRITE;
+#else
+ sta_reg |= EMAC_STACR_WRITE;
+#endif
#else
sta_reg = (sta_reg | EMAC_STACR_WRITE) & ~EMAC_STACR_CLK_100MHZ;
#endif
-#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX)
+#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && \
+ !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
+ !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ; /* Set clock frequency (PLB freq. dependend) */
#endif
- sta_reg = sta_reg | ((unsigned long) addr << 5); /* Phy address */
+ sta_reg = sta_reg | ((unsigned long) addr << 5);/* Phy address */
+ sta_reg = sta_reg | EMAC_STACR_OC_MASK; /* new IBM emac v4 */
memcpy (&sta_reg, &value, 2); /* put in data */
out32 (EMAC_STACR + emac_reg, sta_reg);
@@ -245,12 +272,18 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr,
/* wait for completion */
i = 0;
sta_reg = in32 (EMAC_STACR + emac_reg);
- while ((sta_reg & EMAC_STACR_OC) == 0) {
+#ifdef ET_DEBUG
+ printf ("a31: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */
+#endif
+ while ((sta_reg & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) {
udelay (7);
if (i > 5)
return -1;
i++;
sta_reg = in32 (EMAC_STACR + emac_reg);
+#ifdef ET_DEBUG
+ printf ("a32: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */
+#endif
}
if ((sta_reg & EMAC_STACR_PHYE) != 0)
diff --git a/cpu/ppc4xx/ndfc.c b/cpu/ppc4xx/ndfc.c
new file mode 100644
index 0000000..c255f93
--- /dev/null
+++ b/cpu/ppc4xx/ndfc.c
@@ -0,0 +1,175 @@
+/*
+ * Overview:
+ * Platform independend driver for NDFC (NanD Flash Controller)
+ * integrated into EP440 cores
+ *
+ * (C) Copyright 2006
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * Based on original work by
+ * Thomas Gleixner
+ * Copyright 2006 IBM
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY) && \
+ (defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX))
+
+#include <nand.h>
+#include <linux/mtd/ndfc.h>
+#include <asm/processor.h>
+#include <ppc440.h>
+
+static u8 hwctl = 0;
+
+static void ndfc_hwcontrol(struct mtd_info *mtdinfo, int cmd)
+{
+ switch (cmd) {
+ case NAND_CTL_SETCLE:
+ hwctl |= 0x1;
+ break;
+
+ case NAND_CTL_CLRCLE:
+ hwctl &= ~0x1;
+ break;
+
+ case NAND_CTL_SETALE:
+ hwctl |= 0x2;
+ break;
+
+ case NAND_CTL_CLRALE:
+ hwctl &= ~0x2;
+ break;
+ }
+}
+
+static void ndfc_write_byte(struct mtd_info *mtdinfo, u_char byte)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ ulong base = (ulong) this->IO_ADDR_W;
+
+ if (hwctl & 0x1)
+ out8(base + NDFC_CMD, byte);
+ else if (hwctl & 0x2)
+ out8(base + NDFC_ALE, byte);
+ else
+ out8(base + NDFC_DATA, byte);
+}
+
+static u_char ndfc_read_byte(struct mtd_info *mtdinfo)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ ulong base = (ulong) this->IO_ADDR_W;
+
+ return (in8(base + NDFC_DATA));
+}
+
+static int ndfc_dev_ready(struct mtd_info *mtdinfo)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ ulong base = (ulong) this->IO_ADDR_W;
+
+ while (!(in32(base + NDFC_STAT) & NDFC_STAT_IS_READY))
+ ;
+
+ return 1;
+}
+
+#ifndef CONFIG_NAND_SPL
+/*
+ * Don't use these speedup functions in NAND boot image, since the image
+ * has to fit into 4kByte.
+ */
+
+/*
+ * Speedups for buffer read/write/verify
+ *
+ * NDFC allows 32bit read/write of data. So we can speed up the buffer
+ * functions. No further checking, as nand_base will always read/write
+ * page aligned.
+ */
+static void ndfc_read_buf(struct mtd_info *mtdinfo, uint8_t *buf, int len)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ ulong base = (ulong) this->IO_ADDR_W;
+ uint32_t *p = (uint32_t *) buf;
+
+ for(;len > 0; len -= 4)
+ *p++ = in32(base + NDFC_DATA);
+}
+
+static void ndfc_write_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ ulong base = (ulong) this->IO_ADDR_W;
+ uint32_t *p = (uint32_t *) buf;
+
+ for(; len > 0; len -= 4)
+ out32(base + NDFC_DATA, *p++);
+}
+
+static int ndfc_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ ulong base = (ulong) this->IO_ADDR_W;
+ uint32_t *p = (uint32_t *) buf;
+
+ for(; len > 0; len -= 4)
+ if (*p++ != in32(base + NDFC_DATA))
+ return -1;
+
+ return 0;
+}
+#endif /* #ifndef CONFIG_NAND_SPL */
+
+void board_nand_init(struct nand_chip *nand)
+{
+ nand->eccmode = NAND_ECC_SOFT;
+
+ nand->hwcontrol = ndfc_hwcontrol;
+ nand->read_byte = ndfc_read_byte;
+ nand->write_byte = ndfc_write_byte;
+ nand->dev_ready = ndfc_dev_ready;
+
+#ifndef CONFIG_NAND_SPL
+ nand->write_buf = ndfc_write_buf;
+ nand->read_buf = ndfc_read_buf;
+ nand->verify_buf = ndfc_verify_buf;
+#else
+ /*
+ * Setup EBC (CS0 only right now)
+ */
+ mtdcr(ebccfga, xbcfg);
+ mtdcr(ebccfgd, 0xb8400000);
+
+ mtebc(pb0cr, CFG_EBC_PB0CR);
+ mtebc(pb0ap, CFG_EBC_PB0AP);
+#endif
+
+ /* Set NandFlash Core Configuration Register */
+ /* Chip select 3, 1col x 2 rows */
+ out32(CFG_NAND_BASE + NDFC_CCR, 0x00000000 | (CFG_NAND_CS << 24));
+ out32(CFG_NAND_BASE + NDFC_BCFG0 + (CFG_NAND_CS << 2), 0x80002222);
+}
+
+#endif
diff --git a/cpu/ppc4xx/sdram.c b/cpu/ppc4xx/sdram.c
index e31d59d..faeea5c 100644
--- a/cpu/ppc4xx/sdram.c
+++ b/cpu/ppc4xx/sdram.c
@@ -379,7 +379,7 @@ long int initdram(int board_type)
/*
* Enable the controller, then wait for DCEN to complete
*/
- mtsdram(mem_cfg0, 0x86000000); /* DCEN=1, PMUD=1, 64-bit */
+ mtsdram(mem_cfg0, 0x82000000); /* DCEN=1, PMUD=0, 64-bit */
udelay(10000);
if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
diff --git a/cpu/ppc4xx/serial.c b/cpu/ppc4xx/serial.c
index 83c9479..fab0d95 100644
--- a/cpu/ppc4xx/serial.c
+++ b/cpu/ppc4xx/serial.c
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2000
+ * (C) Copyright 2000-2006
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
@@ -264,10 +264,12 @@ int serial_tstc ()
#endif /* CONFIG_IOP480 */
/*****************************************************************************/
-#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) || defined(CONFIG_405EP)
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405EP) || \
+ defined(CONFIG_440)
#if defined(CONFIG_440)
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
#define UART0_BASE CFG_PERIPHERAL_BASE + 0x00000300
#define UART1_BASE CFG_PERIPHERAL_BASE + 0x00000400
#else
@@ -275,19 +277,38 @@ int serial_tstc ()
#define UART1_BASE CFG_PERIPHERAL_BASE + 0x00000300
#endif
-#if defined(CONFIG_440SP)
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
#define UART2_BASE CFG_PERIPHERAL_BASE + 0x00000600
#endif
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP)
-#define CR0_MASK 0xdfffffff
-#define CR0_EXTCLK_ENA 0x00800000
-#define CR0_UDIV_POS 0
-#else
+#if defined(CONFIG_440GP)
#define CR0_MASK 0x3fff0000
#define CR0_EXTCLK_ENA 0x00600000
#define CR0_UDIV_POS 16
-#endif /* CONFIG_440GX */
+#define UDIV_SUBTRACT 1
+#define UART0_SDR cntrl0
+#define MFREG(a, d) d = mfdcr(a)
+#define MTREG(a, d) mtdcr(a, d)
+#else /* #if defined(CONFIG_440GP) */
+/* all other 440 PPC's access clock divider via sdr register */
+#define CR0_MASK 0xdfffffff
+#define CR0_EXTCLK_ENA 0x00800000
+#define CR0_UDIV_POS 0
+#define UDIV_SUBTRACT 0
+#define UART0_SDR sdr_uart0
+#define UART1_SDR sdr_uart1
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPx) || \
+ defined(CONFIG_440GR) || defined(CONFIG_440GRx) || \
+ defined(CONFIG_440SP) || defined(CONFIG_440SPe)
+#define UART2_SDR sdr_uart2
+#endif
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPx) || \
+ defined(CONFIG_440GR) || defined(CONFIG_440GRx)
+#define UART3_SDR sdr_uart3
+#endif
+#define MFREG(a, d) mfsdr(a, d)
+#define MTREG(a, d) mtsdr(a, d)
+#endif /* #if defined(CONFIG_440GP) */
#elif defined(CONFIG_405EP)
#define UART0_BASE 0xef600300
#define UART1_BASE 0xef600400
@@ -309,17 +330,15 @@ int serial_tstc ()
#if defined(CONFIG_UART1_CONSOLE)
#define ACTING_UART0_BASE UART1_BASE
#define ACTING_UART1_BASE UART0_BASE
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP)
-#define UART0_SDR sdr_uart1
-#define UART1_SDR sdr_uart0
-#endif /* CONFIG_440GX */
#else
#define ACTING_UART0_BASE UART0_BASE
#define ACTING_UART1_BASE UART1_BASE
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP)
-#define UART0_SDR sdr_uart0
-#define UART1_SDR sdr_uart1
-#endif /* CONFIG_440GX */
+#endif
+
+#if defined(CONFIG_SERIAL_MULTI)
+#define UART_BASE dev_base
+#else
+#define UART_BASE ACTING_UART0_BASE
#endif
#if defined(CONFIG_405EP) && defined(CFG_EXT_SERIAL_CLOCK)
@@ -415,7 +434,7 @@ static void serial_divs (int baudrate, unsigned long *pudiv,
*pbdiv = div/udiv;
}
-#endif /* defined(CONFIG_440) && !defined(CFG_EXT_SERIAL_CLK */
+#endif /* defined(CONFIG_440) && !defined(CFG_EXT_SERIAL_CLK) */
/*
* Minimal serial functions needed to use one of the SMC ports
@@ -437,22 +456,9 @@ int serial_init(void)
unsigned long tmp;
#endif
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP)
-#if defined(CONFIG_SERIAL_MULTI)
- if (UART0_BASE == dev_base) {
- mfsdr(UART0_SDR,reg);
- reg &= ~CR0_MASK;
- } else {
- mfsdr(UART1_SDR,reg);
- reg &= ~CR0_MASK;
- }
-#else
- mfsdr(UART0_SDR,reg);
+ MFREG(UART0_SDR, reg);
reg &= ~CR0_MASK;
-#endif
-#else
- reg = mfdcr(cntrl0) & ~CR0_MASK;
-#endif /* CONFIG_440GX */
+
#ifdef CFG_EXT_SERIAL_CLOCK
reg |= CR0_EXTCLK_ENA;
udiv = 1;
@@ -466,45 +472,34 @@ int serial_init(void)
serial_divs (gd->baudrate, &udiv, &bdiv);
#endif
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP)
- reg |= udiv << CR0_UDIV_POS; /* set the UART divisor */
-#if defined(CONFIG_SERIAL_MULTI)
- if (UART0_BASE == dev_base) {
- mtsdr (UART0_SDR,reg);
- } else {
- mtsdr (UART1_SDR,reg);
- }
-#else
- mtsdr (UART0_SDR,reg);
+ reg |= (udiv - UDIV_SUBTRACT) << CR0_UDIV_POS; /* set the UART divisor */
+
+ /*
+ * Configure input clock to baudrate generator for all
+ * available serial ports here
+ */
+ MTREG(UART0_SDR, reg);
+#if defined(UART1_SDR)
+ MTREG(UART1_SDR, reg);
#endif
-#else
- reg |= (udiv - 1) << CR0_UDIV_POS; /* set the UART divisor */
- mtdcr (cntrl0, reg);
+#if defined(UART2_SDR)
+ MTREG(UART2_SDR, reg);
#endif
-
-#if defined(CONFIG_SERIAL_MULTI)
- out8 (dev_base + UART_LCR, 0x80); /* set DLAB bit */
- out8 (dev_base + UART_DLL, bdiv); /* set baudrate divisor */
- out8 (dev_base + UART_DLM, bdiv >> 8);/* set baudrate divisor */
- out8 (dev_base + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
- out8 (dev_base + UART_FCR, 0x00); /* disable FIFO */
- out8 (dev_base + UART_MCR, 0x00); /* no modem control DTR RTS */
- val = in8 (dev_base + UART_LSR); /* clear line status */
- val = in8 (dev_base + UART_RBR); /* read receive buffer */
- out8 (dev_base + UART_SCR, 0x00); /* set scratchpad */
- out8 (dev_base + UART_IER, 0x00); /* set interrupt enable reg */
-#else
- out8 (ACTING_UART0_BASE + UART_LCR, 0x80); /* set DLAB bit */
- out8 (ACTING_UART0_BASE + UART_DLL, bdiv); /* set baudrate divisor */
- out8 (ACTING_UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
- out8 (ACTING_UART0_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
- out8 (ACTING_UART0_BASE + UART_FCR, 0x00); /* disable FIFO */
- out8 (ACTING_UART0_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */
- val = in8 (ACTING_UART0_BASE + UART_LSR); /* clear line status */
- val = in8 (ACTING_UART0_BASE + UART_RBR); /* read receive buffer */
- out8 (ACTING_UART0_BASE + UART_SCR, 0x00); /* set scratchpad */
- out8 (ACTING_UART0_BASE + UART_IER, 0x00); /* set interrupt enable reg */
+#if defined(UART3_SDR)
+ MTREG(UART3_SDR, reg);
#endif
+
+ out8(UART_BASE + UART_LCR, 0x80); /* set DLAB bit */
+ out8(UART_BASE + UART_DLL, bdiv); /* set baudrate divisor */
+ out8(UART_BASE + UART_DLM, bdiv >> 8); /* set baudrate divisor */
+ out8(UART_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
+ out8(UART_BASE + UART_FCR, 0x00); /* disable FIFO */
+ out8(UART_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */
+ val = in8(UART_BASE + UART_LSR); /* clear line status */
+ val = in8(UART_BASE + UART_RBR); /* read receive buffer */
+ out8(UART_BASE + UART_SCR, 0x00); /* set scratchpad */
+ out8(UART_BASE + UART_IER, 0x00); /* set interrupt enable reg */
+
return (0);
}
@@ -557,29 +552,17 @@ int serial_init (void)
tmp = gd->baudrate * udiv * 16;
bdiv = (clk + tmp / 2) / tmp;
-#if defined(CONFIG_SERIAL_MULTI)
- out8 (dev_base + UART_LCR, 0x80); /* set DLAB bit */
- out8 (dev_base + UART_DLL, bdiv); /* set baudrate divisor */
- out8 (dev_base + UART_DLM, bdiv >> 8);/* set baudrate divisor */
- out8 (dev_base + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
- out8 (dev_base + UART_FCR, 0x00); /* disable FIFO */
- out8 (dev_base + UART_MCR, 0x00); /* no modem control DTR RTS */
- val = in8 (dev_base + UART_LSR); /* clear line status */
- val = in8 (dev_base + UART_RBR); /* read receive buffer */
- out8 (dev_base + UART_SCR, 0x00); /* set scratchpad */
- out8 (dev_base + UART_IER, 0x00); /* set interrupt enable reg */
-#else
- out8 (ACTING_UART0_BASE + UART_LCR, 0x80); /* set DLAB bit */
- out8 (ACTING_UART0_BASE + UART_DLL, bdiv); /* set baudrate divisor */
- out8 (ACTING_UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
- out8 (ACTING_UART0_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
- out8 (ACTING_UART0_BASE + UART_FCR, 0x00); /* disable FIFO */
- out8 (ACTING_UART0_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */
- val = in8 (ACTING_UART0_BASE + UART_LSR); /* clear line status */
- val = in8 (ACTING_UART0_BASE + UART_RBR); /* read receive buffer */
- out8 (ACTING_UART0_BASE + UART_SCR, 0x00); /* set scratchpad */
- out8 (ACTING_UART0_BASE + UART_IER, 0x00); /* set interrupt enable reg */
-#endif
+ out8(UART_BASE + UART_LCR, 0x80); /* set DLAB bit */
+ out8(UART_BASE + UART_DLL, bdiv); /* set baudrate divisor */
+ out8(UART_BASE + UART_DLM, bdiv >> 8); /* set baudrate divisor */
+ out8(UART_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
+ out8(UART_BASE + UART_FCR, 0x00); /* disable FIFO */
+ out8(UART_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */
+ val = in8(UART_BASE + UART_LSR); /* clear line status */
+ val = in8(UART_BASE + UART_RBR); /* read receive buffer */
+ out8(UART_BASE + UART_SCR, 0x00); /* set scratchpad */
+ out8(UART_BASE + UART_IER, 0x00); /* set interrupt enable reg */
+
return (0);
}
@@ -591,35 +574,10 @@ void serial_setbrg_dev (unsigned long dev_base)
void serial_setbrg (void)
#endif
{
- unsigned long tmp;
- unsigned long clk;
- unsigned long udiv;
- unsigned short bdiv;
-
-#ifdef CFG_EXT_SERIAL_CLOCK
- clk = CFG_EXT_SERIAL_CLOCK;
-#else
- clk = gd->cpu_clk;
-#endif
-
-#ifdef CONFIG_405EP
- udiv = ((mfdcr (cpc0_ucr) & UCR0_MASK) >> UCR0_UDIV_POS);
-#else
- udiv = ((mfdcr (cntrl0) & 0x3e) >> 1) + 1;
-#endif /* CONFIG_405EP */
- tmp = gd->baudrate * udiv * 16;
- bdiv = (clk + tmp / 2) / tmp;
-
#if defined(CONFIG_SERIAL_MULTI)
- out8 (dev_base + UART_LCR, 0x80); /* set DLAB bit */
- out8 (dev_base + UART_DLL, bdiv); /* set baudrate divisor */
- out8 (dev_base + UART_DLM, bdiv >> 8);/* set baudrate divisor */
- out8 (dev_base + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
+ serial_init_dev(dev_base);
#else
- out8 (ACTING_UART0_BASE + UART_LCR, 0x80); /* set DLAB bit */
- out8 (ACTING_UART0_BASE + UART_DLL, bdiv); /* set baudrate divisor */
- out8 (ACTING_UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
- out8 (ACTING_UART0_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
+ serial_init();
#endif
}
@@ -640,19 +598,11 @@ void serial_putc (const char c)
/* check THRE bit, wait for transmiter available */
for (i = 1; i < 3500; i++) {
-#if defined(CONFIG_SERIAL_MULTI)
- if ((in8 (dev_base + UART_LSR) & 0x20) == 0x20)
-#else
- if ((in8 (ACTING_UART0_BASE + UART_LSR) & 0x20) == 0x20)
-#endif
+ if ((in8 (UART_BASE + UART_LSR) & 0x20) == 0x20)
break;
udelay (100);
}
-#if defined(CONFIG_SERIAL_MULTI)
- out8 (dev_base + UART_THR, c); /* put character out */
-#else
- out8 (ACTING_UART0_BASE + UART_THR, c); /* put character out */
-#endif
+ out8 (UART_BASE + UART_THR, c); /* put character out */
}
#if defined(CONFIG_SERIAL_MULTI)
@@ -682,11 +632,7 @@ int serial_getc (void)
#if defined(CONFIG_HW_WATCHDOG)
WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */
#endif /* CONFIG_HW_WATCHDOG */
-#if defined(CONFIG_SERIAL_MULTI)
- status = in8 (dev_base + UART_LSR);
-#else
- status = in8 (ACTING_UART0_BASE + UART_LSR);
-#endif
+ status = in8 (UART_BASE + UART_LSR);
if ((status & asyncLSRDataReady1) != 0x0) {
break;
}
@@ -694,22 +640,14 @@ int serial_getc (void)
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1 )) != 0) {
-#if defined(CONFIG_SERIAL_MULTI)
- out8 (dev_base + UART_LSR,
-#else
- out8 (ACTING_UART0_BASE + UART_LSR,
-#endif
+ out8 (UART_BASE + UART_LSR,
asyncLSRFramingError1 |
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1);
}
}
-#if defined(CONFIG_SERIAL_MULTI)
- return (0x000000ff & (int) in8 (dev_base));
-#else
- return (0x000000ff & (int) in8 (ACTING_UART0_BASE));
-#endif
+ return (0x000000ff & (int) in8 (UART_BASE));
}
#if defined(CONFIG_SERIAL_MULTI)
@@ -720,11 +658,7 @@ int serial_tstc (void)
{
unsigned char status;
-#if defined(CONFIG_SERIAL_MULTI)
- status = in8 (dev_base + UART_LSR);
-#else
- status = in8 (ACTING_UART0_BASE + UART_LSR);
-#endif
+ status = in8 (UART_BASE + UART_LSR);
if ((status & asyncLSRDataReady1) != 0x0) {
return (1);
}
@@ -732,11 +666,7 @@ int serial_tstc (void)
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1 )) != 0) {
-#if defined(CONFIG_SERIAL_MULTI)
- out8 (dev_base + UART_LSR,
-#else
- out8 (ACTING_UART0_BASE + UART_LSR,
-#endif
+ out8 (UART_BASE + UART_LSR,
asyncLSRFramingError1 |
asyncLSROverrunError1 |
asyncLSRParityError1 |
diff --git a/cpu/ppc4xx/spd_sdram.c b/cpu/ppc4xx/spd_sdram.c
index ebd5f39..c24456b 100644
--- a/cpu/ppc4xx/spd_sdram.c
+++ b/cpu/ppc4xx/spd_sdram.c
@@ -745,7 +745,7 @@ long int spd_sdram(void) {
*/
check_volt_type(dimm_populated, iic0_dimm_addr, num_dimm_banks);
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP)
/*
* Soft-reset SDRAM controller.
*/
@@ -1007,9 +1007,9 @@ void program_cfg0(unsigned long* dimm_populated,
}
/*
- * program Page Management Unit
+ * program Page Management Unit (0 == enabled)
*/
- cfg0 |= SDRAM_CFG0_PMUD;
+ cfg0 &= ~SDRAM_CFG0_PMUD;
/*
* program Memory Controller Options 0
diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c
index 02b4383..2d16a83 100644
--- a/cpu/ppc4xx/speed.c
+++ b/cpu/ppc4xx/speed.c
@@ -29,7 +29,11 @@
DECLARE_GLOBAL_DATA_PTR;
#define ONE_BILLION 1000000000
-
+#ifdef DEBUG
+#define DEBUGF(fmt,args...) printf(fmt ,##args)
+#else
+#define DEBUGF(fmt,args...)
+#endif
#if defined(CONFIG_405GP) || defined(CONFIG_405CR)
@@ -195,7 +199,8 @@ ulong get_PCI_freq (void)
#elif defined(CONFIG_440)
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
void get_sys_info (sys_info_t *sysInfo)
{
unsigned long temp;
@@ -283,7 +288,7 @@ ulong get_PCI_freq (void)
return sys_info.freqPCI;
}
-#elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP)
+#elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE)
void get_sys_info (sys_info_t * sysInfo)
{
unsigned long strp0;
@@ -326,6 +331,26 @@ void get_sys_info (sys_info_t * sysInfo)
unsigned long m;
unsigned long prbdv0;
+#if defined(CONFIG_440SPE)
+ unsigned long sys_freq;
+ unsigned long sys_per=0;
+ unsigned long msr;
+ unsigned long pci_clock_per;
+ unsigned long sdr_ddrpll;
+
+ /*-------------------------------------------------------------------------+
+ | Get the system clock period.
+ +-------------------------------------------------------------------------*/
+ sys_per = determine_sysper();
+
+ msr = (mfmsr () & ~(MSR_EE)); /* disable interrupts */
+
+ /*-------------------------------------------------------------------------+
+ | Calculate the system clock speed from the period.
+ +-------------------------------------------------------------------------*/
+ sys_freq=(ONE_BILLION/sys_per)*1000;
+#endif
+
/* Extract configured divisors */
mfsdr( sdr_sdstp0,strp0 );
mfsdr( sdr_sdstp1,strp1 );
@@ -360,12 +385,238 @@ void get_sys_info (sys_info_t * sysInfo)
m = sysInfo->pllExtBusDiv * sysInfo->pllOpbDiv * sysInfo->pllFwdDivB;
/* Now calculate the individual clocks */
+#if defined(CONFIG_440SPE)
+ sysInfo->freqVCOMhz = (m * sys_freq) ;
+#else
sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m>>1);
+#endif
sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB/prbdv0;
sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
sysInfo->freqEPB = sysInfo->freqOPB/sysInfo->pllExtBusDiv;
+#if defined(CONFIG_440SPE)
+ /* Determine PCI Clock Period */
+ pci_clock_per = determine_pci_clock_per();
+ sysInfo->freqPCI = (ONE_BILLION/pci_clock_per) * 1000;
+ mfsdr(sdr_ddr0, sdr_ddrpll);
+ sysInfo->freqDDR = ((sysInfo->freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll));
+#endif
+
+
+}
+
+#endif
+
+#if defined(CONFIG_440SPE)
+unsigned long determine_sysper(void)
+{
+ unsigned int fpga_clocking_reg;
+ unsigned int master_clock_selection;
+ unsigned long master_clock_per = 0;
+ unsigned long fb_div_selection;
+ unsigned int vco_div_reg_value;
+ unsigned long vco_div_selection;
+ unsigned long sys_per = 0;
+ int extClkVal;
+
+ /*-------------------------------------------------------------------------+
+ | Read FPGA reg 0 and reg 1 to get FPGA reg information
+ +-------------------------------------------------------------------------*/
+ fpga_clocking_reg = in16(FPGA_REG16);
+
+
+ /* Determine Master Clock Source Selection */
+ master_clock_selection = fpga_clocking_reg & FPGA_REG16_MASTER_CLK_MASK;
+
+ switch(master_clock_selection) {
+ case FPGA_REG16_MASTER_CLK_66_66:
+ master_clock_per = PERIOD_66_66MHZ;
+ break;
+ case FPGA_REG16_MASTER_CLK_50:
+ master_clock_per = PERIOD_50_00MHZ;
+ break;
+ case FPGA_REG16_MASTER_CLK_33_33:
+ master_clock_per = PERIOD_33_33MHZ;
+ break;
+ case FPGA_REG16_MASTER_CLK_25:
+ master_clock_per = PERIOD_25_00MHZ;
+ break;
+ case FPGA_REG16_MASTER_CLK_EXT:
+ if ((extClkVal==EXTCLK_33_33)
+ && (extClkVal==EXTCLK_50)
+ && (extClkVal==EXTCLK_66_66)
+ && (extClkVal==EXTCLK_83)) {
+ /* calculate master clock period from external clock value */
+ master_clock_per=(ONE_BILLION/extClkVal) * 1000;
+ } else {
+ /* Unsupported */
+ DEBUGF ("%s[%d] *** master clock selection failed ***\n", __FUNCTION__,__LINE__);
+ hang();
+ }
+ break;
+ default:
+ /* Unsupported */
+ DEBUGF ("%s[%d] *** master clock selection failed ***\n", __FUNCTION__,__LINE__);
+ hang();
+ break;
+ }
+
+ /* Determine FB divisors values */
+ if ((fpga_clocking_reg & FPGA_REG16_FB1_DIV_MASK) == FPGA_REG16_FB1_DIV_LOW) {
+ if ((fpga_clocking_reg & FPGA_REG16_FB2_DIV_MASK) == FPGA_REG16_FB2_DIV_LOW)
+ fb_div_selection = FPGA_FB_DIV_6;
+ else
+ fb_div_selection = FPGA_FB_DIV_12;
+ } else {
+ if ((fpga_clocking_reg & FPGA_REG16_FB2_DIV_MASK) == FPGA_REG16_FB2_DIV_LOW)
+ fb_div_selection = FPGA_FB_DIV_10;
+ else
+ fb_div_selection = FPGA_FB_DIV_20;
+ }
+
+ /* Determine VCO divisors values */
+ vco_div_reg_value = fpga_clocking_reg & FPGA_REG16_VCO_DIV_MASK;
+
+ switch(vco_div_reg_value) {
+ case FPGA_REG16_VCO_DIV_4:
+ vco_div_selection = FPGA_VCO_DIV_4;
+ break;
+ case FPGA_REG16_VCO_DIV_6:
+ vco_div_selection = FPGA_VCO_DIV_6;
+ break;
+ case FPGA_REG16_VCO_DIV_8:
+ vco_div_selection = FPGA_VCO_DIV_8;
+ break;
+ case FPGA_REG16_VCO_DIV_10:
+ default:
+ vco_div_selection = FPGA_VCO_DIV_10;
+ break;
+ }
+
+ if (master_clock_selection == FPGA_REG16_MASTER_CLK_EXT) {
+ switch(master_clock_per) {
+ case PERIOD_25_00MHZ:
+ if (fb_div_selection == FPGA_FB_DIV_12) {
+ if (vco_div_selection == FPGA_VCO_DIV_4)
+ sys_per = PERIOD_75_00MHZ;
+ if (vco_div_selection == FPGA_VCO_DIV_6)
+ sys_per = PERIOD_50_00MHZ;
+ }
+ break;
+ case PERIOD_33_33MHZ:
+ if (fb_div_selection == FPGA_FB_DIV_6) {
+ if (vco_div_selection == FPGA_VCO_DIV_4)
+ sys_per = PERIOD_50_00MHZ;
+ if (vco_div_selection == FPGA_VCO_DIV_6)
+ sys_per = PERIOD_33_33MHZ;
+ }
+ if (fb_div_selection == FPGA_FB_DIV_10) {
+ if (vco_div_selection == FPGA_VCO_DIV_4)
+ sys_per = PERIOD_83_33MHZ;
+ if (vco_div_selection == FPGA_VCO_DIV_10)
+ sys_per = PERIOD_33_33MHZ;
+ }
+ if (fb_div_selection == FPGA_FB_DIV_12) {
+ if (vco_div_selection == FPGA_VCO_DIV_4)
+ sys_per = PERIOD_100_00MHZ;
+ if (vco_div_selection == FPGA_VCO_DIV_6)
+ sys_per = PERIOD_66_66MHZ;
+ if (vco_div_selection == FPGA_VCO_DIV_8)
+ sys_per = PERIOD_50_00MHZ;
+ }
+ break;
+ case PERIOD_50_00MHZ:
+ if (fb_div_selection == FPGA_FB_DIV_6) {
+ if (vco_div_selection == FPGA_VCO_DIV_4)
+ sys_per = PERIOD_75_00MHZ;
+ if (vco_div_selection == FPGA_VCO_DIV_6)
+ sys_per = PERIOD_50_00MHZ;
+ }
+ if (fb_div_selection == FPGA_FB_DIV_10) {
+ if (vco_div_selection == FPGA_VCO_DIV_6)
+ sys_per = PERIOD_83_33MHZ;
+ if (vco_div_selection == FPGA_VCO_DIV_10)
+ sys_per = PERIOD_50_00MHZ;
+ }
+ if (fb_div_selection == FPGA_FB_DIV_12) {
+ if (vco_div_selection == FPGA_VCO_DIV_6)
+ sys_per = PERIOD_100_00MHZ;
+ if (vco_div_selection == FPGA_VCO_DIV_8)
+ sys_per = PERIOD_75_00MHZ;
+ }
+ break;
+ case PERIOD_66_66MHZ:
+ if (fb_div_selection == FPGA_FB_DIV_6) {
+ if (vco_div_selection == FPGA_VCO_DIV_4)
+ sys_per = PERIOD_100_00MHZ;
+ if (vco_div_selection == FPGA_VCO_DIV_6)
+ sys_per = PERIOD_66_66MHZ;
+ if (vco_div_selection == FPGA_VCO_DIV_8)
+ sys_per = PERIOD_50_00MHZ;
+ }
+ if (fb_div_selection == FPGA_FB_DIV_10) {
+ if (vco_div_selection == FPGA_VCO_DIV_8)
+ sys_per = PERIOD_83_33MHZ;
+ if (vco_div_selection == FPGA_VCO_DIV_10)
+ sys_per = PERIOD_66_66MHZ;
+ }
+ if (fb_div_selection == FPGA_FB_DIV_12) {
+ if (vco_div_selection == FPGA_VCO_DIV_8)
+ sys_per = PERIOD_100_00MHZ;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (sys_per == 0) {
+ /* Other combinations are not supported */
+ DEBUGF ("%s[%d] *** sys period compute failed ***\n", __FUNCTION__,__LINE__);
+ hang();
+ }
+ } else {
+ /* calcul system clock without cheking */
+ /* if engineering option clock no check is selected */
+ /* sys_per = master_clock_per * vco_div_selection / fb_div_selection */
+ sys_per = (master_clock_per/fb_div_selection) * vco_div_selection;
+ }
+
+ return(sys_per);
+
+}
+
+/*-------------------------------------------------------------------------+
+| determine_pci_clock_per.
++-------------------------------------------------------------------------*/
+unsigned long determine_pci_clock_per(void)
+{
+ unsigned long pci_clock_selection, pci_period;
+
+ /*-------------------------------------------------------------------------+
+ | Read FPGA reg 6 to get PCI 0 FPGA reg information
+ +-------------------------------------------------------------------------*/
+ pci_clock_selection = in16(FPGA_REG16); /* was reg6 averifier */
+
+
+ pci_clock_selection = pci_clock_selection & FPGA_REG16_PCI0_CLK_MASK;
+
+ switch (pci_clock_selection) {
+ case FPGA_REG16_PCI0_CLK_133_33:
+ pci_period = PERIOD_133_33MHZ;
+ break;
+ case FPGA_REG16_PCI0_CLK_100:
+ pci_period = PERIOD_100_00MHZ;
+ break;
+ case FPGA_REG16_PCI0_CLK_66_66:
+ pci_period = PERIOD_66_66MHZ;
+ break;
+ default:
+ pci_period = PERIOD_33_33MHZ;;
+ break;
+ }
+
+ return(pci_period);
}
#endif
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index 948de43..5a1ab38 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -117,12 +117,16 @@
.extern ext_bus_cntlr_init
.extern sdram_init
+#ifdef CONFIG_NAND_U_BOOT
+ .extern reconfig_tlb0
+#endif
/*
* Set up GOT: Global Offset Table
*
* Use r14 to access the GOT
*/
+#if !defined(CONFIG_NAND_SPL)
START_GOT
GOT_ENTRY(_GOT2_TABLE_)
GOT_ENTRY(_FIXUP_TABLE_)
@@ -136,6 +140,18 @@
GOT_ENTRY(_end)
GOT_ENTRY(__bss_start)
END_GOT
+#endif /* CONFIG_NAND_SPL */
+
+#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
+ /*
+ * NAND U-Boot image is started from offset 0
+ */
+ .text
+ bl reconfig_tlb0
+ GET_GOT
+ bl cpu_init_f /* run low-level CPU init code (from Flash) */
+ bl board_init_f
+#endif
/*
* 440 Startup -- on reset only the top 4k of the effective
@@ -150,11 +166,26 @@
*/
#if defined(CONFIG_440)
+#if !defined(CONFIG_NAND_SPL)
.section .bootpg,"ax"
+#endif
.globl _start_440
/**************************************************************************/
_start_440:
+ /*--------------------------------------------------------------------+
+ | 440EPX BUP Change - Hardware team request
+ +--------------------------------------------------------------------*/
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ sync
+ nop
+ nop
+#endif
+ /*----------------------------------------------------------------+
+ | Core bug fix. Clear the esr
+ +-----------------------------------------------------------------*/
+ li r0,0
+ mtspr esr,r0
/*----------------------------------------------------------------*/
/* Clear and set up some registers. */
/*----------------------------------------------------------------*/
@@ -166,15 +197,19 @@ _start_440:
mtspr srr1,r0
mtspr csrr0,r0
mtspr csrr1,r0
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) /* NOTE: 440GX adds machine check status regs */
+ /* NOTE: 440GX adds machine check status regs */
+#if defined(CONFIG_440) && !defined(CONFIG_440GP)
mtspr mcsrr0,r0
mtspr mcsrr1,r0
- mfspr r1, mcsr
+ mfspr r1,mcsr
mtspr mcsr,r1
#endif
/*----------------------------------------------------------------*/
/* Initialize debug */
/*----------------------------------------------------------------*/
+ mfspr r1,dbcr0
+ andis. r1, r1, 0x8000 /* test DBCR0[EDM] bit */
+ bne skip_debug_init /* if set, don't clear debug register */
mtspr dbcr0,r0
mtspr dbcr1,r0
mtspr dbcr2,r0
@@ -188,6 +223,7 @@ _start_440:
mfspr r1,dbsr
mtspr dbsr,r1 /* Clear all valid bits */
+skip_debug_init:
/*----------------------------------------------------------------*/
/* CCR0 init */
@@ -200,6 +236,31 @@ _start_440:
ori r1,r1,0x6000 /* cache touch */
mtspr ccr0,r1
+#if defined (CONFIG_440SPE)
+ /*----------------------------------------------------------------+
+ | Initialize Core Configuration Reg1.
+ | a. ICDPEI: Record even parity. Normal operation.
+ | b. ICTPEI: Record even parity. Normal operation.
+ | c. DCTPEI: Record even parity. Normal operation.
+ | d. DCDPEI: Record even parity. Normal operation.
+ | e. DCUPEI: Record even parity. Normal operation.
+ | f. DCMPEI: Record even parity. Normal operation.
+ | g. FCOM: Normal operation
+ | h. MMUPEI: Record even parity. Normal operation.
+ | i. FFF: Flush only as much data as necessary.
+ | j. TCS: Timebase increments from CPU clock.
+ +-----------------------------------------------------------------*/
+ li r0,0
+ mtspr ccr1, r0
+
+ /*----------------------------------------------------------------+
+ | Reset the timebase.
+ | The previous write to CCR1 sets the timebase source.
+ +-----------------------------------------------------------------*/
+ mtspr tbl, r0
+ mtspr tbu, r0
+#endif
+
/*----------------------------------------------------------------*/
/* Setup interrupt vectors */
/*----------------------------------------------------------------*/
@@ -261,20 +322,47 @@ _start_440:
mtspr ivlim,r1
mtspr dvlim,r1
+ /*----------------------------------------------------------------+
+ |Initialize MMUCR[STID] = 0.
+ +-----------------------------------------------------------------*/
+ mfspr r0,mmucr
+ addis r1,0,0xFFFF
+ ori r1,r1,0xFF00
+ and r0,r0,r1
+ mtspr mmucr,r0
+
/*----------------------------------------------------------------*/
/* Clear all TLB entries -- TID = 0, TS = 0 */
/*----------------------------------------------------------------*/
- mtspr mmucr,r0
+ addis r0,0,0x0000
li r1,0x003f /* 64 TLB entries */
mtctr r1
-0: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/
+rsttlb: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/
+ tlbwe r0,r1,0x0001
+ tlbwe r0,r1,0x0002
subi r1,r1,0x0001
- bdnz 0b
+ bdnz rsttlb
/*----------------------------------------------------------------*/
/* TLB entry setup -- step thru tlbtab */
/*----------------------------------------------------------------*/
+#if defined(CONFIG_440SPE)
+ /*----------------------------------------------------------------*/
+ /* We have different TLB tables for revA and rev B of 440SPe */
+ /*----------------------------------------------------------------*/
+ mfspr r1, PVR
+ lis r0,0x5342
+ ori r0,r0,0x1891
+ cmpw r7,r1,r0
+ bne r7,..revA
+ bl tlbtabB
+ b ..goon
+..revA:
+ bl tlbtabA
+..goon:
+#else
bl tlbtab /* Get tlbtab pointer */
+#endif
mr r5,r0
li r1,0x003f /* 64 TLB entries max */
mtctr r1
@@ -295,7 +383,53 @@ _start_440:
/*----------------------------------------------------------------*/
/* Continue from 'normal' start */
/*----------------------------------------------------------------*/
-2: bl 3f
+2:
+
+#if defined(CONFIG_NAND_SPL)
+ /*
+ * Enable internal SRAM
+ */
+ lis r2,0x7fff
+ ori r2,r2,0xffff
+ mfdcr r1,isram0_dpc
+ and r1,r1,r2 /* Disable parity check */
+ mtdcr isram0_dpc,r1
+ mfdcr r1,isram0_pmeg
+ and r1,r1,r2 /* Disable pwr mgmt */
+ mtdcr isram0_pmeg,r1
+
+ /*
+ * Copy SPL from cache into internal SRAM
+ */
+ li r4,(CFG_NAND_BOOT_SPL_SIZE >> 2) - 1
+ mtctr r4
+ lis r2,CFG_NAND_BOOT_SPL_SRC@h
+ ori r2,r2,CFG_NAND_BOOT_SPL_SRC@l
+ lis r3,CFG_NAND_BOOT_SPL_DST@h
+ ori r3,r3,CFG_NAND_BOOT_SPL_DST@l
+spl_loop:
+ lwzu r4,4(r2)
+ stwu r4,4(r3)
+ bdnz spl_loop
+
+ /*
+ * Jump to code in RAM
+ */
+ bl 00f
+00: mflr r10
+ lis r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@h
+ ori r3,r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@l
+ sub r10,r10,r3
+ addi r10,r10,28
+ mtlr r10
+ blr
+
+start_ram:
+ sync
+ isync
+#endif
+
+ bl 3f
b _start
3: li r0,0
@@ -309,6 +443,7 @@ _start_440:
* r3 - 1st arg to board_init(): IMMP pointer
* r4 - 2nd arg to board_init(): boot flag
*/
+#ifndef CONFIG_NAND_SPL
.text
.long 0x27051956 /* U-Boot Magic Number */
.globl version_string
@@ -322,6 +457,7 @@ version_string:
* location (0x100) is where the CriticalInput Execption should be.
*/
. = EXC_OFF_SYS_RESET
+#endif
.globl _start
_start:
@@ -360,7 +496,8 @@ _start:
/* Setup the internal SRAM */
/*----------------------------------------------------------------*/
li r0,0
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+
+#ifdef CFG_INIT_RAM_DCACHE
/* Clear Dcache to use as RAM */
addis r3,r0,CFG_INIT_RAM_ADDR@h
ori r3,r3,CFG_INIT_RAM_ADDR@l
@@ -376,19 +513,22 @@ _start:
dcbz r0,r3
addi r3,r3,32
bdnz ..d_ag
-#else
-#if defined (CONFIG_440GX) || defined(CONFIG_440SP)
+#endif /* CFG_INIT_RAM_DCACHE */
+
+ /* 440EP & 440GR are only 440er PPC's without internal SRAM */
+#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR)
+ /* not all PPC's have internal SRAM usable as L2-cache */
+#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
mtdcr l2_cache_cfg,r0 /* Ensure L2 Cache is off */
#endif
- mtdcr isram0_sb1cr,r0 /* Disable bank 1 */
- li r2,0x7fff
+ lis r2,0x7fff
ori r2,r2,0xffff
mfdcr r1,isram0_dpc
and r1,r1,r2 /* Disable parity check */
mtdcr isram0_dpc,r1
mfdcr r1,isram0_pmeg
- andis. r1,r1,r2 /* Disable pwr mgmt */
+ and r1,r1,r2 /* Disable pwr mgmt */
mtdcr isram0_pmeg,r1
lis r1,0x8000 /* BAS = 8000_0000 */
@@ -404,11 +544,25 @@ _start:
lis r1, 0x8003
ori r1,r1, 0x0980 /* fourth 64k */
mtdcr isram0_sb3cr,r1
-#else
+#elif defined(CONFIG_440SPE)
+ lis r1,0x0000 /* BAS = 0000_0000 */
+ ori r1,r1,0x0984 /* first 64k */
+ mtdcr isram0_sb0cr,r1
+ lis r1,0x0001
+ ori r1,r1,0x0984 /* second 64k */
+ mtdcr isram0_sb1cr,r1
+ lis r1, 0x0002
+ ori r1,r1, 0x0984 /* third 64k */
+ mtdcr isram0_sb2cr,r1
+ lis r1, 0x0003
+ ori r1,r1, 0x0984 /* fourth 64k */
+ mtdcr isram0_sb3cr,r1
+#elif defined(CONFIG_440GP)
ori r1,r1,0x0380 /* 8k rw */
mtdcr isram0_sb0cr,r1
+ mtdcr isram0_sb1cr,r0 /* Disable bank 1 */
#endif
-#endif
+#endif /* #if !defined(CONFIG_440EP) && !defined(CONFIG_440GR) */
/*----------------------------------------------------------------*/
/* Setup the stack in internal SRAM */
@@ -425,10 +579,14 @@ _start:
stwu r1,-8(r1) /* Save back chain and move SP */
stw r0,+12(r1) /* Save return addr (underflow vect) */
+#ifdef CONFIG_NAND_SPL
+ bl nand_boot /* will not return */
+#else
GET_GOT
bl cpu_init_f /* run low-level CPU init code (from Flash) */
bl board_init_f
+#endif
#endif /* CONFIG_440 */
@@ -738,6 +896,7 @@ _start:
/*----------------------------------------------------------------------- */
+#ifndef CONFIG_NAND_SPL
/*****************************************************************************/
.globl _start_of_vectors
_start_of_vectors:
@@ -943,6 +1102,7 @@ crit_return:
lwz r1,GPR1(r1)
SYNC
rfci
+#endif /* CONFIG_NAND_SPL */
/* Cache functions.
*/
@@ -1184,6 +1344,7 @@ ppcSync:
/*------------------------------------------------------------------------------*/
+#ifndef CONFIG_NAND_SPL
/*
* void relocate_code (addr_sp, gd, addr_moni)
*
@@ -1197,13 +1358,22 @@ ppcSync:
*/
.globl relocate_code
relocate_code:
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
- dccci 0,0 /* Invalidate data cache, now no longer our stack */
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_440SPE)
+ /*
+ * On some 440er platforms the cache is enabled in the first TLB (Boot-CS)
+ * to speed up the boot process. Now this cache needs to be disabled.
+ */
+ iccci 0,0 /* Invalidate inst cache */
+ dccci 0,0 /* Invalidate data cache, now no longer our stack */
sync
+ isync
addi r1,r0,0x0000 /* TLB entry #0 */
tlbre r0,r1,0x0002 /* Read contents */
ori r0,r0,0x0c00 /* Or in the inhibit, write through bit */
tlbwe r0,r1,0x0002 /* Save it out */
+ sync
isync
#endif
mr r1, r3 /* Set new stack pointer */
@@ -1405,22 +1575,22 @@ trap_init:
cmplw 0, r7, r8
blt 4b
-#if !defined(CONFIG_440_GX)
+#if !defined(CONFIG_440)
addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */
oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */
mtmsr r7 /* change MSR */
#else
- bl __440gx_msr_set
- b __440gx_msr_continue
+ bl __440_msr_set
+ b __440_msr_continue
-__440gx_msr_set:
+__440_msr_set:
addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */
oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */
mtspr srr1,r7
mflr r7
mtspr srr0,r7
rfi
-__440gx_msr_continue:
+__440_msr_continue:
#endif
mtlr r4 /* restore link register */
@@ -1439,6 +1609,7 @@ trap_reloc:
stw r0, 4(r7)
blr
+#endif /* CONFIG_NAND_SPL */
/**************************************************************************/
diff --git a/cpu/ppc4xx/usb_ohci.c b/cpu/ppc4xx/usb_ohci.c
index bb57658..ab852c5 100644
--- a/cpu/ppc4xx/usb_ohci.c
+++ b/cpu/ppc4xx/usb_ohci.c
@@ -76,7 +76,7 @@
#define m16_swap(x) swap_16(x)
#define m32_swap(x) swap_32(x)
-#ifdef CONFIG_440EP
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPX)
#define ohci_cpu_to_le16(x) (x)
#define ohci_cpu_to_le32(x) (x)
#else
@@ -1599,7 +1599,11 @@ int usb_lowlevel_init(void)
gohci.disabled = 1;
gohci.sleeping = 0;
gohci.irq = -1;
- gohci.regs = (struct ohci_regs *)(CFG_PERIPHERAL_BASE | 0x1000);
+#if defined(CONFIG_440EP)
+ gohci.regs = (struct ohci_regs *)(CFG_PERIPHERAL_BASE | 0x1000);
+#elif defined(CONFIG_440EPX)
+ gohci.regs = (struct ohci_regs *)(CFG_USB_HOST);
+#endif
gohci.flags = 0;
gohci.slot_name = "ppc440";
diff --git a/cpu/ppc4xx/usbdev.c b/cpu/ppc4xx/usbdev.c
index 8262c54..6140d2a 100644
--- a/cpu/ppc4xx/usbdev.c
+++ b/cpu/ppc4xx/usbdev.c
@@ -3,7 +3,7 @@
#include <common.h>
#include <asm/processor.h>
-#ifdef CONFIG_440EP
+#if (defined(CONFIG_440EP) || defined(CONFIG_440EPX)) && (CONFIG_COMMANDS & CFG_CMD_USB)
#include <usb.h>
#include "usbdev.h"
@@ -186,6 +186,21 @@ int usbInt(void)
return 0;
}
+#if defined(CONFIG_440EPX)
+void usb_dev_init()
+{
+ printf("USB 2.0 Device init\n");
+
+ /*usb dev init */
+ *(unsigned char *)USB2D0_POWER_8 = 0xa1; /* 2.0 */
+
+ /*enable interrupts */
+ *(unsigned char *)USB2D0_INTRUSBE_8 = 0x0f;
+
+ irq_install_handler(VECNUM_HSB2D, (interrupt_handler_t *) usbInt,
+ NULL);
+}
+#else
void usb_dev_init()
{
#ifdef USB_2_0_DEVICE
@@ -210,5 +225,6 @@ void usb_dev_init()
irq_install_handler(VECNUM_USBDEV, (interrupt_handler_t *) usbInt,
NULL);
}
+#endif
-#endif /*CONFIG_440EP */
+#endif /* CONFIG_440EP || CONFIG_440EPX */
diff --git a/cpu/ppc4xx/vecnum.h b/cpu/ppc4xx/vecnum.h
index cbfe41d..70e436a 100644
--- a/cpu/ppc4xx/vecnum.h
+++ b/cpu/ppc4xx/vecnum.h
@@ -31,7 +31,135 @@
#ifndef _VECNUMS_H_
#define _VECNUMS_H_
-#if defined(CONFIG_440SP)
+#if defined(CONFIG_440EPX) || defined(CONFIG_440_GRX)
+
+/* UIC 0 */
+#define VECNUM_U0 0 /* UART 0 */
+#define VECNUM_U1 1 /* UART 1 */
+#define VECNUM_IIC0 2 /* IIC */
+#define VECNUM_KRD 3 /* Kasumi Ready for data */
+#define VECNUM_KDA 4 /* Kasumi Data Available */
+#define VECNUM_PCRW 5 /* PCI command register write */
+#define VECNUM_PPM 6 /* PCI power management */
+#define VECNUM_IIC1 7 /* IIC */
+#define VECNUM_SPI 8 /* SPI */
+#define VECNUM_EPCISER 9 /* External PCI SERR */
+#define VECNUM_MTE 10 /* MAL TXEOB */
+#define VECNUM_MRE 11 /* MAL RXEOB */
+#define VECNUM_D0 12 /* DMA channel 0 */
+#define VECNUM_D1 13 /* DMA channel 1 */
+#define VECNUM_D2 14 /* DMA channel 2 */
+#define VECNUM_D3 15 /* DMA channel 3 */
+#define VECNUM_UD0 16 /* UDMA irq 0 */
+#define VECNUM_UD1 17 /* UDMA irq 1 */
+#define VECNUM_UD2 18 /* UDMA irq 2 */
+#define VECNUM_UD3 19 /* UDMA irq 3 */
+#define VECNUM_HSB2D 20 /* USB2.0 Device */
+#define VECNUM_USBDEV 20 /* USB 1.1/USB 2.0 Device */
+#define VECNUM_OHCI1 21 /* USB2.0 Host OHCI irq 1 */
+#define VECNUM_OHCI2 22 /* USB2.0 Host OHCI irq 2 */
+#define VECNUM_EIP94 23 /* Security EIP94 */
+#define VECNUM_ETH0 24 /* Emac 0 */
+#define VECNUM_ETH1 25 /* Emac 1 */
+#define VECNUM_EHCI 26 /* USB2.0 Host EHCI */
+#define VECNUM_EIR4 27 /* External interrupt 4 */
+#define VECNUM_UIC2NC 28 /* UIC2 non-critical interrupt */
+#define VECNUM_UIC2C 29 /* UIC2 critical interrupt */
+#define VECNUM_UIC1NC 30 /* UIC1 non-critical interrupt */
+#define VECNUM_UIC1C 31 /* UIC1 critical interrupt */
+
+/* UIC 1 */
+#define VECNUM_MS (32 + 0) /* MAL SERR */
+#define VECNUM_MTDE (32 + 1) /* MAL TXDE */
+#define VECNUM_MRDE (32 + 2) /* MAL RXDE */
+#define VECNUM_U2 (32 + 3) /* UART 2 */
+#define VECNUM_U3 (32 + 4) /* UART 3 */
+#define VECNUM_EBCO (32 + 5) /* EBCO interrupt status */
+#define VECNUM_NDFC (32 + 6) /* NDFC */
+#define VECNUM_KSLE (32 + 7) /* KASUMI slave error */
+#define VECNUM_CT5 (32 + 8) /* GPT compare timer 5 */
+#define VECNUM_CT6 (32 + 9) /* GPT compare timer 6 */
+#define VECNUM_PLB34I0 (32 + 10) /* PLB3X4X MIRQ0 */
+#define VECNUM_PLB34I1 (32 + 11) /* PLB3X4X MIRQ1 */
+#define VECNUM_PLB34I2 (32 + 12) /* PLB3X4X MIRQ2 */
+#define VECNUM_PLB34I3 (32 + 13) /* PLB3X4X MIRQ3 */
+#define VECNUM_PLB34I4 (32 + 14) /* PLB3X4X MIRQ4 */
+#define VECNUM_PLB34I5 (32 + 15) /* PLB3X4X MIRQ5 */
+#define VECNUM_CT0 (32 + 16) /* GPT compare timer 0 */
+#define VECNUM_CT1 (32 + 17) /* GPT compare timer 1 */
+#define VECNUM_EIR7 (32 + 18) /* External interrupt 7 */
+#define VECNUM_EIR8 (32 + 19) /* External interrupt 8 */
+#define VECNUM_EIR9 (32 + 20) /* External interrupt 9 */
+#define VECNUM_CT2 (32 + 21) /* GPT compare timer 2 */
+#define VECNUM_CT3 (32 + 22) /* GPT compare timer 3 */
+#define VECNUM_CT4 (32 + 23) /* GPT compare timer 4 */
+#define VECNUM_SRE (32 + 24) /* Serial ROM error */
+#define VECNUM_GPTDC (32 + 25) /* GPT decrementer pulse */
+#define VECNUM_RSVD0 (32 + 26) /* Reserved */
+#define VECNUM_EPCIPER (32 + 27) /* External PCI PERR */
+#define VECNUM_EIR0 (32 + 28) /* External interrupt 0 */
+#define VECNUM_EWU0 (32 + 29) /* Ethernet 0 wakeup */
+#define VECNUM_EIR1 (32 + 30) /* External interrupt 1 */
+#define VECNUM_EWU1 (32 + 31) /* Ethernet 1 wakeup */
+
+#define VECNUM_TXDE VECNUM_MTDE
+#define VECNUM_RXDE VECNUM_MRDE
+
+/* UIC 2 */
+#define VECNUM_EIR5 (62 + 0) /* External interrupt 5 */
+#define VECNUM_EIR6 (62 + 1) /* External interrupt 6 */
+#define VECNUM_OPB (62 + 2) /* OPB to PLB bridge int stat */
+#define VECNUM_EIR2 (62 + 3) /* External interrupt 2 */
+#define VECNUM_EIR3 (62 + 4) /* External interrupt 3 */
+#define VECNUM_DDR2 (62 + 5) /* DDR2 sdram */
+#define VECNUM_MCTX0 (62 + 6) /* MAl intp coalescence TX0 */
+#define VECNUM_MCTX1 (62 + 7) /* MAl intp coalescence TX1 */
+#define VECNUM_MCTR0 (62 + 8) /* MAl intp coalescence TR0 */
+#define VECNUM_MCTR1 (62 + 9) /* MAl intp coalescence TR1 */
+
+#elif defined(CONFIG_440SPE)
+
+/* UIC 0 */
+#define VECNUM_U0 0 /* UART0 */
+#define VECNUM_U1 1 /* UART1 */
+#define VECNUM_IIC0 2 /* IIC0 */
+#define VECNUM_IIC1 3 /* IIC1 */
+#define VECNUM_PIM 4 /* PCI inbound message */
+#define VECNUM_PCRW 5 /* PCI command reg write */
+#define VECNUM_PPM 6 /* PCI power management */
+#define VECNUM_MSI0 7 /* PCI MSI level 0 */
+#define VECNUM_MSI1 8 /* PCI MSI level 0 */
+#define VECNUM_MSI2 9 /* PCI MSI level 0 */
+#define VECNUM_D0 12 /* DMA channel 0 */
+#define VECNUM_D1 13 /* DMA channel 1 */
+#define VECNUM_D2 14 /* DMA channel 2 */
+#define VECNUM_D3 15 /* DMA channel 3 */
+#define VECNUM_UIC1NC 30 /* UIC1 non-critical interrupt */
+#define VECNUM_UIC1C 31 /* UIC1 critical interrupt */
+
+/* UIC 1 */
+#define VECNUM_MS (32 + 1 ) /* MAL SERR */
+#define VECNUM_TXDE (32 + 2 ) /* MAL TXDE */
+#define VECNUM_RXDE (32 + 3 ) /* MAL RXDE */
+#define VECNUM_MTE (32 + 6 ) /* MAL Tx EOB */
+#define VECNUM_MRE (32 + 7 ) /* MAL Rx EOB */
+#define VECNUM_CT0 (32 + 12 ) /* GPT compare timer 0 */
+#define VECNUM_CT1 (32 + 13 ) /* GPT compare timer 1 */
+#define VECNUM_CT2 (32 + 14 ) /* GPT compare timer 2 */
+#define VECNUM_CT3 (32 + 15 ) /* GPT compare timer 3 */
+#define VECNUM_CT4 (32 + 16 ) /* GPT compare timer 4 */
+#define VECNUM_ETH0 (32 + 28) /* Ethernet interrupt status */
+#define VECNUM_EWU0 (32 + 29) /* Emac wakeup */
+
+/* UIC 2 */
+#define VECNUM_EIR5 (62 + 24) /* External interrupt 5 */
+#define VECNUM_EIR4 (62 + 25) /* External interrupt 4 */
+#define VECNUM_EIR3 (62 + 26) /* External interrupt 3 */
+#define VECNUM_EIR2 (62 + 27) /* External interrupt 2 */
+#define VECNUM_EIR1 (62 + 28) /* External interrupt 1 */
+#define VECNUM_EIR0 (62 + 29) /* External interrupt 0 */
+
+#elif defined(CONFIG_440SP)
/* UIC 0 */
#define VECNUM_U0 0 /* UART0 */
diff --git a/cpu/pxa/Makefile b/cpu/pxa/Makefile
index 1af53d6..a6f6b59 100644
--- a/cpu/pxa/Makefile
+++ b/cpu/pxa/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000, 2002
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = serial.o interrupts.o cpu.o i2c.o pxafb.o mmc.o
+COBJS = serial.o interrupts.o cpu.o i2c.o pxafb.o mmc.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/s3c44b0/Makefile b/cpu/s3c44b0/Makefile
index d43c73e..62cb514 100644
--- a/cpu/s3c44b0/Makefile
+++ b/cpu/s3c44b0/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2004
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = serial.o interrupts.o cpu.o
+COBJS = serial.o interrupts.o cpu.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/sa1100/Makefile b/cpu/sa1100/Makefile
index 8c950da..62cb514 100644
--- a/cpu/sa1100/Makefile
+++ b/cpu/sa1100/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = serial.o interrupts.o cpu.o
+COBJS = serial.o interrupts.o cpu.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################