示例#1
0
PUBLIC IX_STATUS
ixTimeSyncAccCodeletMain (UINT32 configIndex)
{
	IxTimeSyncAccStatus tsStatus;
	IxTimeSyncAcc1588PTPPort tsChannel;
	IxTimeSyncAcc1588PTPPortMode tsChannelMode;

	/* check the validity of configuration */
	if (IX_TIMESYNCACC_CODELET_MAX_CONFIGURATIONS <= configIndex)
	{
		ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletMain: invalid configuration\n",
			0, 0, 0, 0, 0, 0);
		ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, "ixTimeSyncAccCodeletMain: Usage :\n", 
			0, 0, 0, 0, 0, 0);
		ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, "ixTimeSyncAccCodeletMain:\t-> ixTimeSyncAccCodeletMain <x>\n\n",
			0, 0, 0, 0, 0, 0);
		ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, "ixTimeSyncAccCodeletMain:\twhere <x> =\n",
			0, 0, 0, 0, 0, 0);
		ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, "ixTimeSyncAccCodeletMain:\t0 -> NPE A - Slave,  NPE B - Slave,  NPE C - Master (default)\n",
			0, 0, 0, 0, 0, 0);  
		ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, "ixTimeSyncAccCodeletMain:\t1 -> NPE A - Slave,  NPE B - Master, NPE C - Slave\n",
			0, 0, 0, 0, 0, 0); 
		ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, "ixTimeSyncAccCodeletMain:\t2 -> NPE A - Master, NPE B - Slave,  NPE C - Slave\n",
			0, 0, 0, 0, 0, 0);  

		return IX_FAIL;
	}

    	/* Disable UTOPIA to enable Ethernet on Npe-A */
    	ixFeatureCtrlWrite (ixFeatureCtrlRead() | ((UINT32)1<<IX_FEATURECTRL_UTOPIA));

	/* set termination flag to false */
	ixTimeSyncAccCodeletTerminate = FALSE;

	/* save global configuration pointer */
	ixTimeSyncAccCodeletConfigPtr = &ixTimeSyncAccCodeletConfigList[configIndex];

	/* write default frequency scale value to Addend Register */
	tsStatus = ixTimeSyncAccTickRateSet (IX_TIMESYNCACC_CODELET_FSV_DEFAULT);
	if (IX_TIMESYNCACC_SUCCESS != tsStatus)
	{
		ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletMain: failed to set frequency scale value, error code %d\n",
			tsStatus, 0, 0, 0, 0, 0);

		return IX_FAIL;
	}
	
	/* configure all Time Sync channels */
	for (tsChannel = IX_TIMESYNCACC_NPE_A_1588PTP_PORT; 
	     tsChannel < IX_TIMESYNCACC_CODELET_MAX_TS_CHANNELS; 
	     tsChannel++)
	{
		/* get channel operating mode from the configuration table */
		tsChannelMode = ixTimeSyncAccCodeletConfigPtr->tsChannelMode[tsChannel];

		tsStatus = ixTimeSyncAccPTPPortConfigSet(tsChannel, tsChannelMode);
		if (IX_TIMESYNCACC_SUCCESS != tsStatus)
		{
			ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletMain: failed to configure %s channel to %s mode, error code %d\n",
				(UINT32)(ixTimeSyncAccCodeletTSChannelLabel[tsChannel]),
				(UINT32)(ixTimeSyncAccCodeletTSChannelModeLabel[tsChannelMode]), 
				tsStatus, 0, 0, 0);
		
			return IX_FAIL;
		}
	}

	ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, "\nixTimeSyncAccCodeletMain: TS channel configuration: NPE A - %s, NPE B - %s, NPE C - %s\n\n",
		(UINT32)(ixTimeSyncAccCodeletTSChannelModeLabel[ixTimeSyncAccCodeletConfigPtr->tsChannelMode[0]]),
		(UINT32)(ixTimeSyncAccCodeletTSChannelModeLabel[ixTimeSyncAccCodeletConfigPtr->tsChannelMode[1]]),
		(UINT32)(ixTimeSyncAccCodeletTSChannelModeLabel[ixTimeSyncAccCodeletConfigPtr->tsChannelMode[2]]),
		0, 0, 0);

	/* set target time using default interval */
	if (IX_SUCCESS != ixTimeSyncAccCodeletTargetTimeSet ())
	{
		ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletMain: failed to set target time\n",
			0, 0, 0, 0, 0, 0);

		return IX_FAIL;
	}

		
	/* initialize ethernet components to transmit PTP messages */
	if (IX_SUCCESS != ixTimeSyncAccCodeletEthInit ())
	{
		ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletMain: failed to initialize ethernet components\n",
			0, 0, 0, 0, 0, 0);

		/* unload all initialized modules and free all resources */
		ixTimeSyncAccCodeletUninit ();
		return IX_FAIL;
	}

	return IX_SUCCESS;

} /* end of ixTimeSyncAccCodeletMain function */
示例#2
0
/*
 * Function definition: ixNpeDlNpeMgrNpeReset
 */
