Example #1
0
/**
 * @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;
        }
    }

    /* Initialize the event processor pausing state */
    ixEthDBEventProcessorPausing = FALSE;

    return IX_ETH_DB_SUCCESS;
}
Example #2
0
/**
 * @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_ETHNPE_PHYSICAL_ID_TO_NODE(portID), message, result);

    if (result == IX_SUCCESS)
    {
        ixEthDBPortInfo[portID].macAddressUploaded = TRUE;
    }

    return result;
}
Example #3
0
/**
 * @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)
{
    if (IX_FEATURE_CTRL_SWCONFIG_ENABLED ==
        ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
    {

    	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;
    }

    return IX_ETH_DB_FEATURE_UNAVAILABLE;
}
Example #4
0
/**
 * @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 ((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);
        }

        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;
}
Example #5
0
/*
 * 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();
    }
}
Example #6
0
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_ETHNPE_PHYSICAL_ID_TO_NODE(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
                {
                     ixOsalLog(IX_OSAL_LOG_LVL_WARNING,
                        IX_OSAL_LOG_DEV_STDOUT, 
                        "EthDB: (Maintenance) warning, Clearing Database records for all types for port %d\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);
    }
}
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;

}