/**
 * @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);
}