IX_STATUS
ixNpeDlNpeMgrNpeReset (
    IxNpeDlNpeId npeId)
{
    UINT32 npeBaseAddress;
    IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */
    UINT32 ctxtNum;            /* identifies Context number (0-16)   */
    UINT32 regAddr;
    UINT32 regVal;
    UINT32 localIndex;
    UINT32 indexMax;
    IX_STATUS status = IX_SUCCESS;
    IxFeatureCtrlReg unitFuseReg;
    UINT32 ixNpeConfigCtrlRegVal;
    
    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, 
		     "Entering ixNpeDlNpeMgrNpeReset\n");
    
    /* get base memory address of NPE from npeId */
    npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);

    /* pre-store the NPE Config Control Register Value */
    IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, &ixNpeConfigCtrlRegVal);
    
    ixNpeConfigCtrlRegVal |= 0x3F000000;
    
    /* disable the parity interrupt */
    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, (ixNpeConfigCtrlRegVal & IX_NPEDL_PARITY_BIT_MASK));
    
    ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress);

    /*
     * clear the FIFOs
     */
    while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
				      IX_NPEDL_REG_OFFSET_WFIFO,
				      IX_NPEDL_MASK_WFIFO_VALID))
    {
	/* read from the Watch-point FIFO until empty */
	IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WFIFO,
			   &regVal);
    }
    
    while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
					  IX_NPEDL_REG_OFFSET_STAT,
				      IX_NPEDL_MASK_STAT_OFNE))
    {
	/* read from the outFIFO until empty */
	IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_FIFO,
			   &regVal);
    }
    
    while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
				      IX_NPEDL_REG_OFFSET_STAT,
				      IX_NPEDL_MASK_STAT_IFNE))
    {
	/*
	 * step execution of the NPE intruction to read inFIFO using
	 * the Debug Executing Context stack
	 */
	status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress,
					   IX_NPEDL_INSTR_RD_FIFO, 0, 0);

    if (IX_SUCCESS != status)
    {
        return status;   
    }
    
    }
    
    /*
     * Reset the mailbox reg
     */
    /* ...from XScale side */
    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_MBST,
			IX_NPEDL_REG_RESET_MBST);
    /* ...from NPE side */
    status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress,
				       IX_NPEDL_INSTR_RESET_MBOX, 0, 0);

    if (IX_SUCCESS != status)
    {
        return status;   
    }

    /* 
     *   Reset the physical registers in the NPE register file:
     *   Note: no need to save/restore REGMAP for Context 0 here
     *   since all Context Store regs are reset in subsequent code
     */
    for (regAddr = 0;
	 (regAddr < IX_NPEDL_TOTAL_NUM_PHYS_REG) && (status != IX_FAIL);
	 regAddr++)
    {
	/* for each physical register in the NPE reg file, write 0 : */
	status = ixNpeDlNpeMgrPhysicalRegWrite (npeBaseAddress, regAddr,
						0, TRUE);
	if (status != IX_SUCCESS)
	{
	    return status;  /* abort reset */
	}
    }
    

    /*
     * Reset the context store:
     */
    for (ctxtNum = IX_NPEDL_CTXT_NUM_MIN;
	 ctxtNum <= IX_NPEDL_CTXT_NUM_MAX; ctxtNum++)
    {	
	/* set each context's Context Store registers to reset values: */
	for (ctxtReg = 0; ctxtReg < IX_NPEDL_CTXT_REG_MAX; ctxtReg++)
	{
	    /* NOTE that there is no STEVT register for Context 0 */
	    if (!((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT)))
	    { 
		regVal = ixNpeDlCtxtRegResetValues[ctxtReg];
		status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum,
						    ctxtReg, regVal, TRUE);
		if (status != IX_SUCCESS)
		{
		    return status;  /* abort reset */
		}
	    }
	}
    }

    ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress);

    /* write Reset values to Execution Context Stack registers */
    indexMax = sizeof (ixNpeDlEcsRegResetValues) /
	sizeof (IxNpeDlEcsRegResetValue);
    for (localIndex = 0; localIndex < indexMax; localIndex++)
    {
	regAddr = ixNpeDlEcsRegResetValues[localIndex].regAddr;
	regVal = ixNpeDlEcsRegResetValues[localIndex].regResetVal;
	ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, regAddr, regVal);
    }
    
    /* clear the profile counter */
    ixNpeDlNpeMgrCommandIssue (npeBaseAddress, 
			       IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT);
    
    /* clear registers EXCT, AP0, AP1, AP2 and AP3 */
    for (regAddr = IX_NPEDL_REG_OFFSET_EXCT;
	     regAddr <= IX_NPEDL_REG_OFFSET_AP3;
	 regAddr += IX_NPEDL_BYTES_PER_WORD)
    {
	IX_NPEDL_REG_WRITE (npeBaseAddress, regAddr, 0);
    }
    
    /* Reset the Watch-count register */
    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, 0);
    
    /*
     * WR IXA00055043 - Remove IMEM Parity Introduced by NPE Reset Operation
     */

    /*
     * Call the feature control API to fused out and reset the NPE and its
     * coprocessor - to reset internal states and remove parity error
     */
    unitFuseReg = ixFeatureCtrlRead ();
    unitFuseReg |= (IX_NPEDL_RESET_NPE_PARITY << npeId);
    ixFeatureCtrlWrite (unitFuseReg);

    /* call the feature control API to un-fused and un-reset the NPE & COP */
    unitFuseReg &= (~(IX_NPEDL_RESET_NPE_PARITY << npeId));
    ixFeatureCtrlWrite (unitFuseReg);

    /*
     * Call NpeMgr function to stop the NPE again after the Feature Control
     * has unfused and Un-Reset the NPE and its associated Coprocessors
     */
    status = ixNpeDlNpeMgrNpeStop (npeId);

    /* restore NPE configuration bus Control Register - Parity Settings  */
    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, 
        (ixNpeConfigCtrlRegVal & IX_NPEDL_CONFIG_CTRL_REG_MASK));

    ixNpeDlNpeMgrStats.npeResets++;

    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
		     "Exiting ixNpeDlNpeMgrNpeReset : status = %d\n", status);
    return status;
}
示例#3
0
/*
 * Function definition: ixEthAccCodeletInit()
 *
 * See header file for documentation.
 */
