diff options
Diffstat (limited to 'drivers/net/npe/IxNpeMhConfig.c')
| -rw-r--r-- | drivers/net/npe/IxNpeMhConfig.c | 608 | 
1 files changed, 608 insertions, 0 deletions
| diff --git a/drivers/net/npe/IxNpeMhConfig.c b/drivers/net/npe/IxNpeMhConfig.c new file mode 100644 index 000000000..50c8f2113 --- /dev/null +++ b/drivers/net/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; +} + + |