PRIVATE IX_STATUS 
ixEthAccCodeletTxGenRxSinkStart(IxEthAccPortId portId)
{
    IX_OSAL_MBUF *mBufPtr;
    UINT32 numBufs;
    IxEthDBStatus status;

    /* port transmits as fast as possible and drops rx traffic */
    if (ixEthAccCodeletPortConfigure(portId,
				     NULL,
				     ixEthAccCodeletRxSinkRxCB, 
				     ixEthAccCodeletTxGenTxCB,
				     portId)
	!= IX_ETH_ACC_SUCCESS)
    {
	printf("Loopbacks: Failed to start the Tx-Gen Rx-Sink Operation port %u\n",
	       (UINT32)portId);
	return IX_FAIL;
    }

    /* Disable MAC learning and filtering at the port that sinks the frame. 
       With learning enabled at both ports, TxGenRxSink will report buffer underrun and overruns 
       as this mode generates a heavy load of MAC address migrations in the learning/filtering 
       database. 
     */
    status = ixEthDBFeatureEnable (portId, IX_ETH_DB_FILTERING, FALSE);
    if (IX_ETH_DB_SUCCESS == status)
    {
        status = ixEthDBFeatureEnable (portId, IX_ETH_DB_LEARNING, FALSE); 
    }

    if (IX_ETH_DB_SUCCESS == status)
    {
        printf("\nMAC learning & filtering are disabled at port %d\n", portId);
        printf("This is to prohibit the MAC address from being migrated back and forth\n");
        printf("between two connected ports in the learning/filtering database.\n\n");
    }
    else
    {
        printf("\nFailed to disable MAC learning & filtering at port %d.\n", portId);
        printf("TxGenRxSink will report buffer underrun and overruns as this mode generates \n");
        printf("a heavy load of MAC address migrations in the learning/filtering database. \n");
        printf("With learning enabled at both ports, buffer underrun and overruns are expected.\n");
    }

    /* Generate our random data for the payload */
    IX_ETHACC_CODELET_DATAGEN(compData);
	
    /* Now start the loopback by transmitting the first few frames */
    for (numBufs=0; numBufs<IX_ETHACC_CODELET_TXGEN_PCKS; numBufs++)
    {
	IX_ETHACC_CODELET_REMOVE_MBUF_FROM_Q_HEAD(ixEthAccCodeletFreeBufQ,
						  mBufPtr);
	
	if (mBufPtr == NULL)
	{
	    printf("Loopbacks: Buffer queue empty. Not enough free buffers to transmit in TxGen-RxSink Loopback!\n");
	    return (IX_FAIL);
	}
	
	IX_OSAL_MBUF_MLEN(mBufPtr) = IX_ETHACC_CODELET_TXGEN_PCK_LEN;
	IX_OSAL_MBUF_PKT_LEN(mBufPtr) = IX_ETHACC_CODELET_TXGEN_PCK_LEN;
	
	memcpy(IX_OSAL_MBUF_MDATA(mBufPtr), 
	       &compData[0], 
	       IX_ETHACC_CODELET_TXGEN_PCK_LEN);
	
	IX_OSAL_CACHE_FLUSH(IX_OSAL_MBUF_MDATA(mBufPtr), 
				IX_OSAL_MBUF_MLEN(mBufPtr));
	
	if(ixEthAccPortTxFrameSubmit(portId, 
				     mBufPtr,
				     IX_ETH_ACC_TX_DEFAULT_PRIORITY)
	   != IX_ETH_ACC_SUCCESS)
	{
	    printf("Loopbacks: Error Submitting frame for transmission on port %u\n",
		   portId);
	    return (IX_FAIL);
	}
    }
    printf("Port %d Tx pool has %d buffers\n", portId, numBufs);

    /* enable traffic */
    if(ixEthAccPortEnable(portId) 
       != IX_ETH_ACC_SUCCESS)
    {
	printf("Loopbacks: Error Enabling port %u\n",
	       (UINT32)portId);
	return (IX_FAIL);
    }

    return (IX_SUCCESS);
}
/*
 * Function definition: ixEthAccCodeletSwBridgeQoSStart()
 *
 * Configure QoS and Start bridge datapath
 */