IX_STATUS ixEthAccCodeletInit(IxEthAccCodeletOperation operationType,
                    IxEthAccPortId inPort,
                    IxEthAccPortId outPort)
{  
    IxEthAccPortId portId;

    IxOsalThread statsPollThread;
    IxOsalThreadAttr threadAttr;

    threadAttr.name      = "Codelet Stats";
    threadAttr.stackSize = 32 * 1024; /* 32kbytes */
    threadAttr.priority  = 128;


#ifdef __ixp46X
    /* Set the expansion bus fuse register to enable MUX for NPEA MII */
    {
        UINT32 expbusCtrlReg;
        expbusCtrlReg = ixFeatureCtrlRead ();
        expbusCtrlReg |= ((unsigned long)1<<8);
        ixFeatureCtrlWrite (expbusCtrlReg);
    }
#endif

    /* check the component is already initialized */
    if(ixEthAccCodeletInitialised) 
    {
	printf("CodeletMain: Ethernet codelet already initialised\n");
	return(IX_SUCCESS);
    }

#ifdef __vxworks
    /* When the ixe drivers are running, the codelets
    * cannot run.
    */
    for (portId = 0; portId < IX_ETHACC_CODELET_MAX_PORT; portId++)
    {
        if (endFindByName ("ixe", portId) != NULL)
        {
            printf("CodeletMain: FAIL: Driver ixe%d detected\n",portId);
            return IX_FAIL;
        }
    }
#endif

    /* Initialize NPE IMAGE ID here again to prevent confusion in multiple 
     * ixEthAccCodeletMain() calls with different operationType.
     */   
    ETH_NPEA_IMAGEID = IX_NPEDL_NPEIMAGE_NPEA_ETH_MACFILTERLEARN_HSSCHAN_COEXIST;
    ETH_NPEB_IMAGEID = IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_MASK_FIREWALL_VLAN_QOS_EXTMIB;
    ETH_NPEC_IMAGEID = IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_MASK_FIREWALL_VLAN_QOS_EXTMIB;

    /* Create mutexes for thread control */
    ixEthAccCodeletStatsPollTaskStop = TRUE;
    ixOsalMutexInit (&ixEthAccCodeletStatsPollTaskRunning);

    /* Initialise MBUF pool */
    if(ixEthAccCodeletMemPoolInit() != IX_SUCCESS)
    {
	printf("CodeletMain: Error initialising mBuf pool\n");
	return (IX_FAIL);
    }

    /* Check Silicon stepping */
    printf("Checking Silicon stepping...\n");

    if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X)
    {

        if ((ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) == 
           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)
            {
                ixEthAccCodeletHardwareExists[IX_ETH_PORT_1] = TRUE;
            }

            if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == 
               IX_FEATURE_CTRL_COMPONENT_ENABLED)
            {
                ixEthAccCodeletHardwareExists[IX_ETH_PORT_2] = TRUE;
            }
        }
        else if ((ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) == 
                  IX_FEATURE_CTRL_SILICON_TYPE_A0) 
        {
            /*
             * If it is A0 Silicon, we enable both as both Eth Coprocessors 
             * are available. 
             */ 
            ixEthAccCodeletHardwareExists[IX_ETH_PORT_1] = TRUE;
            ixEthAccCodeletHardwareExists[IX_ETH_PORT_2] = TRUE;
        }
        else
        {
            printf("CodeletMain: Error. Operation for other silicon stepping is undefined!.\n");
            return (IX_FAIL);
        }
    }
    else if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X)
    {
        ixEthAccCodeletHardwareExists[IX_ETH_PORT_1] = TRUE;
        ixEthAccCodeletHardwareExists[IX_ETH_PORT_2] = TRUE;
#ifdef __ixp46X
        ixEthAccCodeletHardwareExists[IX_ETH_PORT_3] = TRUE;
#endif
    }

    /***********************************************************************
     *
     * System initialisation done. Now initialise Access components. 
     *
     ***********************************************************************/

    /* Initialise Queue Manager */
    printf("Initialising Queue Manager...\n");
    if (ixQMgrInit() != IX_SUCCESS)
    {
	printf("CodeletMain: Error initialising queue manager!\n");
	return (IX_FAIL);
    }

    /* Start the Queue Manager dispatcher */   
    if(ixEthAccCodeletDispatcherStart(IX_ETH_CODELET_QMGR_DISPATCH_MODE) 
       != IX_SUCCESS)
    {
	printf("CodeletMain: Error starting queue manager dispatch loop!\n");
	return (IX_FAIL);
    }

    /* Initialise NPE Message handler */
    printf("\nStarting NPE message handler...\n");
    if(ixNpeMhInitialize(IX_NPEMH_NPEINTERRUPTS_YES) != IX_SUCCESS)
    {
	printf("CodeletMain: Error initialising NPE Message handler!\n");
	return (IX_FAIL);
    }

    /* Initialise NPEs firmware */
    printf ("Initialising NPEs...\n");
    if (ixEthAccCodeletHardwareExists[IX_ETH_PORT_1])
    {
        if ((operationType == IX_ETHACC_CODELET_BRIDGE_WIFI) && (inPort == IX_ETH_PORT_1))
        {
            printf("CodeletMain: the 802.3 <=> 802.11 header conversion image is loaded on NPE B\n");
            ETH_NPEB_IMAGEID = IX_NPEDL_NPEIMAGE_NPEB_ETH_SPAN_VLAN_QOS_HDR_CONV_EXTMIB;
        }

	if (IX_SUCCESS != ixNpeDlNpeInitAndStart(ETH_NPEB_IMAGEID))
        {
	    printf ("CodeletMain: Error initialising and starting NPE B!\n");
	    return (IX_FAIL);
	}
    }

    if (ixEthAccCodeletHardwareExists[IX_ETH_PORT_2])
    {
        if ((operationType == IX_ETHACC_CODELET_BRIDGE_WIFI) && (inPort == IX_ETH_PORT_2))
        {
            printf("CodeletMain: the 802.3 <=> 802.11 header conversion image is loaded on NPE C\n");
            ETH_NPEC_IMAGEID = IX_NPEDL_NPEIMAGE_NPEC_ETH_SPAN_VLAN_QOS_HDR_CONV_EXTMIB;
        }

	if (IX_SUCCESS != ixNpeDlNpeInitAndStart(ETH_NPEC_IMAGEID))
        {
	    printf ("CodeletMain: Error initialising and starting NPE C!\n");
	    return (IX_FAIL);
	}
    }
