diff options
Diffstat (limited to 'cpu')
156 files changed, 69708 insertions, 17 deletions
diff --git a/cpu/ixp/config.mk b/cpu/ixp/config.mk index eddda39e0..a71a20b82 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 2a2bd504d..7f9f3344b 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 e260dea0e..2dd9561e1 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 *)×tamp; +	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 000000000..d981649da --- /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 000000000..bda2c4479 --- /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 000000000..44328473e --- /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 000000000..e46fc9b25 --- /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 000000000..d57e71678 --- /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 000000000..86368a473 --- /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(®val); +      +	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(®val); +    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(®val); + +	/*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, ®val); +    printf("    Control Register                  :      0x%4.4x\n", regval); +    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_STAT_REG, ®val); +    printf("    Status Register                   :      0x%4.4x\n", regval); +    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_PHY_ID1_REG, ®val); +    printf("    PHY ID1 Register                  :      0x%4.4x\n", regval); +    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_PHY_ID2_REG, ®val); +    printf("    PHY ID2 Register                  :      0x%4.4x\n", regval); +    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_AN_ADS_REG, ®val); +    printf("    Auto Neg ADS Register             :      0x%4.4x\n", regval); +    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_AN_PRTN_REG, ®val); +    printf("    Auto Neg Partner Ability Register :      0x%4.4x\n", regval); +    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_AN_EXP_REG, ®val); +    printf("    Auto Neg Expansion Register       :      0x%4.4x\n", regval); +    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_AN_NEXT_REG, ®val); +    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(®val); +    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(®val); +    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 000000000..b2bfb7260 --- /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 000000000..25633a3d5 --- /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 000000000..25b7cbb8b --- /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 000000000..4d44e0333 --- /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 000000000..7a58d268c --- /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 000000000..eb46174b6 --- /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 000000000..f1b18e6b4 --- /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 000000000..2287dbe96 --- /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 000000000..133cbef8d --- /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 000000000..112a46c99 --- /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 000000000..cdf114bfc --- /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 000000000..9c7ae1cc6 --- /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 000000000..4a10878b6 --- /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 000000000..6d9fd6ec1 --- /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 000000000..e708bf1bc --- /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 000000000..e2efb9b33 --- /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 000000000..0a6043f36 --- /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 000000000..4d92f17ee --- /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, +			      ®val) == 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, ®valId1); +		ixEthAccMiiReadRtn(i,  IX_ETH_MII_PHY_ID1_REG, ®valId1); +		ixEthAccMiiReadRtn(i,  IX_ETH_MII_PHY_ID2_REG, ®valId2); +		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,  +			     ®val)  +	 == 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,  +			     ®val)  +	 == 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, +				   ®val); +		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,  +				   ®val) != 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, ®val4); +		    ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_PRTN_REG, ®val5); +		    /* 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 000000000..e02aabfb4 --- /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 000000000..ffe355c51 --- /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 000000000..e05c22853 --- /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 000000000..f5a4c5f50 --- /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, +			   ®Val); +    } +     +    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, +			   ®Val); +    } +     +    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, ®Val); + +    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 000000000..9dcf3c1e4 --- /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 000000000..8703def8b --- /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 000000000..50c8f2113 --- /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 000000000..57c8be30e --- /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 000000000..318913ac8 --- /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 000000000..8e083a63b --- /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 000000000..d37f9f930 --- /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 000000000..fa8db477a --- /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 000000000..9e540c18e --- /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 000000000..3db1a70da --- /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 000000000..45a5c68b1 --- /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 000000000..443aefd4f --- /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 000000000..e18c6c4c1 --- /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 000000000..e6a4967fc --- /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 000000000..b27b3a287 --- /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, ®isterWord); + + +    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, ®isterWord); +    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, ®isterWord); +    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, ®isterWord); + +    /* 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 000000000..09f69ce32 --- /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 000000000..b00c22d08 --- /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 000000000..2c3e30269 --- /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 000000000..ec7d837c3 --- /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 000000000..937de9d47 --- /dev/null +++ b/cpu/ixp/npe/Makefile @@ -0,0 +1,91 @@ +# +# (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 := libnpe.a + +CFLAGS  += -I$(TOPDIR)/cpu/ixp/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB + +OBJS := 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 + +all:	$(LIB) + +$(LIB):	$(OBJS) +	$(AR) crv $@ $(OBJS) + +######################################################################### + +.depend:	Makefile $(OBJS:.o=.c) +		$(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@ + +sinclude .depend diff --git a/cpu/ixp/npe/include/IxAssert.h b/cpu/ixp/npe/include/IxAssert.h new file mode 100644 index 000000000..eae8b3f27 --- /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 000000000..73c3be29a --- /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 000000000..8624c3328 --- /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 000000000..ae7b2434c --- /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 000000000..e2230493f --- /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 000000000..fcf523fca --- /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 000000000..53d262559 --- /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 000000000..b424648e9 --- /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 000000000..8b8e6b256 --- /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 000000000..93e9d98e7 --- /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 000000000..aa42f9c2a --- /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 000000000..e5fd16e2f --- /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 000000000..37c55605d --- /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 000000000..43ee802d6 --- /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 000000000..1d8b24fdf --- /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 000000000..1d6b0bb20 --- /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 000000000..ff18160c1 --- /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 000000000..c3acbddde --- /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 000000000..6d3488945 --- /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 000000000..e7c67ae52 --- /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 000000000..a1bfe0672 --- /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 000000000..104b65c1f --- /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 000000000..21bdedc5a --- /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 000000000..dabc38e25 --- /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 000000000..07bb119b0 --- /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 000000000..2472f31a7 --- /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 000000000..7427cc41c --- /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 000000000..86f69f414 --- /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 000000000..622f879a4 --- /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 000000000..e32906a63 --- /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 000000000..f68212667 --- /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 000000000..a752f26e8 --- /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 000000000..b7fb0f021 --- /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 000000000..20ee38b06 --- /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 000000000..375b3468e --- /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 000000000..68f34ef35 --- /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 000000000..6416bedcb --- /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 000000000..977cc94a7 --- /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 000000000..40cd496c9 --- /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 000000000..dea8cafa2 --- /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 000000000..893d8030a --- /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 000000000..a297a97d8 --- /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 000000000..b7de712bc --- /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 000000000..4a983c791 --- /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 000000000..2c8592fe8 --- /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 000000000..218e14093 --- /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 000000000..62e8a790b --- /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 000000000..d662cd3ee --- /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 000000000..0d6cd8cce --- /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 000000000..58e994106 --- /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 000000000..4ce37c3f6 --- /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 000000000..b2a93a5db --- /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 000000000..45cebcdaa --- /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 000000000..ea9f30731 --- /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 000000000..be1e27255 --- /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 000000000..5ac3f0cac --- /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 000000000..fe570e641 --- /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 000000000..18f8f24df --- /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 000000000..0ccff84ae --- /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 000000000..634b494ae --- /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 000000000..497ed0471 --- /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 000000000..684b52edb --- /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 000000000..d56e79639 --- /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 000000000..3b1c73947 --- /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 000000000..ac0ce6570 --- /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 000000000..2ad0ccfbb --- /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 000000000..f89402620 --- /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 000000000..6c6661341 --- /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 000000000..e4c3e1f61 --- /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 000000000..8e46586ea --- /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 000000000..44a94fb30 --- /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 000000000..47ce3a2d8 --- /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 000000000..272eef185 --- /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 000000000..beb45a079 --- /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 000000000..c617ec578 --- /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 000000000..f2a73db8b --- /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 000000000..62fe1714f --- /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 000000000..65c0ba96a --- /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 000000000..c083a2b32 --- /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 000000000..7f5733c5d --- /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, ®isterWord); +     +    /* +     * 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, ®isterWord); +     + +    /* +     * 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 000000000..0183596af --- /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 000000000..71a3f8588 --- /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 000000000..6b685b8a2 --- /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 000000000..8612670a1 --- /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 000000000..c9dae1ef0 --- /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 000000000..0c1543fa7 --- /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 000000000..35e7abf06 --- /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 000000000..25effed90 --- /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 000000000..669dd3ef2 --- /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 000000000..c4c5a2d26 --- /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 000000000..03a44441c --- /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 000000000..27796ede8 --- /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 000000000..d32ace20b --- /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 000000000..53f5942f9 --- /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 000000000..857509672 --- /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 000000000..b59f7d087 --- /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 000000000..f7bb029d6 --- /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 000000000..fc7b1e993 --- /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 000000000..e53458def --- /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 000000000..4387b2a05 --- /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 000000000..c63c54e28 --- /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 000000000..ab7ca8bef --- /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, ®_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, ®_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 2726f6597..757cfaa2d 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 8df2a31f5..920f34e61 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/mpc8260/pci.c b/cpu/mpc8260/pci.c index ea5514fb1..b14fc159b 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,  |