IX_STATUS ixEthAccCodeletSwBridgeQoSStart(IxEthAccPortId firstPortId, 
					  IxEthAccPortId secondPortId)
{
    UINT32 firstPortCbTag = firstPortId | (secondPortId << 16);
    UINT32 secondPortCbTag = secondPortId | (firstPortId << 16);

    IxEthDBPriorityTable priorityTable = { 0,1,2,3,4,5,6,7};
    IxEthDBFeature featureSet = 0;

    if (firstPortId == secondPortId)
    {
	printf("SwBridgeQoS: Cannot configure a Bridge Operation between port %u and port %u (ports must be different)\n",
	       firstPortId, 
               secondPortId);
	return (IX_FAIL);
    }

    /* initialize pendingTx for both ports */
    pendingTx[firstPortId] = pendingTx[secondPortId] = 0;

    /* register the rx/tx callback */
    if ( ixEthAccCodeletPortConfigure(firstPortId, 
	      ixEthAccCodeletSwBridgeQoSTaggedToUntaggedRxCB, 
	      (IxEthAccPortMultiBufferRxCallback) NULL,
	      ixEthAccCodeletSwBridgeQoSTxCB,
	      firstPortCbTag) != IX_SUCCESS)
    {
	printf("SwBridgeQoS: Failed to configure the Bridge Operation for port %u\n",
	       firstPortId);
	return (IX_FAIL);
    }

    if ( ixEthAccCodeletPortConfigure(secondPortId, 
	      ixEthAccCodeletSwBridgeQoSUntaggedToTaggedRxCB, 
	      NULL,
	      ixEthAccCodeletSwBridgeQoSTxCB,
	      secondPortCbTag) != IX_SUCCESS)
    {
	printf("SwBridgeQoS: Failed to configure the Bridge Operation for port %u\n",
	       secondPortId);
	return (IX_FAIL);
    }

    /* Enable the VLAN/QoS Feature in EthDB for each port but first 
     * check that the Firmware downloaded to the NPE can support it
     */
    ixEthDBFeatureCapabilityGet((IxEthDBPortId)firstPortId, &featureSet);
    
    if ((featureSet & IX_ETH_DB_VLAN_QOS) == 0)
    {
	printf("SwBridgeQoS: Port %u NPE image not VLAN/QoS capable\n",
	       firstPortId);
	return (IX_FAIL);
    }

    if ( ixEthDBFeatureEnable((IxEthDBPortId)firstPortId, 
			      IX_ETH_DB_VLAN_QOS,
			      TRUE) != IX_ETH_DB_SUCCESS )
    {
	printf("SwBridgeQoS: Failed to enable VLAN/QoS on port %u\n",
	       firstPortId);
	return (IX_FAIL);
    }

    /* Enable the EthDB Port in order to configure and download the
     * VLAN/QoS configuration information
     */ 
    if ((ixEthDBPortEnable(firstPortId)) != IX_ETH_DB_SUCCESS)
    {
        printf("SwBridgeQoS: Cannot enable port %u\n", firstPortId);
        return (IX_FAIL);
    }
    if ((ixEthDBPortEnable(secondPortId)) != IX_ETH_DB_SUCCESS)
    {
        printf("SwBridgeQos: Cannot enable port %u\n", secondPortId);
        return (IX_FAIL);
    }

    /* Configure Xscale QoS : the access layer datapath 
     * prioritizes the different classes of traffic.
     */
    printf("Set Tx Scheduling discipline...\n");
    if (ixEthAccTxSchedulingDisciplineSet(firstPortId, 
					  FIFO_PRIORITY)
	!= IX_ETH_ACC_SUCCESS)
    {
	printf("SwBridgeQos: Failed to set Tx Scheduling for discipline port %u\n",
	       (UINT32)firstPortId);
	return (IX_FAIL);
    }

    if (ixEthAccTxSchedulingDisciplineSet(secondPortId, 
					  FIFO_PRIORITY)
	!= IX_ETH_ACC_SUCCESS)
    {
	printf("SwBridgeQos: Failed to set Tx Scheduling for discipline port %u\n",
	       (UINT32)secondPortId);
	return (IX_FAIL);
    }

    printf("Set Rx Scheduling discipline...\n");
    if (ixEthAccRxSchedulingDisciplineSet(FIFO_PRIORITY)
	!= IX_ETH_ACC_SUCCESS)
    {
	printf("SwBridgeQos: Failed to set Rx Scheduling discipline!\n");
	return (IX_FAIL);
    }

    /* NPE QoS : Configure VLAN traffic for highest priority 
     * on first port. Tagging is enabled on Egress (use default tag
     * for this port) and untagging is enabled on ingress.
     * The traffic running on this bridge will be untagged.
     */
    printf("Set VLAN default tag...\n");
    if (ixEthDBPortVlanTagSet(firstPortId, 
			      IX_ETHACC_CODELET_VLANID_DEFAULT)
	!= IX_ETH_DB_SUCCESS)
    {
	printf("SwBridgeQos: Failed to set the default VLAN ID for port %u\n",
	       firstPortId);
	return (IX_FAIL);
    }

    printf("Enable tagged frames...\n");
    if (ixEthDBAcceptableFrameTypeSet(firstPortId,
				      IX_ETH_DB_VLAN_TAGGED_FRAMES
				      | IX_ETH_DB_UNTAGGED_FRAMES)
	!= IX_ETH_DB_SUCCESS)
    {
	printf("SwBridgeQos: Failed to set the acceptable frame type for port %u\n",
	       firstPortId);
	return (IX_FAIL);
    }

    printf("Setting VLAN membership...\n");

    /* by default the entire VLAN range 0-4094 is included in the
       port VLAN membership table, therefore we need to remove all 
       VLAN IDs but 0 (which is required to accept untagged frames) */
    if (ixEthDBPortVlanMembershipRangeRemove(firstPortId, 
        1, IX_ETH_DB_802_1Q_MAX_VLAN_ID) != IX_ETH_DB_SUCCESS)
    {
        printf("SwBridgeQos: Failed to set VLAN membership for port %u\n", firstPortId);
        return (IX_FAIL);
    }

    /* now add the range used by this codelet */
    if (ixEthDBPortVlanMembershipRangeAdd(firstPortId, 
					  IX_ETHACC_CODELET_VLANID_MIN,
					  IX_ETHACC_CODELET_VLANID_MAX)
	!= IX_ETH_DB_SUCCESS)
    {
	printf("SwBridgeQos: Failed to set VLAN membership for port %u\n",
	       firstPortId);
	return (IX_FAIL);
    }

    printf("Enable Egress VLAN tagging...\n");
    if (ixEthDBEgressVlanRangeTaggingEnabledSet(firstPortId, 
						IX_ETHACC_CODELET_VLANID_MIN,
						IX_ETHACC_CODELET_VLANID_MAX,
						TRUE)
	!= IX_ETH_DB_SUCCESS)
    {
	printf("SwBridgeQos: Failed to enable VLAN Egress tagging for port %u\n",
	       firstPortId);
	return (IX_FAIL);
    }

    printf("Enable Ingress VLAN untagging...\n");
    if (ixEthDBIngressVlanTaggingEnabledSet(firstPortId, 
					    IX_ETH_DB_REMOVE_TAG)
	!= IX_ETH_DB_SUCCESS)
    {
	printf("SwBridgeQos: Failed to enable VLAN Ingress untagging for port %u\n",
	       firstPortId);
	return (IX_FAIL);
    }
    
    printf("Setup priority mapping table...\n");
    if (ixEthDBPriorityMappingTableSet(firstPortId,
				       priorityTable)
	!= IX_ETH_DB_SUCCESS)
    {
	printf("SwBridgeQos: Failed to set the priority mapping Table for port %u\n",
	       firstPortId);
	return (IX_FAIL);	
    }
    
    /* Configure 10 mb/s on second port to create a 
     * traffic congestion on the bridge : the high 
     * priority traffic should pass, the low priority
     * traffic should starve.
     */
    if (ixEthAccCodeletLinkSlowSpeedSet(secondPortId)
	!= IX_SUCCESS)
    {
	printf("SwBridgeQos: Failed to set port %u to 10 Mbit\n", 
	       secondPortId);
	return (IX_FAIL);
    }

    /* Allow RX and TX traffic to run */
    if ( ixEthAccPortEnable(firstPortId) != IX_SUCCESS)
    {
	printf("SwBridgeQos: Failed to start the Bridge Operation for port %u\n",
	       firstPortId);
	return (IX_FAIL);
    }

    if ( ixEthAccPortEnable(secondPortId) != IX_SUCCESS)
    {
	printf("SwBridgeQos: Failed to start the Bridge Operation for port %u\n",
	       secondPortId);
	return (IX_FAIL);
    }

    /* display the default settings for both ports */
    printf("Port %u configuration:\n", 
	   (UINT32)firstPortId);
    printf("- Accept Ingress VLAN-tagged traffic, VLAN tag range is [%u-%u]\n",
	   (UINT32)IX_ETHACC_CODELET_VLANID_MIN,
	   (UINT32)IX_ETHACC_CODELET_VLANID_MAX);
    printf("- Strip tag from ingress traffic\n");
    printf("- Bridge Ingress to port %u without tag\n",
	   (UINT32)secondPortId);
    printf("- Frame priorities may change the frame order (QoS enabled)\n");
    printf("- Insert a default tag [%u] to egress traffic\n",
	   (UINT32)IX_ETHACC_CODELET_VLANID_DEFAULT);
 
    printf("Port %u configuration:\n", 
	   (UINT32)secondPortId);
    printf("- Set as default\n\n");

    return (IX_SUCCESS);
}
/*
 * Function definition: ixEthAccCodeletSwBridgeQoSStop()
 *
 * Unconfigure QoS and Stop bridge datapath
 */