#ifdef __ixp46X
    if (ixEthAccCodeletHardwareExists[IX_ETH_PORT_3])
    {
        if ((operationType == IX_ETHACC_CODELET_BRIDGE_WIFI) && (inPort == IX_ETH_PORT_3))
        {
            printf("CodeletMain: the 802.3 <=> 802.11 header conversion image is loaded on NPE A\n");
            ETH_NPEA_IMAGEID = IX_NPEDL_NPEIMAGE_NPEA_ETH_SPAN_VLAN_QOS_HDR_CONV_EXTMIB;
        }

	if (IX_SUCCESS != ixNpeDlNpeInitAndStart(ETH_NPEA_IMAGEID))
        {
	    printf ("CodeletMain: Error initialising and starting NPE A!\n");
	    return (IX_FAIL);
	}
    }
#endif

    printf ("Initialising Access Layers\n");

    /* Enable QoS on ethDB. This has to be done before ethAcc initialisation */
    if (operationType == IX_ETHACC_CODELET_BRIDGE_QOS)
    {
	printf("Enabling QoS\n");
        if (IX_ETH_DB_SUCCESS != ixEthDBInit())
	{
	    printf ("CodeletMain: Error initialising EthDB\n");
	    return (IX_FAIL);
	}

	(void)ixEthDBPortInit(inPort);

        if (IX_ETH_DB_SUCCESS != ixEthDBFeatureEnable(inPort, 
						      IX_ETH_DB_VLAN_QOS, 
						      TRUE))
	{
            printf("CodeletMain: Error enabling QoS on port %d\n",inPort);
	    return (IX_FAIL);
        }
    }

    /* initialise ethAcc : QoS, if needed is already configured */
    if (ixEthAccInit() != IX_ETH_ACC_SUCCESS)
    {
	printf("CodeletMain: Error initialising Ethernet access driver!\n");
	return (IX_FAIL);
    }

    /***********************************************************************
     *
     * Access components initialisation done. Now initialize the ports
     *
     ***********************************************************************/

    /* Configure all available ports */
    for (portId = 0; portId < IX_ETHACC_CODELET_MAX_PORT; portId++)
    {
	if (ixEthAccCodeletHardwareExists[portId])
	{
	    if(ixEthAccCodeletPortInit(portId) != IX_ETH_ACC_SUCCESS)
            {
   	        printf("CodeletMain: Error setup port %u\n",
		       portId);
	        return (IX_FAIL);
            }
        }
    }

    /* Find and initialise all available PHYs */
    printf ("Discover and reset the PHYs...\n");
    if(ixEthAccCodeletPhyInit() != IX_SUCCESS)
    {
	printf("CodeletMain: Error initialising Ethernet phy(s)!\n");
	return (IX_FAIL);
    }

    /***********************************************************************
     *
     * PortInitialization done. Now start the codelet features
     *
     ***********************************************************************/

    /* starts ethDB maintenance running from a different task */
    if (ixEthAccCodeletDBMaintenanceStart()
	!= IX_SUCCESS)
    {
	printf("CodeletMain: Error spawning DB maintenance task\n");
	return (IX_FAIL);
    }

    /* Starts the traffic display (in a different task) this is initially
     * set to FALSE in order to allow the traffic stats to start only
     * once traffic is started to be received 
     */
    ixEthAccCodeletTrafficPollEnabled = FALSE;

    if (ixOsalThreadCreate(&statsPollThread,
			   &threadAttr,
			   (IxOsalVoidFnVoidPtr) ixEthAccCodeletStatsPollTask,
			   NULL)	
	!= IX_SUCCESS)
    {
	printf("CodeletMain: Error spawning stats task\n");
	return (IX_FAIL);
    }

     /* Start the thread */
    if (ixOsalThreadStart(&statsPollThread) != IX_SUCCESS)
    {
	printf("CodeletMain: Error failed to start the stats thread\n");
        return IX_FAIL;
    }
    ixEthAccCodeletInitialised = TRUE;
    return (IX_SUCCESS);
}