IX_STATUS ixEthAccCodeletSwBridgeQoSStop(IxEthAccPortId firstPortId, 
					 IxEthAccPortId secondPortId)
{

    /* Stop the receive and transmit traffic */
    if ( ixEthAccCodeletPortUnconfigure(firstPortId)
	 != IX_SUCCESS)
    {
	printf("SwBridgeQos: Failed to unconfigure the Bridge Operation for port %u\n",
	       firstPortId);
	return (IX_FAIL);
    }

    if ( ixEthAccCodeletPortUnconfigure(secondPortId)
	 != IX_SUCCESS)
    {
	printf("SwBridgeQos: Failed to unconfigure the Bridge Operation for port %u\n",
	       secondPortId);
	return (IX_FAIL);
    }

    if ( ixEthAccPortDisable(firstPortId)
	 != IX_SUCCESS)
    {
	printf("SwBridgeQos: Failed to stop the Bridge Operation for port %u\n",
	       firstPortId);
	return (IX_FAIL);
    }

    if ( ixEthAccPortDisable(secondPortId)
	 != IX_SUCCESS)
    {
	printf("SwBridgeQos: Failed to stop the Bridge Operation for port %u\n",
	       secondPortId);
	return (IX_FAIL);
    }

    /* Disable Xscale QoS */
    printf("Set Tx Scheduling discipline...\n");
    if (ixEthAccTxSchedulingDisciplineSet(firstPortId, 
					  FIFO_NO_PRIORITY)
	!= IX_ETH_ACC_SUCCESS)
    {
	printf("SwBridgeQos: Failed to set Tx Scheduling discipline port %u\n",
	       (UINT32)firstPortId);
	return (IX_FAIL);
    }
    if (ixEthAccTxSchedulingDisciplineSet(secondPortId, 
					  FIFO_NO_PRIORITY)
	!= IX_ETH_ACC_SUCCESS)
    {
	printf("SwBridgeQos: Failed to set Tx Scheduling discipline port %u\n",
	       (UINT32)secondPortId);
	return (IX_FAIL);
    }

    printf("Set Rx Scheduling discipline...\n");
    if (ixEthAccRxSchedulingDisciplineSet(FIFO_NO_PRIORITY)
	!= IX_ETH_ACC_SUCCESS)
    {
	printf("SwBridgeQos: Failed to set Rx Scheduling discipline\n");
	return (IX_FAIL);
    }

    /* Enable the EDB Port again and disable the VLAN/QoS configuration
     * note that no traffic will pass in this mode. After the restoring the
     * configuration to a known state that will not affect other operation
     * modes the ethDB port will be disabled
     */
    if ((ixEthDBPortEnable(firstPortId)) != IX_ETH_DB_SUCCESS)
    {
        printf("SwBridgeQoS: Cannot enable port %u\n", firstPortId);
        return (IX_FAIL);
    }
    if ((ixEthDBPortEnable(secondPortId)) != IX_ETH_DB_SUCCESS)
    {
        printf("SwBridgeQoS: Cannot enable port %u\n", secondPortId);
        return (IX_FAIL);
    }    

    /* Disable NPE QoS and VLAN setup */
    printf("Disable VLAN tagging...\n");
    if (ixEthDBEgressVlanRangeTaggingEnabledSet(firstPortId, 
						IX_ETHACC_CODELET_VLANID_MIN,
						IX_ETHACC_CODELET_VLANID_MAX,
						FALSE)
	!= IX_ETH_DB_SUCCESS)
    {
	printf("SwBridgeQos: Failed to disable VLAN Egress tagging for port %u\n",
	       firstPortId);
	return (IX_FAIL);
    }

    printf("Disable tagged frames...\n");
    if (ixEthDBAcceptableFrameTypeSet(firstPortId,
				      IX_ETH_DB_UNTAGGED_FRAMES)
	!= IX_ETH_DB_SUCCESS)
    {
	printf("SwBridgeQos: Failed to set the acceptable frame type for port %u\n",
	       firstPortId);
	return (IX_FAIL);
    }

    /* Disable the VLAN/QoS Feature to return to the initial processing
     * capabilities
     */
    if ( ixEthDBFeatureEnable((IxEthDBPortId) firstPortId, 
			      IX_ETH_DB_VLAN_QOS, 
			      FALSE) != IX_ETH_DB_SUCCESS )
    {
	printf("SwBridgeQoS: Failed to disable the VLAN/QoS Feature for port %u\n", 
	       firstPortId);
	return (IX_FAIL);
    }

    /* disable the ethDB port */
    if ((ixEthDBPortDisable(firstPortId)) != IX_ETH_DB_SUCCESS)
    {
        printf("SwBridgeQoS: Cannot disable port %u\n", firstPortId);
        return (IX_FAIL);
    }
    if ((ixEthDBPortDisable(secondPortId)) != IX_ETH_DB_SUCCESS)
    {
        printf("SwBridgeQoS: Cannot disable port %u\n", secondPortId);
        return (IX_FAIL);
    }    

    /* Restore the link speed to 100 Mbit */
    if (ixEthAccCodeletLinkDefaultSpeedSet(secondPortId)
	!= IX_SUCCESS)
    {
	printf("SwBridgeQos: Failed to reset port %u to a 100 Mbit port!\n",
	       secondPortId);
	return (IX_FAIL);
    }

    return (IX_SUCCESS);
}
Example #4
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);
}