/******************************************************************************* *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. * *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. * *THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 ********************************************************************************/ /*******************************************************************************/ /*! \file sainit.c * \brief The file implements the functions to initialize the LL layer * */ /******************************************************************************/ #include <sys/cdefs.h> #include <dev/pms/config.h> #include <dev/pms/RefTisa/sallsdk/spc/saglobal.h> #ifdef SA_ENABLE_TRACE_FUNCTIONS #ifdef siTraceFileID #undef siTraceFileID #endif #define siTraceFileID 'F' #endif bit32 gLLDebugLevel = 3; #if defined(SALLSDK_DEBUG) bit32 gLLDebugLevelSet = 0; // block reinitialize from updating bit32 gLLLogFuncDebugLevel = 0; bit32 gLLSoftResetCounter = 0; #endif bit32 gPollForMissingInt; #ifdef FW_EVT_LOG_TST void *eventLogAddress = NULL; #endif extern bit32 gWait_3; extern bit32 gWait_2; bit32 gFPGA_TEST = 0; // If set unblock fpga functions /******************************************************************************/ /*! \brief Get the memory and lock requirement from LL layer * * Get the memory and lock requirement from LL layer * * \param agRoot Handles for this instance of SAS/SATA hardware * \param swConfig Pointer to the software configuration * \param memoryRequirement Point to the data structure that holds the different * chunks of memory that are required * \param usecsPerTick micro-seconds per tick for the LL layer * \param maxNumLocks maximum number of locks for the LL layer * * \return -void- * */ /*******************************************************************************/ GLOBAL void saGetRequirements( agsaRoot_t *agRoot, agsaSwConfig_t *swConfig, agsaMemoryRequirement_t *memoryRequirement, bit32 *usecsPerTick, bit32 *maxNumLocks ) { bit32 memoryReqCount = 0; bit32 i; static mpiConfig_t mpiConfig; static mpiMemReq_t mpiMemoryRequirement; /* sanity check */ SA_ASSERT((agNULL != swConfig), ""); SA_ASSERT((agNULL != memoryRequirement), ""); SA_ASSERT((agNULL != usecsPerTick), ""); SA_ASSERT((agNULL != maxNumLocks), ""); si_memset(&mpiMemoryRequirement, 0, sizeof(mpiMemReq_t)); si_memset(&mpiConfig, 0, sizeof(mpiConfig_t)); SA_DBG1(("saGetRequirements:agRoot %p swConfig %p memoryRequirement %p usecsPerTick %p maxNumLocks %p\n",agRoot, swConfig,memoryRequirement,usecsPerTick,maxNumLocks)); SA_DBG1(("saGetRequirements: usecsPerTick 0x%x (%d)\n",*usecsPerTick,*usecsPerTick)); /* Get Resource Requirements for SPC MPI */ /* Set the default/specified requirements swConfig from TD layer */ siConfiguration(agRoot, &mpiConfig, agNULL, swConfig); mpiRequirementsGet(&mpiConfig, &mpiMemoryRequirement); /* memory requirement for saRoot, CACHE memory */ memoryRequirement->agMemory[LLROOT_MEM_INDEX].singleElementLength = sizeof(agsaLLRoot_t); memoryRequirement->agMemory[LLROOT_MEM_INDEX].numElements = 1; memoryRequirement->agMemory[LLROOT_MEM_INDEX].totalLength = sizeof(agsaLLRoot_t); memoryRequirement->agMemory[LLROOT_MEM_INDEX].alignment = sizeof(void *); memoryRequirement->agMemory[LLROOT_MEM_INDEX].type = AGSA_CACHED_MEM; memoryReqCount ++; SA_DBG1(("saGetRequirements: agMemory[LLROOT_MEM_INDEX] singleElementLength = 0x%x totalLength = 0x%x align = 0x%x type %x\n", memoryRequirement->agMemory[LLROOT_MEM_INDEX].singleElementLength, memoryRequirement->agMemory[LLROOT_MEM_INDEX].totalLength, memoryRequirement->agMemory[LLROOT_MEM_INDEX].alignment, memoryRequirement->agMemory[LLROOT_MEM_INDEX].type )); /* memory requirement for Device Links, CACHE memory */ memoryRequirement->agMemory[DEVICELINK_MEM_INDEX].singleElementLength = sizeof(agsaDeviceDesc_t); memoryRequirement->agMemory[DEVICELINK_MEM_INDEX].numElements = swConfig->numDevHandles; memoryRequirement->agMemory[DEVICELINK_MEM_INDEX].totalLength = sizeof(agsaDeviceDesc_t) * swConfig->numDevHandles; memoryRequirement->agMemory[DEVICELINK_MEM_INDEX].alignment = sizeof(void *); memoryRequirement->agMemory[DEVICELINK_MEM_INDEX].type = AGSA_CACHED_MEM; memoryReqCount ++; SA_DBG1(("saGetRequirements: agMemory[DEVICELINK_MEM_INDEX] singleElementLength = 0x%x totalLength = 0x%x align = 0x%x type %x\n", memoryRequirement->agMemory[DEVICELINK_MEM_INDEX].singleElementLength, memoryRequirement->agMemory[DEVICELINK_MEM_INDEX].totalLength, memoryRequirement->agMemory[DEVICELINK_MEM_INDEX].alignment, memoryRequirement->agMemory[DEVICELINK_MEM_INDEX].type )); /* memory requirement for IORequest Links, CACHE memory */ memoryRequirement->agMemory[IOREQLINK_MEM_INDEX].singleElementLength = sizeof(agsaIORequestDesc_t); /* Add SA_RESERVED_REQUEST_COUNT to guarantee quality of service */ memoryRequirement->agMemory[IOREQLINK_MEM_INDEX].numElements = swConfig->maxActiveIOs + SA_RESERVED_REQUEST_COUNT; memoryRequirement->agMemory[IOREQLINK_MEM_INDEX].totalLength = sizeof(agsaIORequestDesc_t) * memoryRequirement->agMemory[IOREQLINK_MEM_INDEX].numElements; memoryRequirement->agMemory[IOREQLINK_MEM_INDEX].alignment = sizeof(void *); memoryRequirement->agMemory[IOREQLINK_MEM_INDEX].type = AGSA_CACHED_MEM; memoryReqCount ++; SA_DBG1(("saGetRequirements: agMemory[IOREQLINK_MEM_INDEX] singleElementLength = 0x%x totalLength = 0x%x align = 0x%x type %x\n", memoryRequirement->agMemory[IOREQLINK_MEM_INDEX].singleElementLength, memoryRequirement->agMemory[IOREQLINK_MEM_INDEX].totalLength, memoryRequirement->agMemory[IOREQLINK_MEM_INDEX].alignment, memoryRequirement->agMemory[IOREQLINK_MEM_INDEX].type )); /* memory requirement for Timer Links, CACHE memory */ memoryRequirement->agMemory[TIMERLINK_MEM_INDEX].singleElementLength = sizeof(agsaTimerDesc_t); memoryRequirement->agMemory[TIMERLINK_MEM_INDEX].numElements = NUM_TIMERS; memoryRequirement->agMemory[TIMERLINK_MEM_INDEX].totalLength = sizeof(agsaTimerDesc_t) * NUM_TIMERS; memoryRequirement->agMemory[TIMERLINK_MEM_INDEX].alignment = sizeof(void *); memoryRequirement->agMemory[TIMERLINK_MEM_INDEX].type = AGSA_CACHED_MEM; memoryReqCount ++; SA_DBG1(("saGetRequirements: agMemory[TIMERLINK_MEM_INDEX] singleElementLength = 0x%x totalLength = 0x%x align = 0x%x type %x\n", memoryRequirement->agMemory[TIMERLINK_MEM_INDEX].singleElementLength, memoryRequirement->agMemory[TIMERLINK_MEM_INDEX].totalLength, memoryRequirement->agMemory[TIMERLINK_MEM_INDEX].alignment, memoryRequirement->agMemory[TIMERLINK_MEM_INDEX].type )); #ifdef SA_ENABLE_TRACE_FUNCTIONS /* memory requirement for LL trace memory */ memoryRequirement->agMemory[LL_FUNCTION_TRACE].singleElementLength = 1; memoryRequirement->agMemory[LL_FUNCTION_TRACE].numElements = swConfig->TraceBufferSize; memoryRequirement->agMemory[LL_FUNCTION_TRACE].totalLength = swConfig->TraceBufferSize; memoryRequirement->agMemory[LL_FUNCTION_TRACE].alignment = sizeof(void *); memoryRequirement->agMemory[LL_FUNCTION_TRACE].type = AGSA_CACHED_MEM; memoryReqCount ++; SA_DBG1(("saGetRequirements: agMemory[LL_FUNCTION_TRACE] singleElementLength = 0x%x totalLength = 0x%x align = 0x%x type %x\n", memoryRequirement->agMemory[LL_FUNCTION_TRACE].singleElementLength, memoryRequirement->agMemory[LL_FUNCTION_TRACE].totalLength, memoryRequirement->agMemory[LL_FUNCTION_TRACE].alignment, memoryRequirement->agMemory[LL_FUNCTION_TRACE].type )); #endif /* END SA_ENABLE_TRACE_FUNCTIONS */ #ifdef FAST_IO_TEST { agsaMem_t *agMemory = memoryRequirement->agMemory; /* memory requirement for Super IO CACHE memory */ agMemory[LL_FAST_IO].singleElementLength = sizeof(saFastRequest_t); agMemory[LL_FAST_IO].numElements = LL_FAST_IO_SIZE; agMemory[LL_FAST_IO].totalLength = LL_FAST_IO_SIZE * agMemory[LL_FAST_IO].singleElementLength; agMemory[LL_FAST_IO].alignment = sizeof(void*); agMemory[LL_FAST_IO].type = AGSA_CACHED_MEM; memoryReqCount ++; SA_DBG1(("saGetRequirements: agMemory[LL_FAST_IO] singleElementLength = 0x%x totalLength = 0x%x align = 0x%x type %x\n", memoryRequirement->agMemory[LL_FAST_IO].singleElementLength, memoryRequirement->agMemory[LL_FAST_IO].totalLength, memoryRequirement->agMemory[LL_FAST_IO].alignment, memoryRequirement->agMemory[LL_FAST_IO].type )); } #endif #ifdef SA_ENABLE_HDA_FUNCTIONS { agsaMem_t *agMemory = memoryRequirement->agMemory; /* memory requirement for HDA FW image */ agMemory[HDA_DMA_BUFFER].singleElementLength = (1024 * 1024); /* must be greater than size of aap1 fw image */ agMemory[HDA_DMA_BUFFER].numElements = 1; agMemory[HDA_DMA_BUFFER].totalLength = agMemory[HDA_DMA_BUFFER].numElements * agMemory[HDA_DMA_BUFFER].singleElementLength; agMemory[HDA_DMA_BUFFER].alignment = 32; agMemory[HDA_DMA_BUFFER].type = AGSA_DMA_MEM; memoryReqCount ++; SA_DBG1(("saGetRequirements: agMemory[HDA_DMA_BUFFER] singleElementLength = 0x%x totalLength = 0x%x align = 0x%x type %x\n", memoryRequirement->agMemory[HDA_DMA_BUFFER].singleElementLength, memoryRequirement->agMemory[HDA_DMA_BUFFER].totalLength, memoryRequirement->agMemory[HDA_DMA_BUFFER].alignment, memoryRequirement->agMemory[HDA_DMA_BUFFER].type )); } #endif /* SA_ENABLE_HDA_FUNCTIONS */ /* memory requirement for MPI MSGU layer, DMA memory */ for ( i = 0; i < mpiMemoryRequirement.count; i ++ ) { memoryRequirement->agMemory[memoryReqCount].singleElementLength = mpiMemoryRequirement.region[i].elementSize; memoryRequirement->agMemory[memoryReqCount].numElements = mpiMemoryRequirement.region[i].numElements; memoryRequirement->agMemory[memoryReqCount].totalLength = mpiMemoryRequirement.region[i].totalLength; memoryRequirement->agMemory[memoryReqCount].alignment = mpiMemoryRequirement.region[i].alignment; memoryRequirement->agMemory[memoryReqCount].type = mpiMemoryRequirement.region[i].type; SA_DBG1(("saGetRequirements:MPI agMemory[%d] singleElementLength = 0x%x totalLength = 0x%x align = 0x%x type %x\n", memoryReqCount, memoryRequirement->agMemory[memoryReqCount].singleElementLength, memoryRequirement->agMemory[memoryReqCount].totalLength, memoryRequirement->agMemory[memoryReqCount].alignment, memoryRequirement->agMemory[memoryReqCount].type )); memoryReqCount ++; } /* requirement for locks */ if (swConfig->param3 == agNULL) { *maxNumLocks = (LL_IOREQ_IBQ_LOCK + AGSA_MAX_INBOUND_Q ); SA_DBG1(("saGetRequirements: param3 == agNULL maxNumLocks %d\n", *maxNumLocks )); } else { agsaQueueConfig_t *queueConfig; queueConfig = (agsaQueueConfig_t *)swConfig->param3; *maxNumLocks = (LL_IOREQ_IBQ_LOCK_PARM + queueConfig->numInboundQueues ); SA_DBG1(("saGetRequirements: maxNumLocks %d\n", *maxNumLocks )); } /* setup the time tick */ *usecsPerTick = SA_USECS_PER_TICK; SA_ASSERT(memoryReqCount < AGSA_NUM_MEM_CHUNKS, "saGetRequirements: Exceed max number of memory place holder"); /* set up memory requirement count */ memoryRequirement->count = memoryReqCount; swConfig->legacyInt_X = 1; swConfig->max_MSI_InterruptVectors = 32; swConfig->max_MSIX_InterruptVectors = 64;//16; SA_DBG1(("saGetRequirements: swConfig->stallUsec %d\n",swConfig->stallUsec )); #ifdef SA_CONFIG_MDFD_REGISTRY SA_DBG1(("saGetRequirements: swConfig->disableMDF %d\n",swConfig->disableMDF)); #endif /*SA_CONFIG_MDFD_REGISTRY*/ /*SA_DBG1(("saGetRequirements: swConfig->enableDIF %d\n",swConfig->enableDIF ));*/ /*SA_DBG1(("saGetRequirements: swConfig->enableEncryption %d\n",swConfig->enableEncryption ));*/ #ifdef SA_ENABLE_HDA_FUNCTIONS swConfig->hostDirectAccessSupport = 1; swConfig->hostDirectAccessMode = 0; #else swConfig->hostDirectAccessSupport = 0; swConfig->hostDirectAccessMode = 0; #endif } /******************************************************************************/ /*! \brief Initialize the Hardware * * Initialize the Hardware * * \param agRoot Handles for this instance of SAS/SATA hardware * \param memoryAllocated Point to the data structure that holds the different chunks of memory that are required * \param hwConfig Pointer to the hardware configuration * \param swConfig Pointer to the software configuration * \param usecsPerTick micro-seconds per tick for the LL layer * * \return If initialization is successful * - \e AGSA_RC_SUCCESS initialization is successful * - \e AGSA_RC_FAILURE initialization is not successful */ /*******************************************************************************/ GLOBAL bit32 saInitialize( agsaRoot_t *agRoot, agsaMemoryRequirement_t *memoryAllocated, agsaHwConfig_t *hwConfig, agsaSwConfig_t *swConfig, bit32 usecsPerTick ) { agsaLLRoot_t *saRoot; agsaDeviceDesc_t *pDeviceDesc; agsaIORequestDesc_t *pRequestDesc; agsaTimerDesc_t *pTimerDesc; agsaPort_t *pPort; agsaPortMap_t *pPortMap; agsaDeviceMap_t *pDeviceMap; agsaIOMap_t *pIOMap; bit32 maxNumIODevices; bit32 i, j; static mpiMemReq_t mpiMemoryAllocated; bit32 Tried_NO_HDA = agFALSE; bit32 Double_Reset_HDA = agFALSE; bit32 ret = AGSA_RC_SUCCESS; #ifdef FAST_IO_TEST void *fr; /* saFastRequest_t */ bit32 size; bit32 alignment; #endif /* sanity check */ SA_ASSERT((agNULL != agRoot), ""); SA_ASSERT((agNULL != memoryAllocated), ""); SA_ASSERT((agNULL != hwConfig), ""); SA_ASSERT((agNULL != swConfig), ""); SA_ASSERT((LLROOT_MEM_INDEX < memoryAllocated->count), ""); SA_ASSERT((DEVICELINK_MEM_INDEX < memoryAllocated->count), ""); SA_ASSERT((IOREQLINK_MEM_INDEX < memoryAllocated->count), ""); SA_ASSERT((TIMERLINK_MEM_INDEX < memoryAllocated->count), ""); si_memset(&mpiMemoryAllocated, 0, sizeof(mpiMemReq_t)); si_macro_check(agRoot); SA_DBG1(("saInitialize: WAIT_INCREMENT %d\n", WAIT_INCREMENT )); SA_DBG1(("saInitialize: usecsPerTick %d\n", usecsPerTick )); if(! smIS_SPC(agRoot)) { if(! smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: ossaHwRegReadConfig32 ID reads as %08X\n", ossaHwRegReadConfig32(agRoot,0 ) )); SA_DBG1(("saInitialize: expect %08X or %08X or\n", VEN_DEV_SPCV, VEN_DEV_SPCVE)); SA_DBG1(("saInitialize: expect %08X or %08X or\n", VEN_DEV_SPCVP, VEN_DEV_SPCVEP)); SA_DBG1(("saInitialize: expect %08X or %08X\n", VEN_DEV_ADAPVEP, VEN_DEV_ADAPVP)); return AGSA_RC_FAILURE; } } if( smIS_SPC(agRoot) && smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: Macro error !smIS_SPC %d smIS_SPCv %d smIS_SFC %d\n",smIS_SPC(agRoot),smIS_SPCV(agRoot), smIS_SFC(agRoot) )); return AGSA_RC_FAILURE; } /* Check the memory allocated */ for ( i = 0; i < memoryAllocated->count; i ++ ) { /* If memory allocation failed */ if (memoryAllocated->agMemory[i].singleElementLength && memoryAllocated->agMemory[i].numElements) { if ( (0 != memoryAllocated->agMemory[i].numElements) && (0 == memoryAllocated->agMemory[i].totalLength) ) { /* return failure */ SA_DBG1(("saInitialize:AGSA_RC_FAILURE Memory[%d] singleElementLength = 0x%x numElements = 0x%x NOT allocated\n", i, memoryAllocated->agMemory[i].singleElementLength, memoryAllocated->agMemory[i].numElements)); ret = AGSA_RC_FAILURE; return ret; } else { SA_DBG1(("saInitialize: Memory[%d] singleElementLength = 0x%x numElements = 0x%x allocated %p\n", i, memoryAllocated->agMemory[i].singleElementLength, memoryAllocated->agMemory[i].numElements, memoryAllocated->agMemory[i].virtPtr)); } } } /* Get the saRoot memory address */ saRoot = (agsaLLRoot_t *) (memoryAllocated->agMemory[LLROOT_MEM_INDEX].virtPtr); SA_ASSERT((agNULL != saRoot), "saRoot"); if(agNULL == saRoot) { SA_DBG1(("saInitialize:AGSA_RC_FAILURE saRoot\n")); return AGSA_RC_FAILURE; } agRoot->sdkData = (void *) saRoot; SA_DBG1(("saInitialize: saRoot %p\n",saRoot)); if ( (memoryAllocated != &saRoot->memoryAllocated) || (hwConfig != &saRoot->hwConfig) || (swConfig != &saRoot->swConfig) ) { agsaMemoryRequirement_t *memA = &saRoot->memoryAllocated; agsaHwConfig_t *hwC = &saRoot->hwConfig; agsaSwConfig_t *swC = &saRoot->swConfig; /* Copy data here */ *memA = *memoryAllocated; *hwC = *hwConfig; *swC = *swConfig; } #if defined(SALLSDK_DEBUG) if(gLLDebugLevelSet == 0) { gLLDebugLevelSet = 1; gLLDebugLevel = swConfig->sallDebugLevel & 0xF; SA_DBG1(("saInitialize: gLLDebugLevel %x\n",gLLDebugLevel)); } #endif /* SALLSDK_DEBUG */ #ifdef SA_ENABLE_TRACE_FUNCTIONS saRoot->TraceBufferLength = memoryAllocated->agMemory[LL_FUNCTION_TRACE].totalLength; saRoot->TraceBuffer = memoryAllocated->agMemory[LL_FUNCTION_TRACE].virtPtr; siEnableTracing ( agRoot ); /* */ #endif /* SA_ENABLE_TRACE_FUNCTIONS */ #ifdef FAST_IO_TEST { agsaMem_t *agMemory = memoryAllocated->agMemory; /* memory requirement for Super IO CACHE memory */ size = sizeof(saRoot->freeFastReq) / sizeof(saRoot->freeFastReq[0]); SA_ASSERT(size == agMemory[LL_FAST_IO].numElements, ""); SA_ASSERT(agMemory[LL_FAST_IO].virtPtr, ""); SA_ASSERT((agMemory[LL_FAST_IO].singleElementLength == sizeof(saFastRequest_t)) && (agMemory[LL_FAST_IO].numElements == LL_FAST_IO_SIZE) && (agMemory[LL_FAST_IO].totalLength == agMemory[LL_FAST_IO].numElements * agMemory[LL_FAST_IO].singleElementLength), ""); for (i = 0, alignment = agMemory[LL_FAST_IO].alignment, fr = agMemory[LL_FAST_IO].virtPtr; i < size; i++, fr = (void*)((bitptr)fr + (bitptr)(((bit32)sizeof(saFastRequest_t) + alignment - 1) & ~(alignment - 1)))) { saRoot->freeFastReq[i] = fr; } saRoot->freeFastIdx = size; } #endif /* FAST_IO_TEST*/ smTraceFuncEnter(hpDBG_VERY_LOUD, "m1"); SA_DBG1(("saInitialize: swConfig->PortRecoveryResetTimer %x\n",swConfig->PortRecoveryResetTimer )); SA_DBG1(("saInitialize: hwDEVICE_ID_VENDID 0x%08x\n", ossaHwRegReadConfig32(agRoot,0))); SA_DBG1(("saInitialize: CFGSTAT CFGCMD 0x%08x\n", ossaHwRegReadConfig32(agRoot,4))); SA_DBG1(("saInitialize: CLSCODE REVID 0x%08x\n", ossaHwRegReadConfig32(agRoot,8))); SA_DBG1(("saInitialize: BIST DT HDRTYPE LATTIM CLSIZE 0x%08x\n", ossaHwRegReadConfig32(agRoot,12))); SA_DBG1(("saInitialize: hwSVID 0x%08x\n", ossaHwRegReadConfig32(agRoot,44))); #ifdef SA_ENABLE_PCI_TRIGGER SA_DBG1(("saInitialize: SA_ENABLE_PCI_TRIGGER a 0x%08x %p\n", saRoot->swConfig.PCI_trigger,&saRoot->swConfig.PCI_trigger)); if( saRoot->swConfig.PCI_trigger & PCI_TRIGGER_INIT_TEST ) { SA_DBG1(("saInitialize: SA_ENABLE_PCI_TRIGGER 0x%08x %p\n", saRoot->swConfig.PCI_trigger,&saRoot->swConfig.PCI_trigger)); saRoot->swConfig.PCI_trigger &= ~PCI_TRIGGER_INIT_TEST; siPCITriger(agRoot); } #endif /* SA_ENABLE_PCI_TRIGGER */ saRoot->ChipId = (ossaHwRegReadConfig32(agRoot,0) & 0xFFFF0000); SA_DBG1(("saInitialize: saRoot->ChipId 0x%08x\n", saRoot->ChipId)); siUpdateBarOffsetTable(agRoot,saRoot->ChipId); if(saRoot->ChipId == VEN_DEV_SPC) { if(! smIS_SPC(agRoot)) { SA_DBG1(("saInitialize: smIS_SPC macro fail !!!!\n" )); smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "m1"); return AGSA_RC_FAILURE; } SA_DBG1(("saInitialize: SPC \n" )); } else if(saRoot->ChipId == VEN_DEV_HIL ) { SA_DBG1(("saInitialize: SPC HIL\n" )); if(! smIS_SPC(agRoot)) { SA_DBG1(("saInitialize: smIS_SPC macro fail !!!!\n" )); smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "m1"); return AGSA_RC_FAILURE; } } else if(saRoot->ChipId == VEN_DEV_SPCV) { SA_DBG1(("saInitialize: SPC V\n" )); if(! smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: smIS_SPCV macro fail !!!!\n" )); smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "m1"); return AGSA_RC_FAILURE; } } else if(saRoot->ChipId == VEN_DEV_SPCVE) { SA_DBG1(("saInitialize: SPC VE\n" )); if(! smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: smIS_SPCV macro fail !!!!\n" )); smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "m1"); return AGSA_RC_FAILURE; } } else if(saRoot->ChipId == VEN_DEV_SPCVP) { SA_DBG1(("saInitialize: SPC VP\n" )); if(! smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: smIS_SPCV macro fail !!!!\n" )); smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "m1"); return AGSA_RC_FAILURE; } } else if(saRoot->ChipId == VEN_DEV_SPCVEP) { SA_DBG1(("saInitialize: SPC VEP\n" )); if(! smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: smIS_SPCV macro fail !!!!\n" )); smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "m1"); return AGSA_RC_FAILURE; } } else if(saRoot->ChipId == VEN_DEV_ADAPVP) { SA_DBG1(("saInitialize: Adaptec 8088\n" )); } else if(saRoot->ChipId == VEN_DEV_ADAPVEP) { SA_DBG1(("saInitialize: Adaptec 8089\n" )); } else if(saRoot->ChipId == VEN_DEV_SPC12V) { SA_DBG1(("saInitialize: SPC 12V\n" )); if(! smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: smIS_SPCV macro fail !!!!\n" )); smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "m1"); return AGSA_RC_FAILURE; } } else if(saRoot->ChipId == VEN_DEV_SPC12VE) { SA_DBG1(("saInitialize: SPC 12VE\n" )); if(! smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: smIS_SPCV macro fail !!!!\n" )); smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "m1"); return AGSA_RC_FAILURE; } } else if(saRoot->ChipId == VEN_DEV_SPC12VP) { SA_DBG1(("saInitialize: SPC 12VP\n" )); if(! smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: smIS_SPCV macro fail !!!!\n" )); smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "m1"); return AGSA_RC_FAILURE; } } else if(saRoot->ChipId == VEN_DEV_SPC12VEP) { SA_DBG1(("saInitialize: SPC 12VEP\n" )); if(! smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: smIS_SPCV macro fail !!!!\n" )); smTraceFuncExit(hpDBG_VERY_LOUD, 'j', "m1"); return AGSA_RC_FAILURE; } } else if(saRoot->ChipId == VEN_DEV_SPC12ADP) { SA_DBG1(("saInitialize: SPC 12ADP\n" )); if(! smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: smIS_SPCV macro fail !!!!\n" )); smTraceFuncExit(hpDBG_VERY_LOUD, 'k', "m1"); return AGSA_RC_FAILURE; } } else if(saRoot->ChipId == VEN_DEV_SPC12ADPE) { SA_DBG1(("saInitialize: SPC 12ADPE\n" )); if(! smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: smIS_SPCV macro fail !!!!\n" )); smTraceFuncExit(hpDBG_VERY_LOUD, 'l', "m1"); return AGSA_RC_FAILURE; } } else if(saRoot->ChipId == VEN_DEV_SPC12ADPP) { SA_DBG1(("saInitialize: SPC 12ADPP\n" )); if(! smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: smIS_SPCV macro fail !!!!\n" )); smTraceFuncExit(hpDBG_VERY_LOUD, 'm', "m1"); return AGSA_RC_FAILURE; } } else if(saRoot->ChipId == VEN_DEV_SPC12ADPEP) { SA_DBG1(("saInitialize: SPC 12ADPEP\n" )); if(! smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: smIS_SPCV macro fail !!!!\n" )); smTraceFuncExit(hpDBG_VERY_LOUD, 'n', "m1"); return AGSA_RC_FAILURE; } } else if(saRoot->ChipId == VEN_DEV_SPC12SATA) { SA_DBG1(("saInitialize: SPC12SATA\n" )); if(! smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: smIS_SPCV macro fail !!!!\n" )); smTraceFuncExit(hpDBG_VERY_LOUD, 'o', "m1"); return AGSA_RC_FAILURE; } } else if(saRoot->ChipId == VEN_DEV_9015) { SA_DBG1(("saInitialize: SPC 12V FPGA\n" )); if(! smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: smIS_SPCV macro fail !!!!\n" )); smTraceFuncExit(hpDBG_VERY_LOUD, 'p', "m1"); return AGSA_RC_FAILURE; } } else if(saRoot->ChipId == VEN_DEV_9060) { SA_DBG1(("saInitialize: SPC 12V FPGA B\n" )); if(! smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: smIS_SPCV macro fail !!!!\n" )); smTraceFuncExit(hpDBG_VERY_LOUD, 'q', "m1"); return AGSA_RC_FAILURE; } } else if(saRoot->ChipId == VEN_DEV_SFC) { SA_DBG1(("saInitialize: SFC \n" )); } else { SA_DBG1(("saInitialize saRoot->ChipId %8X expect %8X or %8X\n", saRoot->ChipId,VEN_DEV_SPC, VEN_DEV_SPCV)); SA_ASSERT(0, "ChipId"); smTraceFuncExit(hpDBG_VERY_LOUD, 'r', "m1"); return AGSA_RC_FAILURE; } if( smIS_SPC(agRoot)) { SA_DBG1(("saInitialize: Rev is A %d B %d C %d\n",smIsCfgSpcREV_A(agRoot),smIsCfgSpcREV_B(agRoot),smIsCfgSpcREV_C(agRoot))); } else { SA_DBG1(("saInitialize: Rev is A %d B %d C %d\n",smIsCfgVREV_A(agRoot),smIsCfgVREV_B(agRoot),smIsCfgVREV_C(agRoot))); } if( smIS_SPC(agRoot)) { SA_DBG1(("saInitialize: LINK_CTRL 0x%08x Speed 0x%X Lanes 0x%X \n", ossaHwRegReadConfig32(agRoot,128), ((ossaHwRegReadConfig32(agRoot,128) & 0x000F0000) >> 16), ((ossaHwRegReadConfig32(agRoot,128) & 0x0FF00000) >> 20) )); } else { SA_DBG1(("saInitialize: LINK_CTRL 0x%08x Speed 0x%X Lanes 0x%X \n", ossaHwRegReadConfig32(agRoot,208), ((ossaHwRegReadConfig32(agRoot,208) & 0x000F0000) >> 16), ((ossaHwRegReadConfig32(agRoot,208) & 0x0FF00000) >> 20) )); } SA_DBG1(("saInitialize: V_SoftResetRegister %08X\n", ossaHwRegReadExt(agRoot, PCIBAR0, V_SoftResetRegister ))); /* SA_DBG1(("saInitialize:TOP_BOOT_STRAP STRAP_BIT %X\n", ossaHwRegReadExt(agRoot, PCIBAR1, 0) )); SA_DBG1(("SPC_REG_TOP_DEVICE_ID %8X expect %08X\n", ossaHwRegReadExt(agRoot, PCIBAR2, SPC_REG_TOP_DEVICE_ID), SPC_TOP_DEVICE_ID)); SA_DBG1(("SPC_REG_TOP_DEVICE_ID %8X expect %08X\n", siHalRegReadExt( agRoot, GEN_SPC_REG_TOP_DEVICE_ID,SPC_REG_TOP_DEVICE_ID ) , SPC_TOP_DEVICE_ID)); SA_DBG1(("SPC_REG_TOP_BOOT_STRAP %8X expect %08X\n", ossaHwRegReadExt(agRoot, PCIBAR2, SPC_REG_TOP_BOOT_STRAP), SPC_TOP_BOOT_STRAP)); SA_DBG1(("swConfig->numSASDevHandles =%d\n", swConfig->numDevHandles)); */ smTrace(hpDBG_VERY_LOUD,"29",swConfig->numDevHandles); /* TP:29 swConfig->numDevHandles */ /* Setup Device link */ /* Save the information of allocated device Link memory */ saRoot->deviceLinkMem = memoryAllocated->agMemory[DEVICELINK_MEM_INDEX]; if(agNULL == saRoot->deviceLinkMem.virtPtr) { SA_ASSERT(0, "deviceLinkMem"); smTraceFuncExit(hpDBG_VERY_LOUD, 'q', "m1"); return AGSA_RC_FAILURE; } si_memset(saRoot->deviceLinkMem.virtPtr, 0, saRoot->deviceLinkMem.totalLength); SA_DBG2(("saInitialize: [%d] saRoot->deviceLinkMem VirtPtr=%p PhysicalLo=%x Count=%x Total=%x type %x\n", DEVICELINK_MEM_INDEX, saRoot->deviceLinkMem.virtPtr, saRoot->deviceLinkMem.phyAddrLower, saRoot->deviceLinkMem.numElements, saRoot->deviceLinkMem.totalLength, saRoot->deviceLinkMem.type)); maxNumIODevices = swConfig->numDevHandles; SA_DBG2(("saInitialize: maxNumIODevices=%d, swConfig->numDevHandles=%d \n", maxNumIODevices, swConfig->numDevHandles)); #ifdef SA_ENABLE_PCI_TRIGGER SA_DBG1(("saInitialize: swConfig->PCI_trigger= 0x%x\n", swConfig->PCI_trigger)); #endif /* SA_ENABLE_PCI_TRIGGER */ /* Setup free IO Devices link list */ saLlistInitialize(&(saRoot->freeDevicesList)); for ( i = 0; i < (bit32) maxNumIODevices; i ++ ) { /* get the pointer to the device descriptor */ pDeviceDesc = (agsaDeviceDesc_t *) AGSAMEM_ELEMENT_READ(&(saRoot->deviceLinkMem), i); /* Initialize device descriptor */ saLlinkInitialize(&(pDeviceDesc->linkNode)); pDeviceDesc->initiatorDevHandle.osData = agNULL; pDeviceDesc->initiatorDevHandle.sdkData = agNULL; pDeviceDesc->targetDevHandle.osData = agNULL; pDeviceDesc->targetDevHandle.sdkData = agNULL; pDeviceDesc->deviceType = SAS_SATA_UNKNOWN_DEVICE; pDeviceDesc->pPort = agNULL; pDeviceDesc->DeviceMapIndex = 0; saLlistInitialize(&(pDeviceDesc->pendingIORequests)); /* Add the device descriptor to the free IO device link list */ saLlistAdd(&(saRoot->freeDevicesList), &(pDeviceDesc->linkNode)); } /* Setup IO Request link */ /* Save the information of allocated IO Request Link memory */ saRoot->IORequestMem = memoryAllocated->agMemory[IOREQLINK_MEM_INDEX]; si_memset(saRoot->IORequestMem.virtPtr, 0, saRoot->IORequestMem.totalLength); SA_DBG2(("saInitialize: [%d] saRoot->IORequestMem VirtPtr=%p PhysicalLo=%x Count=%x Total=%x type %x\n", IOREQLINK_MEM_INDEX, saRoot->IORequestMem.virtPtr, saRoot->IORequestMem.phyAddrLower, saRoot->IORequestMem.numElements, saRoot->IORequestMem.totalLength, saRoot->IORequestMem.type)); /* Setup free IO Request link list */ saLlistIOInitialize(&(saRoot->freeIORequests)); saLlistIOInitialize(&(saRoot->freeReservedRequests)); for ( i = 0; i < swConfig->maxActiveIOs; i ++ ) { /* get the pointer to the request descriptor */ pRequestDesc = (agsaIORequestDesc_t *) AGSAMEM_ELEMENT_READ(&(saRoot->IORequestMem), i); /* Initialize request descriptor */ saLlinkInitialize(&(pRequestDesc->linkNode)); pRequestDesc->valid = agFALSE; pRequestDesc->requestType = AGSA_REQ_TYPE_UNKNOWN; pRequestDesc->pIORequestContext = agNULL; pRequestDesc->HTag = i; pRequestDesc->pDevice = agNULL; pRequestDesc->pPort = agNULL; /* Add the request descriptor to the free Reserved Request link list */ /* SMP request must get service so reserve one request when first SMP completes */ if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) { saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequestDesc->linkNode)); } else { /* Add the request descriptor to the free IO Request link list */ saLlistIOAdd(&(saRoot->freeIORequests), &(pRequestDesc->linkNode)); } } /* Setup timer link */ /* Save the information of allocated timer Link memory */ saRoot->timerLinkMem = memoryAllocated->agMemory[TIMERLINK_MEM_INDEX]; si_memset(saRoot->timerLinkMem.virtPtr, 0, saRoot->timerLinkMem.totalLength); SA_DBG2(("saInitialize: [%d] saRoot->timerLinkMem VirtPtr=%p PhysicalLo=%x Count=%x Total=%x type %x\n", TIMERLINK_MEM_INDEX, saRoot->timerLinkMem.virtPtr, saRoot->timerLinkMem.phyAddrLower, saRoot->timerLinkMem.numElements, saRoot->timerLinkMem.totalLength, saRoot->timerLinkMem.type )); /* Setup free timer link list */ saLlistInitialize(&(saRoot->freeTimers)); for ( i = 0; i < NUM_TIMERS; i ++ ) { /* get the pointer to the timer descriptor */ pTimerDesc = (agsaTimerDesc_t *) AGSAMEM_ELEMENT_READ(&(saRoot->timerLinkMem), i); /* Initialize timer descriptor */ saLlinkInitialize(&(pTimerDesc->linkNode)); pTimerDesc->valid = agFALSE; pTimerDesc->timeoutTick = 0; pTimerDesc->pfnTimeout = agNULL; pTimerDesc->Event = 0; pTimerDesc->pParm = agNULL; /* Add the timer descriptor to the free timer link list */ saLlistAdd(&(saRoot->freeTimers), &(pTimerDesc->linkNode)); } /* Setup valid timer link list */ saLlistInitialize(&(saRoot->validTimers)); /* Setup Phys */ /* Setup PhyCount */ saRoot->phyCount = (bit8) hwConfig->phyCount; /* Init Phy data structure */ for ( i = 0; i < saRoot->phyCount; i ++ ) { saRoot->phys[i].pPort = agNULL; saRoot->phys[i].phyId = (bit8) i; /* setup phy status is PHY_STOPPED */ PHY_STATUS_SET(&(saRoot->phys[i]), PHY_STOPPED); } /* Setup Ports */ /* Setup PortCount */ saRoot->portCount = saRoot->phyCount; /* Setup free port link list */ saLlistInitialize(&(saRoot->freePorts)); for ( i = 0; i < saRoot->portCount; i ++ ) { /* get the pointer to the port */ pPort = &(saRoot->ports[i]); /* Initialize port */ saLlinkInitialize(&(pPort->linkNode)); pPort->portContext.osData = agNULL; pPort->portContext.sdkData = pPort; pPort->portId = 0; pPort->portIdx = (bit8) i; pPort->status = PORT_NORMAL; for ( j = 0; j < saRoot->phyCount; j ++ ) { pPort->phyMap[j] = agFALSE; } saLlistInitialize(&(pPort->listSASATADevices)); /* Add the port to the free port link list */ saLlistAdd(&(saRoot->freePorts), &(pPort->linkNode)); } /* Setup valid port link list */ saLlistInitialize(&(saRoot->validPorts)); /* Init sysIntsActive - default is interrupt enable */ saRoot->sysIntsActive = agFALSE; /* setup timer tick granunarity */ saRoot->usecsPerTick = usecsPerTick; /* setup smallest timer increment for stall */ saRoot->minStallusecs = swConfig->stallUsec; SA_DBG1(("saInitialize: WAIT_INCREMENT %d\n" ,WAIT_INCREMENT )); if (0 == WAIT_INCREMENT) { saRoot->minStallusecs = WAIT_INCREMENT_DEFAULT; } /* initialize LL timer tick */ saRoot->timeTick = 0; /* initialize device (de)registration callback fns */ saRoot->DeviceRegistrationCB = agNULL; saRoot->DeviceDeregistrationCB = agNULL; /* Initialize the PortMap for port context */ for ( i = 0; i < saRoot->portCount; i ++ ) { pPortMap = &(saRoot->PortMap[i]); pPortMap->PortContext = agNULL; pPortMap->PortID = PORT_MARK_OFF; pPortMap->PortStatus = PORT_NORMAL; saRoot->autoDeregDeviceflag[i] = 0; } /* Initialize the DeviceMap for device handle */ for ( i = 0; i < MAX_IO_DEVICE_ENTRIES; i ++ ) { pDeviceMap = &(saRoot->DeviceMap[i]); pDeviceMap->DeviceHandle = agNULL; pDeviceMap->DeviceIdFromFW = i; } /* Initialize the IOMap for IOrequest */ for ( i = 0; i < MAX_ACTIVE_IO_REQUESTS; i ++ ) { pIOMap = &(saRoot->IOMap[i]); pIOMap->IORequest = agNULL; pIOMap->Tag = MARK_OFF; } /* setup mpi configuration */ if (!swConfig->param3) { /* default configuration */ siConfiguration(agRoot, &saRoot->mpiConfig, hwConfig, swConfig); } else { /* get from TD layer and save it */ agsaQueueConfig_t *dCFG = &saRoot->QueueConfig; agsaQueueConfig_t *sCFG = (agsaQueueConfig_t *)swConfig->param3; if (dCFG != sCFG) { *dCFG = *sCFG; if ((hwConfig->hwInterruptCoalescingTimer) || (hwConfig->hwInterruptCoalescingControl)) { for ( i = 0; i < sCFG->numOutboundQueues; i ++ ) { /* disable FW assisted coalescing */ sCFG->outboundQueues[i].interruptDelay = 0; sCFG->outboundQueues[i].interruptCount = 0; } if(smIS_SPC(agRoot)) { if (hwConfig->hwInterruptCoalescingTimer == 0) { hwConfig->hwInterruptCoalescingTimer = 1; SA_DBG1(("saInitialize:InterruptCoalescingTimer should not be zero. Force to 1\n")); } } } ret = siConfiguration(agRoot, &saRoot->mpiConfig, hwConfig, swConfig); if (AGSA_RC_FAILURE == ret) { SA_DBG1(("saInitialize failure queue number=%d\n", saRoot->QueueConfig.numInboundQueues)); agRoot->sdkData = agNULL; smTraceFuncExit(hpDBG_VERY_LOUD, 'r', "m1"); return ret; } } } saRoot->swConfig.param3 = &saRoot->QueueConfig; mpiMemoryAllocated.count = memoryAllocated->count - MPI_MEM_INDEX; for ( i = 0; i < mpiMemoryAllocated.count; i ++ ) { mpiMemoryAllocated.region[i].virtPtr = memoryAllocated->agMemory[MPI_IBQ_OBQ_INDEX + i].virtPtr; mpiMemoryAllocated.region[i].appHandle = memoryAllocated->agMemory[MPI_IBQ_OBQ_INDEX + i].osHandle; mpiMemoryAllocated.region[i].physAddrUpper = memoryAllocated->agMemory[MPI_IBQ_OBQ_INDEX + i].phyAddrUpper; mpiMemoryAllocated.region[i].physAddrLower = memoryAllocated->agMemory[MPI_IBQ_OBQ_INDEX + i].phyAddrLower; mpiMemoryAllocated.region[i].totalLength = memoryAllocated->agMemory[MPI_IBQ_OBQ_INDEX + i].totalLength; mpiMemoryAllocated.region[i].numElements = memoryAllocated->agMemory[MPI_IBQ_OBQ_INDEX + i].numElements; mpiMemoryAllocated.region[i].elementSize = memoryAllocated->agMemory[MPI_IBQ_OBQ_INDEX + i].singleElementLength; mpiMemoryAllocated.region[i].alignment = memoryAllocated->agMemory[MPI_IBQ_OBQ_INDEX + i].alignment; mpiMemoryAllocated.region[i].type = memoryAllocated->agMemory[MPI_IBQ_OBQ_INDEX + i].type; SA_DBG2(("saInitialize: memoryAllocated->agMemory[%d] VirtPtr=%p PhysicalLo=%x Count=%x Total=%x type %x\n", (MPI_IBQ_OBQ_INDEX + i), memoryAllocated->agMemory[MPI_IBQ_OBQ_INDEX + i].virtPtr, memoryAllocated->agMemory[MPI_IBQ_OBQ_INDEX + i].phyAddrLower, memoryAllocated->agMemory[MPI_IBQ_OBQ_INDEX + i].numElements, memoryAllocated->agMemory[MPI_IBQ_OBQ_INDEX + i].totalLength, memoryAllocated->agMemory[MPI_IBQ_OBQ_INDEX + i].type)); /* set to zeros */ SA_DBG1(("saInitialize: Zero memory region %d virt %p allocated %d\n", i,mpiMemoryAllocated.region[i].virtPtr, mpiMemoryAllocated.region[i].totalLength)); si_memset(mpiMemoryAllocated.region[i].virtPtr , 0,mpiMemoryAllocated.region[i].totalLength); } if ((!swConfig->max_MSI_InterruptVectors) && (!swConfig->max_MSIX_InterruptVectors) && (!swConfig->legacyInt_X)) { /* polling mode */ SA_DBG1(("saInitialize: configured as polling mode\n")); } else { SA_DBG1(("saInitialize: swConfig->max_MSI_InterruptVectors %d\n",swConfig->max_MSI_InterruptVectors)); SA_DBG1(("saInitialize: swConfig->max_MSIX_InterruptVectors %d\n",swConfig->max_MSIX_InterruptVectors)); if ((swConfig->legacyInt_X > 1) || (swConfig->max_MSI_InterruptVectors > 32) || (swConfig->max_MSIX_InterruptVectors > 64)) { /* error */ agRoot->sdkData = agNULL; SA_DBG1(("saInitialize:AGSA_RC_FAILURE InterruptVectors A\n")); smTraceFuncExit(hpDBG_VERY_LOUD, 's', "m1"); return AGSA_RC_FAILURE; } if ((swConfig->legacyInt_X) && (swConfig->max_MSI_InterruptVectors)) { /* error */ agRoot->sdkData = agNULL; SA_DBG1(("saInitialize:AGSA_RC_FAILURE InterruptVectors B\n")); smTraceFuncExit(hpDBG_VERY_LOUD, 't', "m1"); return AGSA_RC_FAILURE; } else if ((swConfig->legacyInt_X) && (swConfig->max_MSIX_InterruptVectors)) { /* error */ agRoot->sdkData = agNULL; SA_DBG1(("saInitialize:AGSA_RC_FAILURE InterruptVectors C\n")); smTraceFuncExit(hpDBG_VERY_LOUD, 'u', "m1"); return AGSA_RC_FAILURE; } else if ((swConfig->max_MSI_InterruptVectors) && (swConfig->max_MSIX_InterruptVectors)) { /* error */ agRoot->sdkData = agNULL; SA_DBG1(("saInitialize:AGSA_RC_FAILURE InterruptVectors D\n")); smTraceFuncExit(hpDBG_VERY_LOUD, 'v', "m1"); return AGSA_RC_FAILURE; } } /* This section sets common interrupt for Legacy(IRQ) and MSI and MSIX types */ if(smIS_SPC(agRoot)) { SA_DBG1(("saInitialize: SPC interrupts\n" )); if (swConfig->legacyInt_X) { saRoot->OurInterrupt = siOurLegacyInterrupt; /* Called in ISR*/ saRoot->DisableInterrupts = siDisableLegacyInterrupts; /* Called in ISR*/ saRoot->ReEnableInterrupts = siReenableLegacyInterrupts;/* Called in Delayed Int handler*/ } else if (swConfig->max_MSIX_InterruptVectors) { saRoot->OurInterrupt = siOurMSIXInterrupt; saRoot->DisableInterrupts = siDisableMSIXInterrupts; saRoot->ReEnableInterrupts = siReenableMSIXInterrupts; } else if (swConfig->max_MSI_InterruptVectors) { saRoot->OurInterrupt = siOurMSIInterrupt; saRoot->DisableInterrupts = siDisableMSIInterrupts; saRoot->ReEnableInterrupts = siReenableMSIInterrupts; } else { /* polling mode */ saRoot->OurInterrupt = siOurLegacyInterrupt; /* Called in ISR*/ saRoot->DisableInterrupts = siDisableLegacyInterrupts; /* Called in ISR*/ saRoot->ReEnableInterrupts = siReenableLegacyInterrupts;/* Called in Delayed Int handler*/ } } else { SA_DBG1(("saInitialize: SPC V interrupts\n" )); if (swConfig->legacyInt_X ) { SA_DBG1(("saInitialize: SPC V legacyInt_X\n" )); saRoot->OurInterrupt = siOurLegacy_V_Interrupt; /* Called in ISR*/ saRoot->DisableInterrupts = siDisableLegacy_V_Interrupts; /* Called in ISR*/ saRoot->ReEnableInterrupts = siReenableLegacy_V_Interrupts;/* Called in Delayed Int handler*/ } else if (swConfig->max_MSIX_InterruptVectors) { SA_DBG1(("saInitialize: SPC V max_MSIX_InterruptVectors %X\n", swConfig->max_MSIX_InterruptVectors)); saRoot->OurInterrupt = siOurMSIX_V_Interrupt; /* */ saRoot->DisableInterrupts = siDisableMSIX_V_Interrupts; saRoot->ReEnableInterrupts = siReenableMSIX_V_Interrupts; } else if (swConfig->max_MSI_InterruptVectors) { SA_DBG1(("saInitialize: SPC V max_MSI_InterruptVectors\n" )); saRoot->OurInterrupt = siOurMSIX_V_Interrupt; /* */ saRoot->DisableInterrupts = siDisableMSIX_V_Interrupts; saRoot->ReEnableInterrupts = siReenableMSIX_V_Interrupts; } else { /* polling mode */ SA_DBG1(("saInitialize: SPC V polling mode\n" )); saRoot->OurInterrupt = siOurLegacy_V_Interrupt; /* Called in ISR*/ saRoot->DisableInterrupts = siDisableLegacy_V_Interrupts; /* Called in ISR*/ saRoot->ReEnableInterrupts = siReenableLegacy_V_Interrupts;/* Called in Delayed Int handler*/ } SA_DBG1(("saInitialize: SPC V\n" )); } saRoot->Use64bit = (saRoot->QueueConfig.numOutboundQueues > 32 ) ? 1 : 0; if( smIS64bInt(agRoot)) { SA_DBG1(("saInitialize: Use 64 bits for interrupts %d %d\n" ,saRoot->Use64bit, saRoot->QueueConfig.numOutboundQueues )); } else { SA_DBG1(("saInitialize: Use 32 bits for interrupts %d %d\n",saRoot->Use64bit , saRoot->QueueConfig.numOutboundQueues )); } #ifdef SA_LL_IBQ_PROTECT SA_DBG1(("saInitialize: Inbound locking defined since LL_IOREQ_IBQ0_LOCK %d\n",LL_IOREQ_IBQ0_LOCK)); #endif /* SA_LL_IBQ_PROTECT */ /* Disable interrupt */ saRoot->DisableInterrupts(agRoot, 0); SA_DBG1(("saInitialize: DisableInterrupts sysIntsActive %X\n" ,saRoot->sysIntsActive)); #ifdef SA_FW_TEST_BUNCH_STARTS saRoot->BunchStarts_Enable = FALSE; saRoot->BunchStarts_Threshold = 5; saRoot->BunchStarts_Pending = 0; saRoot->BunchStarts_TimeoutTicks = 10; // N x 100 ms #endif /* SA_FW_TEST_BUNCH_STARTS */ /* clear the interrupt vector bitmap */ for ( i = 0; i < MAX_NUM_VECTOR; i ++ ) { saRoot->interruptVecIndexBitMap[i] = 0; saRoot->interruptVecIndexBitMap1[i] = 0; } #if defined(SALLSDK_DEBUG) smTrace(hpDBG_VERY_LOUD,"2Y",0); /* TP:2Y SCRATCH_PAD */ SA_DBG1(("saInitialize: SCRATCH_PAD0 value = 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_SCRATCH_PAD_0))); SA_DBG1(("saInitialize: SCRATCH_PAD1 value = 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_SCRATCH_PAD_1))); SA_DBG1(("saInitialize: SCRATCH_PAD2 value = 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_SCRATCH_PAD_2))); SA_DBG1(("saInitialize: SCRATCH_PAD3 value = 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_SCRATCH_PAD_3))); #endif /* SALLSDK_DEBUG */ if(smIS_SPCV(agRoot)) { bit32 ScratchPad1 =0; bit32 ScratchPad3 =0; ScratchPad1 = ossaHwRegRead(agRoot,V_Scratchpad_1_Register); ScratchPad3 = ossaHwRegRead(agRoot,V_Scratchpad_3_Register); if((ScratchPad1 & SCRATCH_PAD1_V_RAAE_MASK) == SCRATCH_PAD1_V_RAAE_MASK) { if(((ScratchPad3 & SCRATCH_PAD3_V_ENC_MASK ) == SCRATCH_PAD3_V_ENC_DIS_ERR ) || ((ScratchPad3 & SCRATCH_PAD3_V_ENC_MASK ) == SCRATCH_PAD3_V_ENC_ENA_ERR ) ) { SA_DBG1(("saInitialize:Warning Encryption Issue SCRATCH_PAD3 value = 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_SCRATCH_PAD_3))); } } } if( smIS_SPC(agRoot)) { #ifdef SA_ENABLE_HDA_FUNCTIONS TryWithHDA_ON: Double_Reset_HDA = TRUE; if (swConfig->hostDirectAccessSupport) { if (AGSA_RC_FAILURE == siHDAMode(agRoot, swConfig->hostDirectAccessMode, (agsaFwImg_t *)swConfig->param4)) { SA_DBG1(("saInitialize:AGSA_RC_FAILURE siHDAMode\n")); agRoot->sdkData = agNULL; smTraceFuncExit(hpDBG_VERY_LOUD, 'w', "m1"); return AGSA_RC_FAILURE; } else { SA_DBG1(("saInitialize:1 Going to HDA mode HDA 0x%X \n",ossaHwRegReadExt(agRoot, PCIBAR3, HDA_RSP_OFFSET1MB+HDA_CMD_CODE_OFFSET))); if(Double_Reset_HDA == agFALSE) { siSpcSoftReset(agRoot, SPC_HDASOFT_RESET_SIGNATURE); SA_DBG1(("saInitialize: Double_Reset_HDA HDA 0x%X \n",ossaHwRegReadExt(agRoot, PCIBAR3, HDA_RSP_OFFSET1MB+HDA_CMD_CODE_OFFSET))); Double_Reset_HDA = TRUE; goto TryWithHDA_ON; } } } else { /* check FW is running */ if (BOOTTLOADERHDA_IDLE == (ossaHwRegReadExt(agRoot, PCIBAR3, HDA_RSP_OFFSET1MB+HDA_CMD_CODE_OFFSET) & HDA_STATUS_BITS)) { /* HDA mode */ SA_DBG1(("saInitialize: No HDA mode enable and FW is not running.\n")); if(Tried_NO_HDA != agTRUE ) { Tried_NO_HDA = TRUE; swConfig->hostDirectAccessSupport = 1; swConfig->hostDirectAccessMode = 1; siSpcSoftReset(agRoot, SPC_HDASOFT_RESET_SIGNATURE); SA_DBG1(("saInitialize: 2 Going to HDA mode HDA %X \n",ossaHwRegReadExt(agRoot, PCIBAR3, HDA_RSP_OFFSET1MB+HDA_CMD_CODE_OFFSET))); goto TryWithHDA_ON; } else { SA_DBG1(("saInitialize: could not start HDA mode HDA %X \n",ossaHwRegReadExt(agRoot, PCIBAR3, HDA_RSP_OFFSET1MB+HDA_CMD_CODE_OFFSET))); smTraceFuncExit(hpDBG_VERY_LOUD, 'x', "m1"); return AGSA_RC_FAILURE; } smTraceFuncExit(hpDBG_VERY_LOUD, 'y', "m1"); return AGSA_RC_FAILURE; } } #else /* SA_ENABLE_HDA_FUNCTIONS */ /* check FW is running */ if (BOOTTLOADERHDA_IDLE == (ossaHwRegReadExt(agRoot, PCIBAR3, HDA_RSP_OFFSET1MB+HDA_CMD_CODE_OFFSET) & HDA_STATUS_BITS) ) { /* HDA mode */ SA_DBG1(("saInitialize: No HDA mode enable and FW is not running.\n")); smTraceFuncExit(hpDBG_VERY_LOUD, 'z', "m1"); return AGSA_RC_FAILURE; } #endif /* SA_ENABLE_HDA_FUNCTIONS */ } else { SA_DBG1(("saInitialize: SPCv swConfig->hostDirectAccessMode %d swConfig->hostDirectAccessSupport %d\n",swConfig->hostDirectAccessMode,swConfig->hostDirectAccessSupport)); if (swConfig->hostDirectAccessSupport) { bit32 hda_status; bit32 soft_reset_status = AGSA_RC_SUCCESS; SA_DBG1(("saInitialize: SPCv load HDA\n")); hda_status = (ossaHwRegReadExt(agRoot, PCIBAR0, SPC_V_HDA_RESPONSE_OFFSET+28)); SA_DBG1(("saInitialize: hda_status 0x%x\n",hda_status)); siScratchDump(agRoot); if( swConfig->hostDirectAccessMode == 0) { soft_reset_status = siSoftReset(agRoot, SPC_HDASOFT_RESET_SIGNATURE); if(soft_reset_status != AGSA_RC_SUCCESS) { agRoot->sdkData = agNULL; SA_DBG1(("saInitialize:AGSA_RC_FAILURE soft_reset_status\n")); smTraceFuncExit(hpDBG_VERY_LOUD, 'A', "m1"); return AGSA_RC_FAILURE; } } if((hda_status & SPC_V_HDAR_RSPCODE_MASK) != SPC_V_HDAR_IDLE) { SA_DBG1(("saInitialize: hda_status not SPC_V_HDAR_IDLE 0x%08x\n", hda_status)); soft_reset_status = siSoftReset(agRoot, SPC_HDASOFT_RESET_SIGNATURE); hda_status = (ossaHwRegReadExt(agRoot, PCIBAR0, SPC_V_HDA_RESPONSE_OFFSET+28)); if((hda_status & SPC_V_HDAR_RSPCODE_MASK) != SPC_V_HDAR_IDLE) { SA_DBG1(("saInitialize: 2 reset hda_status not SPC_V_HDAR_IDLE 0x%08x\n", hda_status)); } } if(soft_reset_status != AGSA_RC_SUCCESS) { agRoot->sdkData = agNULL; SA_DBG1(("saInitialize:AGSA_RC_FAILURE soft_reset_status A\n")); smTraceFuncExit(hpDBG_VERY_LOUD, 'B', "m1"); return AGSA_RC_FAILURE; } #ifdef SA_ENABLE_HDA_FUNCTIONS if (AGSA_RC_FAILURE == siHDAMode_V(agRoot, swConfig->hostDirectAccessMode, (agsaFwImg_t *)swConfig->param4)) { SA_DBG1(("saInitialize:AGSA_RC_FAILURE siHDAMode_V\n")); siChipResetV(agRoot, SPC_HDASOFT_RESET_SIGNATURE); agRoot->sdkData = agNULL; smTraceFuncExit(hpDBG_VERY_LOUD, 'C', "m1"); return AGSA_RC_FAILURE; } #endif /* SA_ENABLE_HDA_FUNCTIONS */ } else { SA_DBG1(("saInitialize: SPCv normal\n")); } } /* copy the table to the LL layer */ si_memcpy(&saRoot->mpiConfig.phyAnalogConfig, &hwConfig->phyAnalogConfig, sizeof(agsaPhyAnalogSetupTable_t)); #ifdef SALL_API_TEST /* Initialize the LL IO counter */ si_memset(&saRoot->LLCounters, 0, sizeof(agsaIOCountInfo_t)); #endif si_memset(&saRoot->IoErrorCount, 0, sizeof(agsaIOErrorEventStats_t)); si_memset(&saRoot->IoEventCount, 0, sizeof(agsaIOErrorEventStats_t)); if(smIS_SPC(agRoot)) { if( smIS_spc8081(agRoot)) { if (AGSA_RC_FAILURE == siBar4Shift(agRoot, MBIC_GSM_SM_BASE)) { SA_DBG1(("saInitialize: siBar4Shift FAILED ******************************************\n")); } } siSpcSoftReset(agRoot, SPC_SOFT_RESET_SIGNATURE); } if(smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: saRoot->ChipId == VEN_DEV_SPCV\n")); siChipResetV(agRoot, SPC_SOFT_RESET_SIGNATURE); } /* MPI Initialization */ ret = mpiInitialize(agRoot, &mpiMemoryAllocated, &saRoot->mpiConfig); SA_DBG1(("saInitialize: MaxOutstandingIO 0x%x swConfig->maxActiveIOs 0x%x\n", saRoot->ControllerInfo.maxPendingIO,saRoot->swConfig.maxActiveIOs )); #ifdef SA_ENABLE_HDA_FUNCTIONS if( ret == AGSA_RC_FAILURE && Tried_NO_HDA == agFALSE && smIS_SPC(agRoot)) { /* FW not flashed */ Tried_NO_HDA=agTRUE; swConfig->hostDirectAccessSupport = 1; swConfig->hostDirectAccessMode = 1; siSoftReset(agRoot, SPC_SOFT_RESET_SIGNATURE); SA_DBG1(("saInitialize: 3 Going to HDA mode HDA %X \n",ossaHwRegReadExt(agRoot, PCIBAR3, HDA_RSP_OFFSET1MB+HDA_CMD_CODE_OFFSET))); goto TryWithHDA_ON; } #endif /* SA_ENABLE_HDA_FUNCTIONS */ if( ret == AGSA_RC_FAILURE) { SA_DBG1(("saInitialize: AGSA_RC_FAILURE mpiInitialize\n")); SA_DBG1(("saInitialize: SCRATCH_PAD0 value = 0x%x\n", ossaHwRegRead(agRoot, V_Scratchpad_0_Register))); SA_DBG1(("saInitialize: SCRATCH_PAD1 value = 0x%x\n", ossaHwRegRead(agRoot, V_Scratchpad_1_Register))); SA_DBG1(("saInitialize: SCRATCH_PAD2 value = 0x%x\n", ossaHwRegRead(agRoot, V_Scratchpad_2_Register))); SA_DBG1(("saInitialize: SCRATCH_PAD3 value = 0x%x\n", ossaHwRegRead(agRoot, V_Scratchpad_3_Register))); if(saRoot->swConfig.fatalErrorInterruptEnable) { ossaDisableInterrupts(agRoot,saRoot->swConfig.fatalErrorInterruptVector ); } agRoot->sdkData = agNULL; smTraceFuncExit(hpDBG_VERY_LOUD, 'D', "m1"); return ret; } /* setup hardware interrupt coalescing control and timer registers */ if(smIS_SPCV(agRoot)) { SA_DBG1(("saInitialize: SPC_V Not set hwInterruptCoalescingTimer\n" )); SA_DBG1(("saInitialize: SPC_V Not set hwInterruptCoalescingControl\n" )); } else { ossaHwRegWriteExt(agRoot, PCIBAR1, SPC_ICTIMER,hwConfig->hwInterruptCoalescingTimer ); ossaHwRegWriteExt(agRoot, PCIBAR1, SPC_ICCONTROL, hwConfig->hwInterruptCoalescingControl); } SA_DBG1(("saInitialize: swConfig->fatalErrorInterruptEnable %X\n",swConfig->fatalErrorInterruptEnable)); SA_DBG1(("saInitialize: saRoot->swConfig.fatalErrorInterruptVector %X\n",saRoot->swConfig.fatalErrorInterruptVector)); SA_DBG1(("saInitialize: swConfig->max_MSI_InterruptVectors %X\n",swConfig->max_MSI_InterruptVectors)); SA_DBG1(("saInitialize: swConfig->max_MSIX_InterruptVectors %X\n",swConfig->max_MSIX_InterruptVectors)); SA_DBG1(("saInitialize: swConfig->legacyInt_X %X\n",swConfig->legacyInt_X)); SA_DBG1(("saInitialize: swConfig->hostDirectAccessSupport %X\n",swConfig->hostDirectAccessSupport)); SA_DBG1(("saInitialize: swConfig->hostDirectAccessMode %X\n",swConfig->hostDirectAccessMode)); #ifdef SA_CONFIG_MDFD_REGISTRY SA_DBG1(("saInitialize: swConfig->disableMDF %X\n",swConfig->disableMDF)); #endif /*SA_CONFIG_MDFD_REGISTRY*/ /*SA_DBG1(("saInitialize: swConfig->enableDIF %X\n",swConfig->enableDIF));*/ /*SA_DBG1(("saInitialize: swConfig->enableEncryption %X\n",swConfig->enableEncryption));*/ /* log message if failure */ if (AGSA_RC_FAILURE == ret) { SA_DBG1(("saInitialize:AGSA_RC_FAILURE mpiInitialize\n")); /* Assign chip status */ saRoot->chipStatus = CHIP_FATAL_ERROR; } else { /* Assign chip status */ saRoot->chipStatus = CHIP_NORMAL; #ifdef SA_FW_TIMER_READS_STATUS siTimerAdd(agRoot,SA_FW_TIMER_READS_STATUS_INTERVAL, siReadControllerStatus,0,agNULL ); #endif /* SA_FW_TIMER_READS_STATUS */ } if( ret == AGSA_RC_SUCCESS || ret == AGSA_RC_VERSION_UNTESTED) { if(gPollForMissingInt) { mpiOCQueue_t *circularQ; SA_DBG1(("saInitialize: saRoot->sysIntsActive %X\n",saRoot->sysIntsActive)); circularQ = &saRoot->outboundQueue[0]; OSSA_READ_LE_32(circularQ->agRoot, &circularQ->producerIdx, circularQ->piPointer, 0); SA_DBG1(("saInitialize: PI 0x%03x CI 0x%03x\n",circularQ->producerIdx, circularQ->consumerIdx)); } } /* If fatal error interrupt enable we need checking it during the interrupt */ SA_DBG1(("saInitialize: swConfig.fatalErrorInterruptEnable %d\n",saRoot->swConfig.fatalErrorInterruptEnable)); SA_DBG1(("saInitialize: swConfig.fatalErrorInterruptVector %d\n",saRoot->swConfig.fatalErrorInterruptVector)); SA_DBG1(("saInitialize: swConfig->max_MSIX_InterruptVectors %X\n",swConfig->max_MSIX_InterruptVectors)); if(saRoot->swConfig.fatalErrorInterruptEnable) { SA_DBG1(("saInitialize: Doorbell_Set %08X U %08X\n", ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Set_Register), ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Set_RegisterU))); SA_DBG1(("saInitialize: Doorbell_Mask %08X U %08X\n", ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_Register ), ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_RegisterU ))); ossaReenableInterrupts(agRoot,saRoot->swConfig.fatalErrorInterruptVector ); SA_DBG1(("saInitialize: Doorbell_Set %08X U %08X\n", ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Set_Register), ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Set_RegisterU))); SA_DBG1(("saInitialize: Doorbell_Mask %08X U %08X\n", ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_Register ), ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_RegisterU ))); } SA_DBG1(("saInitialize: siDumpActiveIORequests\n")); siDumpActiveIORequests(agRoot, saRoot->swConfig.maxActiveIOs); smTraceFuncExit(hpDBG_VERY_LOUD, 'E', "m1"); /* return */ return ret; } #ifdef SA_FW_TIMER_READS_STATUS bit32 siReadControllerStatus( agsaRoot_t *agRoot, bit32 Event, void * pParm ) { bit32 to_ret =0; agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); mpiReadGSTable(agRoot, &saRoot->mpiGSTable); if(smIS_SPCV_2_IOP(agRoot)) { if(saRoot->Iop1Tcnt_last == saRoot->mpiGSTable.Iop1Tcnt ) SA_DBG2(("siReadControllerStatus: Iop1 %d STUCK\n", saRoot->mpiGSTable.Iop1Tcnt)); } if( saRoot->MsguTcnt_last == saRoot->mpiGSTable.MsguTcnt || saRoot->IopTcnt_last == saRoot->mpiGSTable.IopTcnt ) { SA_DBG1(("siReadControllerStatus: Msgu %d Iop %d\n",saRoot->mpiGSTable.MsguTcnt, saRoot->mpiGSTable.IopTcnt)); saFatalInterruptHandler(agRoot, saRoot->swConfig.fatalErrorInterruptVector ); } SA_DBG2(("siReadControllerStatus: Msgu %d Iop %d\n",saRoot->mpiGSTable.MsguTcnt, saRoot->mpiGSTable.IopTcnt)); saRoot->MsguTcnt_last = saRoot->mpiGSTable.MsguTcnt; saRoot->IopTcnt_last = saRoot->mpiGSTable.IopTcnt; saRoot->Iop1Tcnt_last = saRoot->mpiGSTable.Iop1Tcnt; if(gPollForMissingInt) { mpiOCQueue_t *circularQ; SA_DBG4(("siReadControllerStatus: saRoot->sysIntsActive %X\n",saRoot->sysIntsActive)); circularQ = &saRoot->outboundQueue[0]; OSSA_READ_LE_32(circularQ->agRoot, &circularQ->producerIdx, circularQ->piPointer, 0); if(circularQ->producerIdx != circularQ->consumerIdx) { SA_DBG1(("siReadControllerStatus: saRoot->sysIntsActive %X\n",saRoot->sysIntsActive)); SA_DBG1(("siReadControllerStatus: PI 0x%03x CI 0x%03x\n",circularQ->producerIdx, circularQ->consumerIdx)); SA_DBG1(("siReadControllerStatus:IN MSGU_READ_ODMR %08X\n",siHalRegReadExt(agRoot, GEN_MSGU_ODMR, V_Outbound_Doorbell_Mask_Set_Register ))); SA_DBG1(("siReadControllerStatus:MSGU_READ_ODR %08X\n",siHalRegReadExt(agRoot, GEN_MSGU_ODR, V_Outbound_Doorbell_Set_Register))); ossaHwRegWriteExt(agRoot, PCIBAR0,V_Outbound_Doorbell_Clear_Register, 0xFFFFFFFF ); } } siTimerAdd(agRoot,SA_FW_TIMER_READS_STATUS_INTERVAL, siReadControllerStatus,Event,pParm ); return(to_ret); } #endif /* SA_FW_TIMER_READS_STATUS */ /******************************************************************************/ /*! \brief Routine to do SPC configuration with default or specified values * * Set up configuration table in LL Layer * * \param agRoot handles for this instance of SAS/SATA hardware * \param mpiConfig MPI Configuration * \param swConfig Pointer to the software configuration * * \return -void- */ /*******************************************************************************/ GLOBAL bit32 siConfiguration( agsaRoot_t *agRoot, mpiConfig_t *mpiConfig, agsaHwConfig_t *hwConfig, agsaSwConfig_t *swConfig ) { agsaQueueConfig_t *queueConfig; bit32 intOption, enable64 = 0; bit8 i; /* sanity check */ SA_ASSERT( (agNULL != agRoot), ""); smTraceFuncEnter(hpDBG_VERY_LOUD,"m2"); si_memset(mpiConfig, 0, sizeof(mpiConfig_t)); SA_DBG1(("siConfiguration: si_memset mpiConfig\n")); #if defined(SALLSDK_DEBUG) sidump_swConfig(swConfig); #endif mpiConfig->mainConfig.custset = swConfig->FWConfig; SA_DBG1(("siConfiguration:custset %8X %8X\n",mpiConfig->mainConfig.custset,swConfig->FWConfig)); if (swConfig->param3 == agNULL) { SA_DBG1(("siConfiguration: swConfig->param3 == agNULL\n")); /* initialize the mpiConfig */ /* We configure the Host main part of configuration table */ mpiConfig->mainConfig.iQNPPD_HPPD_GEvent = 0; mpiConfig->mainConfig.outboundHWEventPID0_3 = 0; mpiConfig->mainConfig.outboundHWEventPID4_7 = 0; mpiConfig->mainConfig.outboundNCQEventPID0_3 = 0; mpiConfig->mainConfig.outboundNCQEventPID4_7 = 0; mpiConfig->mainConfig.outboundTargetITNexusEventPID0_3 = 0; mpiConfig->mainConfig.outboundTargetITNexusEventPID4_7 = 0; mpiConfig->mainConfig.outboundTargetSSPEventPID0_3 = 0; mpiConfig->mainConfig.outboundTargetSSPEventPID4_7 = 0; mpiConfig->mainConfig.ioAbortDelay = 0; mpiConfig->mainConfig.upperEventLogAddress = 0; mpiConfig->mainConfig.lowerEventLogAddress = 0; mpiConfig->mainConfig.eventLogSize = MPI_LOGSIZE; mpiConfig->mainConfig.eventLogOption = 0; mpiConfig->mainConfig.upperIOPeventLogAddress = 0; mpiConfig->mainConfig.lowerIOPeventLogAddress = 0; mpiConfig->mainConfig.IOPeventLogSize = MPI_LOGSIZE; mpiConfig->mainConfig.IOPeventLogOption = 0; mpiConfig->mainConfig.FatalErrorInterrupt = 0; /* save the default value */ mpiConfig->numInboundQueues = AGSA_MAX_INBOUND_Q; mpiConfig->numOutboundQueues = AGSA_MAX_OUTBOUND_Q; mpiConfig->maxNumInboundQueues = AGSA_MAX_INBOUND_Q; mpiConfig->maxNumOutboundQueues = AGSA_MAX_OUTBOUND_Q; /* configure inbound queues */ for ( i = 0; i < AGSA_MAX_INBOUND_Q; i ++ ) { mpiConfig->inboundQueues[i].numElements = INBOUND_DEPTH_SIZE; mpiConfig->inboundQueues[i].elementSize = IOMB_SIZE64; mpiConfig->inboundQueues[i].priority = MPI_QUEUE_NORMAL; } /* configure outbound queues */ for ( i = 0; i < AGSA_MAX_OUTBOUND_Q; i ++ ) { mpiConfig->outboundQueues[i].numElements = OUTBOUND_DEPTH_SIZE; mpiConfig->outboundQueues[i].elementSize = IOMB_SIZE64; mpiConfig->outboundQueues[i].interruptVector = 0; mpiConfig->outboundQueues[i].interruptDelay = 0; mpiConfig->outboundQueues[i].interruptThreshold = 0; /* always enable OQ interrupt */ mpiConfig->outboundQueues[i].interruptEnable = 1; } } else { /* Parm3 is not null */ queueConfig = (agsaQueueConfig_t *)swConfig->param3; #if defined(SALLSDK_DEBUG) sidump_Q_config( queueConfig ); #endif SA_DBG1(("siConfiguration: swConfig->param3 == %p\n",queueConfig)); if ((queueConfig->numInboundQueues > AGSA_MAX_INBOUND_Q) || (queueConfig->numOutboundQueues > AGSA_MAX_OUTBOUND_Q)) { smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "m2"); SA_DBG1(("siConfiguration:AGSA_RC_FAILURE MAX_Q\n")); return AGSA_RC_FAILURE; } if ((queueConfig->numInboundQueues == 0 || queueConfig->numOutboundQueues == 0 )) { smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "m2"); SA_DBG1(("siConfiguration:AGSA_RC_FAILURE NO_Q\n")); return AGSA_RC_FAILURE; } mpiConfig->mainConfig.eventLogSize = swConfig->sizefEventLog1 * KBYTES; mpiConfig->mainConfig.eventLogOption = swConfig->eventLog1Option; mpiConfig->mainConfig.IOPeventLogSize = swConfig->sizefEventLog2 * KBYTES; mpiConfig->mainConfig.IOPeventLogOption = swConfig->eventLog2Option; if ((queueConfig->numInboundQueues > IQ_NUM_32) || (queueConfig->numOutboundQueues > OQ_NUM_32)) { enable64 = 1; } if (agNULL == hwConfig) { intOption = 0; } else { #if defined(SALLSDK_DEBUG) sidump_hwConfig(hwConfig); #endif if(smIS_SPCV(agRoot)) { intOption = 0; } else { intOption = hwConfig->intReassertionOption & INT_OPTION; } } /* Enable SGPIO */ swConfig->sgpioSupportEnable = 1; /* set bit for normal priority or high priority path */ /* set fatal error interrupt enable and vector */ /* set Interrupt Reassertion enable and 64 IQ/OQ enable */ mpiConfig->mainConfig.FatalErrorInterrupt = (swConfig->fatalErrorInterruptEnable) /* bit 0*/ | (hwConfig == agNULL ? 0: (hwConfig->hwOption & HW_CFG_PICI_EFFECTIVE_ADDRESS ? (0x1 << SHIFT1): 0))| (swConfig->sgpioSupportEnable ? (0x1 << SHIFT2): 0) | /* compile option SA_ENABLE_POISION_TLP */(SA_PTNFE_POISION_TLP << SHIFT3) | #ifdef SA_CONFIG_MDFD_REGISTRY (swConfig->disableMDF ? (0x1 << SHIFT4): 0) | #else /* compile option SA_DISABLE_MDFD */ (SA_MDFD_MULTI_DATA_FETCH << SHIFT4) | #endif /*SA_CONFIG_MDFD_REGISTRY*/ /* compile option SA_DISABLE_OB_COAL */(SA_OUTBOUND_COALESCE << SHIFT5) | /* compile option SA_ENABLE_ARBTE */(SA_ARBTE << SHIFT6) | ((swConfig->fatalErrorInterruptVector & FATAL_ERROR_INT_BITS) << SHIFT8) | (enable64 << SHIFT16) | (intOption << SHIFT17); SA_DBG1(("siConfiguration: swConfig->fatalErrorInterruptEnable %X\n",swConfig->fatalErrorInterruptEnable)); SA_DBG1(("siConfiguration: swConfig->fatalErrorInterruptVector %X\n",swConfig->fatalErrorInterruptVector)); /* initialize the mpiConfig */ /* We configure the Host main part of configuration table */ mpiConfig->mainConfig.outboundTargetITNexusEventPID0_3 = 0; mpiConfig->mainConfig.outboundTargetITNexusEventPID4_7 = 0; mpiConfig->mainConfig.outboundTargetSSPEventPID0_3 = 0; mpiConfig->mainConfig.outboundTargetSSPEventPID4_7 = 0; mpiConfig->mainConfig.ioAbortDelay = 0; mpiConfig->mainConfig.PortRecoveryTimerPortResetTimer = swConfig->PortRecoveryResetTimer; /* get parameter from queueConfig */ mpiConfig->mainConfig.iQNPPD_HPPD_GEvent = queueConfig->iqNormalPriorityProcessingDepth | (queueConfig->iqHighPriorityProcessingDepth << SHIFT8) | (queueConfig->generalEventQueue << SHIFT16) | (queueConfig->tgtDeviceRemovedEventQueue << SHIFT24); mpiConfig->mainConfig.outboundHWEventPID0_3 = queueConfig->sasHwEventQueue[0] | (queueConfig->sasHwEventQueue[1] << SHIFT8) | (queueConfig->sasHwEventQueue[2] << SHIFT16) | (queueConfig->sasHwEventQueue[3] << SHIFT24); mpiConfig->mainConfig.outboundHWEventPID4_7 = queueConfig->sasHwEventQueue[4] | (queueConfig->sasHwEventQueue[5] << SHIFT8) | (queueConfig->sasHwEventQueue[6] << SHIFT16) | (queueConfig->sasHwEventQueue[7] << SHIFT24); mpiConfig->mainConfig.outboundNCQEventPID0_3 = queueConfig->sataNCQErrorEventQueue[0] | (queueConfig->sataNCQErrorEventQueue[1] << SHIFT8) | (queueConfig->sataNCQErrorEventQueue[2] << SHIFT16) | (queueConfig->sataNCQErrorEventQueue[3] << SHIFT24); mpiConfig->mainConfig.outboundNCQEventPID4_7 = queueConfig->sataNCQErrorEventQueue[4] | (queueConfig->sataNCQErrorEventQueue[5] << SHIFT8) | (queueConfig->sataNCQErrorEventQueue[6] << SHIFT16) | (queueConfig->sataNCQErrorEventQueue[7] << SHIFT24); /* save it */ mpiConfig->numInboundQueues = queueConfig->numInboundQueues; mpiConfig->numOutboundQueues = queueConfig->numOutboundQueues; mpiConfig->queueOption = queueConfig->queueOption; SA_DBG2(("siConfiguration: numInboundQueues=%d numOutboundQueues=%d\n", queueConfig->numInboundQueues, queueConfig->numOutboundQueues)); /* configure inbound queues */ /* We configure the size of queue based on swConfig */ for( i = 0; i < queueConfig->numInboundQueues; i ++ ) { mpiConfig->inboundQueues[i].numElements = (bit16)queueConfig->inboundQueues[i].elementCount; mpiConfig->inboundQueues[i].elementSize = (bit16)queueConfig->inboundQueues[i].elementSize; mpiConfig->inboundQueues[i].priority = queueConfig->inboundQueues[i].priority; SA_DBG2(("siConfiguration: IBQ%d:elementCount=%d elementSize=%d priority=%d Total Size 0x%X\n", i, queueConfig->inboundQueues[i].elementCount, queueConfig->inboundQueues[i].elementSize, queueConfig->inboundQueues[i].priority, queueConfig->inboundQueues[i].elementCount * queueConfig->inboundQueues[i].elementSize )); } /* configura outbound queues */ /* We configure the size of queue based on swConfig */ for( i = 0; i < queueConfig->numOutboundQueues; i ++ ) { mpiConfig->outboundQueues[i].numElements = (bit16)queueConfig->outboundQueues[i].elementCount; mpiConfig->outboundQueues[i].elementSize = (bit16)queueConfig->outboundQueues[i].elementSize; mpiConfig->outboundQueues[i].interruptVector = (bit8)queueConfig->outboundQueues[i].interruptVectorIndex; mpiConfig->outboundQueues[i].interruptDelay = (bit16)queueConfig->outboundQueues[i].interruptDelay; mpiConfig->outboundQueues[i].interruptThreshold = (bit8)queueConfig->outboundQueues[i].interruptCount; mpiConfig->outboundQueues[i].interruptEnable = (bit32)queueConfig->outboundQueues[i].interruptEnable; SA_DBG2(("siConfiguration: OBQ%d:elementCount=%d elementSize=%d interruptCount=%d interruptEnable=%d\n", i, queueConfig->outboundQueues[i].elementCount, queueConfig->outboundQueues[i].elementSize, queueConfig->outboundQueues[i].interruptCount, queueConfig->outboundQueues[i].interruptEnable)); } } SA_DBG1(("siConfiguration:mpiConfig->mainConfig.FatalErrorInterrupt 0x%X\n",mpiConfig->mainConfig.FatalErrorInterrupt)); SA_DBG1(("siConfiguration:swConfig->fatalErrorInterruptVector 0x%X\n",swConfig->fatalErrorInterruptVector)); SA_DBG1(("siConfiguration:enable64 0x%X\n",enable64)); SA_DBG1(("siConfiguration:PortRecoveryResetTimer 0x%X\n",swConfig->PortRecoveryResetTimer)); smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "m2"); /* return */ return AGSA_RC_SUCCESS; } #ifdef FW_EVT_LOG_TST void saLogDump(agsaRoot_t *agRoot, U32 *eventLogSize, U32 **eventLogAddress_) { agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); //mpiConfig_t *mpiConfig = &saRoot->mpiConfig; mpiHostLLConfigDescriptor_t *mpiConfig = &saRoot->mainConfigTable; *eventLogAddress_ = (U32*)eventLogAddress; *eventLogSize = (U32)mpiConfig->eventLogSize; } #endif /*******************************************************************************/ /** \fn mpiInitialize(agsaRoot *agRoot, mpiMemReq_t* memoryAllocated, mpiConfig_t* config) * \brief Initializes the MPI Message Unit * \param agRoot Pointer to a data structure containing LL layer context handles * \param memoryAllocated Data structure that holds the different chunks of memory that are allocated * \param config MPI configuration * * This function is called to initialize SPC_HOST_MPI internal data structures and the SPC hardware. * This function is competed synch->ronously (there is no callback) * * Return: * AGSA_RC_SUCCESS if initialization succeeded. * AGSA_RC_FAILURE if initialization failed. */ /*******************************************************************************/ GLOBAL bit32 mpiInitialize(agsaRoot_t *agRoot, mpiMemReq_t* memoryAllocated, mpiConfig_t* config) { static spc_configMainDescriptor_t mainCfg; /* main part of MPI configuration */ static spc_inboundQueueDescriptor_t inQueueCfg; /* Inbound queue HW configuration structure */ static spc_outboundQueueDescriptor_t outQueueCfg; /* Outbound queue HW configuration structure */ bit16 qIdx, i, indexoffset; /* Queue index */ bit16 mIdx = 0; /* Memory region index */ bit32 MSGUCfgTblDWIdx, GSTLenMPIS; bit32 MSGUCfgTblBase, ret = AGSA_RC_SUCCESS; bit32 value, togglevalue; bit32 saveOffset; bit32 inboundoffset, outboundoffset; bit8 pcibar; bit16 maxinbound = AGSA_MAX_INBOUND_Q; bit16 maxoutbound = AGSA_MAX_OUTBOUND_Q; bit32 OB_CIPCIBar; bit32 IB_PIPCIBar; bit32 max_wait_time; bit32 max_wait_count; bit32 memOffset; agsaLLRoot_t *saRoot; mpiICQueue_t *circularIQ = agNULL; mpiOCQueue_t *circularOQ; bit32 mpiUnInitFailed = 0; bit32 mpiStartToggleFailed = 0; #if defined(SALLSDK_DEBUG) bit8 phycount = AGSA_MAX_VALID_PHYS; #endif /* SALLSDK_DEBUG */ SA_DBG1(("mpiInitialize: Entering\n")); SA_ASSERT(NULL != agRoot, "agRoot argument cannot be null"); SA_ASSERT(NULL != memoryAllocated, "memoryAllocated argument cannot be null"); SA_ASSERT(NULL != config, "config argument cannot be null"); SA_ASSERT(0 == (sizeof(spc_inboundQueueDescriptor_t) % 4), "spc_inboundQueueDescriptor_t type size has to be divisible by 4"); saRoot = (agsaLLRoot_t *)(agRoot->sdkData); si_memset(&mainCfg,0,sizeof(spc_configMainDescriptor_t)); si_memset(&inQueueCfg,0,sizeof(spc_inboundQueueDescriptor_t)); si_memset(&outQueueCfg,0,sizeof(spc_outboundQueueDescriptor_t)); SA_ASSERT((agNULL !=saRoot ), ""); if(saRoot == agNULL) { SA_DBG1(("mpiInitialize: saRoot == agNULL\n")); return(AGSA_RC_FAILURE); } smTraceFuncEnter(hpDBG_VERY_LOUD,"m3"); /*Shift BAR 4 for SPC HAILEAH*/ if(smIS_SPC(agRoot)) { if( smIS_HIL(agRoot)) { if (AGSA_RC_FAILURE == siBar4Shift(agRoot, MBIC_GSM_SM_BASE)) { SA_DBG1(("mpiInitialize: siBar4Shift FAILED ******************************************\n")); return AGSA_RC_FAILURE; } } } /* Wait for the SPC Configuration Table to be ready */ ret = mpiWaitForConfigTable(agRoot, &mainCfg); if (AGSA_RC_FAILURE == ret) { /* return error if MPI Configuration Table not ready */ SA_DBG1(("mpiInitialize: mpiWaitForConfigTable FAILED ******************************************\n")); smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "m3"); return ret; } /* read scratch pad0 to get PCI BAR and offset of configuration table */ MSGUCfgTblBase = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0); /* get PCI BAR */ MSGUCfgTblBase = (MSGUCfgTblBase & SCRATCH_PAD0_BAR_MASK) >> SHIFT26; /* get pci Bar index */ pcibar = (bit8)mpiGetPCIBarIndex(agRoot, MSGUCfgTblBase); SA_DBG1(("mpiInitialize: MSGUCfgTblBase = 0x%x\n", MSGUCfgTblBase)); #if defined(SALLSDK_DEBUG) /* get Phy count from configuration table */ phycount = (bit8)((mainCfg.ContrlCapFlag & PHY_COUNT_BITS) >> SHIFT19); SA_DBG1(("mpiInitialize: Number of PHYs = 0x%x\n", phycount)); smTrace(hpDBG_VERY_LOUD,"70",phycount); /* TP:70 phycount */ #endif /* SALLSDK_DEBUG */ /* get High Priority IQ support flag */ if (mainCfg.ContrlCapFlag & HP_SUPPORT_BIT) { SA_DBG1(("mpiInitialize: High Priority IQ support from SPC\n")); } /* get Interrupt Coalescing Support flag */ if (mainCfg.ContrlCapFlag & INT_COL_BIT) { SA_DBG1(("mpiInitialize: Interrupt Coalescing support from SPC\n")); } /* get configured the number of inbound/outbound queues */ if (memoryAllocated->count == TOTAL_MPI_MEM_CHUNKS) { config->maxNumInboundQueues = AGSA_MAX_INBOUND_Q; config->maxNumOutboundQueues = AGSA_MAX_OUTBOUND_Q; } else { config->maxNumInboundQueues = config->numInboundQueues; config->maxNumOutboundQueues = config->numOutboundQueues; maxinbound = config->numInboundQueues; maxoutbound = config->numOutboundQueues; } SA_DBG1(("mpiInitialize: Number of IQ %d\n", maxinbound)); SA_DBG1(("mpiInitialize: Number of OQ %d\n", maxoutbound)); /* get inbound queue offset */ inboundoffset = mainCfg.inboundQueueOffset; /* get outbound queue offset */ outboundoffset = mainCfg.outboundQueueOffset; if(smIS_SPCV(agRoot)) { SA_DBG2(("mpiInitialize: Offset of IQ %d\n", (inboundoffset & 0xFF000000) >> 24)); SA_DBG2(("mpiInitialize: Offset of OQ %d\n", (outboundoffset & 0xFF000000) >> 24)); inboundoffset &= 0x00FFFFFF; outboundoffset &= 0x00FFFFFF; } /* get offset of the configuration table */ MSGUCfgTblDWIdx = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0); MSGUCfgTblDWIdx = MSGUCfgTblDWIdx & SCRATCH_PAD0_OFFSET_MASK; saveOffset = MSGUCfgTblDWIdx; /* Checks if the configuration memory region size is the same as the mpiConfigMain */ if(memoryAllocated->region[mIdx].totalLength != sizeof(bit8) * config->mainConfig.eventLogSize) { SA_DBG1(("ERROR: The memory region [%d] 0x%X != 0x%X does not have the size of the MSGU event log ******************************************\n", mIdx,memoryAllocated->region[mIdx].totalLength,config->mainConfig.eventLogSize)); smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "m3"); return AGSA_RC_FAILURE; } mainCfg.iQNPPD_HPPD_GEvent = config->mainConfig.iQNPPD_HPPD_GEvent; if(smIS_SPCV(agRoot)) { mainCfg.outboundHWEventPID0_3 = 0; mainCfg.outboundHWEventPID4_7 = 0; mainCfg.outboundNCQEventPID0_3 = 0; mainCfg.outboundNCQEventPID4_7 = 0; mainCfg.outboundTargetITNexusEventPID0_3 = 0; mainCfg.outboundTargetITNexusEventPID4_7 = 0; mainCfg.outboundTargetSSPEventPID0_3 = 0; mainCfg.outboundTargetSSPEventPID4_7 = 0; mainCfg.ioAbortDelay = 0; /* SPCV reserved */ mainCfg.custset = 0; mainCfg.portRecoveryResetTimer = config->mainConfig.PortRecoveryTimerPortResetTimer; SA_DBG1(("mpiInitialize:custset V %8X\n",mainCfg.custset)); SA_DBG1(("mpiInitialize:portRecoveryResetTimer V %8X\n",mainCfg.portRecoveryResetTimer)); mainCfg.interruptReassertionDelay = saRoot->hwConfig.intReassertionOption; SA_DBG1(("mpiInitialize:interruptReassertionDelay V %8X\n", mainCfg.interruptReassertionDelay)); } else { mainCfg.outboundHWEventPID0_3 = config->mainConfig.outboundHWEventPID0_3; mainCfg.outboundHWEventPID4_7 = config->mainConfig.outboundHWEventPID4_7; mainCfg.outboundNCQEventPID0_3 = config->mainConfig.outboundNCQEventPID0_3; mainCfg.outboundNCQEventPID4_7 = config->mainConfig.outboundNCQEventPID4_7; mainCfg.outboundTargetITNexusEventPID0_3 = config->mainConfig.outboundTargetITNexusEventPID0_3; mainCfg.outboundTargetITNexusEventPID4_7 = config->mainConfig.outboundTargetITNexusEventPID4_7; mainCfg.outboundTargetSSPEventPID0_3 = config->mainConfig.outboundTargetSSPEventPID0_3; mainCfg.outboundTargetSSPEventPID4_7 = config->mainConfig.outboundTargetSSPEventPID4_7; mainCfg.ioAbortDelay = config->mainConfig.ioAbortDelay; mainCfg.custset = config->mainConfig.custset; SA_DBG1(("mpiInitialize:custset spc %8X\n",mainCfg.custset)); } #ifdef FW_EVT_LOG_TST eventLogAddress = memoryAllocated->region[mIdx].virtPtr; #endif mainCfg.upperEventLogAddress = memoryAllocated->region[mIdx].physAddrUpper; mainCfg.lowerEventLogAddress = memoryAllocated->region[mIdx].physAddrLower; mainCfg.eventLogSize = config->mainConfig.eventLogSize; mainCfg.eventLogOption = config->mainConfig.eventLogOption; mIdx++; /* Checks if the configuration memory region size is the same as the mpiConfigMain */ if(memoryAllocated->region[mIdx].totalLength != sizeof(bit8) * config->mainConfig.IOPeventLogSize) { SA_DBG1(("ERROR: The memory region does not have the size of the IOP event log\n")); smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "m3"); return AGSA_RC_FAILURE; } mainCfg.upperIOPeventLogAddress = memoryAllocated->region[mIdx].physAddrUpper; mainCfg.lowerIOPeventLogAddress = memoryAllocated->region[mIdx].physAddrLower; mainCfg.IOPeventLogSize = config->mainConfig.IOPeventLogSize; mainCfg.IOPeventLogOption = config->mainConfig.IOPeventLogOption; mainCfg.FatalErrorInterrupt = config->mainConfig.FatalErrorInterrupt; SA_DBG1(("mpiInitialize: iQNPPD_HPPD_GEvent 0x%x\n", mainCfg.iQNPPD_HPPD_GEvent)); if(smIS_SPCV(agRoot)) { } else { SA_DBG3(("mpiInitialize: outboundHWEventPID0_3 0x%x\n", mainCfg.outboundHWEventPID0_3)); SA_DBG3(("mpiInitialize: outboundHWEventPID4_7 0x%x\n", mainCfg.outboundHWEventPID4_7)); SA_DBG3(("mpiInitialize: outboundNCQEventPID0_3 0x%x\n", mainCfg.outboundNCQEventPID0_3)); SA_DBG3(("mpiInitialize: outboundNCQEventPID4_7 0x%x\n", mainCfg.outboundNCQEventPID4_7)); SA_DBG3(("mpiInitialize: outboundTargetITNexusEventPID0_3 0x%x\n", mainCfg.outboundTargetITNexusEventPID0_3)); SA_DBG3(("mpiInitialize: outboundTargetITNexusEventPID4_7 0x%x\n", mainCfg.outboundTargetITNexusEventPID4_7)); SA_DBG3(("mpiInitialize: outboundTargetSSPEventPID0_3 0x%x\n", mainCfg.outboundTargetSSPEventPID0_3)); SA_DBG3(("mpiInitialize: outboundTargetSSPEventPID4_7 0x%x\n", mainCfg.outboundTargetSSPEventPID4_7)); } SA_DBG3(("mpiInitialize: upperEventLogAddress 0x%x\n", mainCfg.upperEventLogAddress)); SA_DBG3(("mpiInitialize: lowerEventLogAddress 0x%x\n", mainCfg.lowerEventLogAddress)); SA_DBG3(("mpiInitialize: eventLogSize 0x%x\n", mainCfg.eventLogSize)); SA_DBG3(("mpiInitialize: eventLogOption 0x%x\n", mainCfg.eventLogOption)); #ifdef FW_EVT_LOG_TST SA_DBG3(("mpiInitialize: eventLogAddress 0x%p\n", eventLogAddress)); #endif SA_DBG3(("mpiInitialize: upperIOPLogAddress 0x%x\n", mainCfg.upperIOPeventLogAddress)); SA_DBG3(("mpiInitialize: lowerIOPLogAddress 0x%x\n", mainCfg.lowerIOPeventLogAddress)); SA_DBG3(("mpiInitialize: IOPeventLogSize 0x%x\n", mainCfg.IOPeventLogSize)); SA_DBG3(("mpiInitialize: IOPeventLogOption 0x%x\n", mainCfg.IOPeventLogOption)); SA_DBG3(("mpiInitialize: FatalErrorInterrupt 0x%x\n", mainCfg.FatalErrorInterrupt)); SA_DBG3(("mpiInitialize: HDAModeFlags 0x%x\n", mainCfg.HDAModeFlags)); SA_DBG3(("mpiInitialize: analogSetupTblOffset 0x%08x\n", mainCfg.analogSetupTblOffset)); saRoot->mainConfigTable.iQNPPD_HPPD_GEvent = mainCfg.iQNPPD_HPPD_GEvent; if(smIS_SPCV(agRoot)) { /* SPCV - reserved fields */ saRoot->mainConfigTable.outboundHWEventPID0_3 = 0; saRoot->mainConfigTable.outboundHWEventPID4_7 = 0; saRoot->mainConfigTable.outboundNCQEventPID0_3 = 0; saRoot->mainConfigTable.outboundNCQEventPID4_7 = 0; saRoot->mainConfigTable.outboundTargetITNexusEventPID0_3 = 0; saRoot->mainConfigTable.outboundTargetITNexusEventPID4_7 = 0; saRoot->mainConfigTable.outboundTargetSSPEventPID0_3 = 0; saRoot->mainConfigTable.outboundTargetSSPEventPID4_7 = 0; saRoot->mainConfigTable.ioAbortDelay = 0; saRoot->mainConfigTable.custset = 0; } else { saRoot->mainConfigTable.outboundHWEventPID0_3 = mainCfg.outboundHWEventPID0_3; saRoot->mainConfigTable.outboundHWEventPID4_7 = mainCfg.outboundHWEventPID4_7; saRoot->mainConfigTable.outboundNCQEventPID0_3 = mainCfg.outboundNCQEventPID0_3; saRoot->mainConfigTable.outboundNCQEventPID4_7 = mainCfg.outboundNCQEventPID4_7; saRoot->mainConfigTable.outboundTargetITNexusEventPID0_3 = mainCfg.outboundTargetITNexusEventPID0_3; saRoot->mainConfigTable.outboundTargetITNexusEventPID4_7 = mainCfg.outboundTargetITNexusEventPID4_7; saRoot->mainConfigTable.outboundTargetSSPEventPID0_3 = mainCfg.outboundTargetSSPEventPID0_3; saRoot->mainConfigTable.outboundTargetSSPEventPID4_7 = mainCfg.outboundTargetSSPEventPID4_7; saRoot->mainConfigTable.ioAbortDelay = mainCfg.ioAbortDelay; saRoot->mainConfigTable.custset = mainCfg.custset; } saRoot->mainConfigTable.upperEventLogAddress = mainCfg.upperEventLogAddress; saRoot->mainConfigTable.lowerEventLogAddress = mainCfg.lowerEventLogAddress; saRoot->mainConfigTable.eventLogSize = mainCfg.eventLogSize; saRoot->mainConfigTable.eventLogOption = mainCfg.eventLogOption; saRoot->mainConfigTable.upperIOPeventLogAddress = mainCfg.upperIOPeventLogAddress; saRoot->mainConfigTable.lowerIOPeventLogAddress = mainCfg.lowerIOPeventLogAddress; saRoot->mainConfigTable.IOPeventLogSize = mainCfg.IOPeventLogSize; saRoot->mainConfigTable.IOPeventLogOption = mainCfg.IOPeventLogOption; saRoot->mainConfigTable.FatalErrorInterrupt = mainCfg.FatalErrorInterrupt; if(smIS_SPCV(agRoot)) { ;/* SPCV - reserved fields */ } else { saRoot->mainConfigTable.HDAModeFlags = mainCfg.HDAModeFlags; } saRoot->mainConfigTable.analogSetupTblOffset = mainCfg.analogSetupTblOffset; smTrace(hpDBG_VERY_LOUD,"71",mIdx); /* TP:71 71 mIdx */ ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_IQNPPD_HPPD_OFFSET), mainCfg.iQNPPD_HPPD_GEvent); SA_DBG3(("mpiInitialize: Offset 0x%08x mainCfg.iQNPPD_HPPD_GEvent 0x%x\n", (bit32)(MSGUCfgTblDWIdx + MAIN_IQNPPD_HPPD_OFFSET), mainCfg.iQNPPD_HPPD_GEvent)); if(smIS_SPC6V(agRoot)) { if(smIsCfgVREV_B(agRoot)) { ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_IO_ABORT_DELAY), MAIN_IO_ABORT_DELAY_END_TO_END_CRC_DISABLE); SA_DBG1(("mpiInitialize:SPCV - MAIN_IO_ABORT_DELAY_END_TO_END_CRC_DISABLE\n" )); } if(smIsCfgVREV_C(agRoot)) { SA_DBG1(("mpiInitialize:SPCV - END_TO_END_CRC On\n" )); } SA_DBG3(("mpiInitialize:SPCV - rest reserved field \n" )); ;/* SPCV - reserved field */ } else if(smIS_SPC(agRoot)) { ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_OB_HW_EVENT_PID03_OFFSET), mainCfg.outboundHWEventPID0_3); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_OB_HW_EVENT_PID47_OFFSET), mainCfg.outboundHWEventPID4_7); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_OB_NCQ_EVENT_PID03_OFFSET), mainCfg.outboundNCQEventPID0_3); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_OB_NCQ_EVENT_PID47_OFFSET), mainCfg.outboundNCQEventPID4_7); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_TITNX_EVENT_PID03_OFFSET), mainCfg.outboundTargetITNexusEventPID0_3); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_TITNX_EVENT_PID47_OFFSET), mainCfg.outboundTargetITNexusEventPID4_7); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_OB_SSP_EVENT_PID03_OFFSET), mainCfg.outboundTargetSSPEventPID0_3); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_OB_SSP_EVENT_PID47_OFFSET), mainCfg.outboundTargetSSPEventPID4_7); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_CUSTOMER_SETTING), mainCfg.custset); }else { if(smIsCfgVREV_A(agRoot)) { ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_IO_ABORT_DELAY), MAIN_IO_ABORT_DELAY_END_TO_END_CRC_DISABLE); /* */ SA_DBG1(("mpiInitialize:SPCV12G - offset MAIN_IO_ABORT_DELAY 0x%x value MAIN_IO_ABORT_DELAY_END_TO_END_CRC_DISABLE 0x%x\n",MAIN_IO_ABORT_DELAY ,MAIN_IO_ABORT_DELAY_END_TO_END_CRC_DISABLE)); SA_DBG1(("mpiInitialize:SPCV12G - END_TO_END_CRC OFF for rev A %d\n",smIsCfgVREV_A(agRoot) )); } else if(smIsCfgVREV_B(agRoot)) { SA_DBG1(("mpiInitialize:SPCV12G - END_TO_END_CRC ON rev B %d ****************************\n",smIsCfgVREV_B(agRoot) )); /*ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_IO_ABORT_DELAY), MAIN_IO_ABORT_DELAY_END_TO_END_CRC_DISABLE); */ } else if(smIsCfgVREV_C(agRoot)) { SA_DBG1(("mpiInitialize:SPCV12G - END_TO_END_CRC on rev C %d\n",smIsCfgVREV_C(agRoot) )); } else { ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_IO_ABORT_DELAY), MAIN_IO_ABORT_DELAY_END_TO_END_CRC_DISABLE); SA_DBG1(("mpiInitialize:SPCV12G - END_TO_END_CRC Off unknown rev 0x%x\n", ossaHwRegReadConfig32((agRoot), 8 ))); } } ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_EVENT_LOG_ADDR_HI), mainCfg.upperEventLogAddress); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_EVENT_LOG_ADDR_LO), mainCfg.lowerEventLogAddress); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_EVENT_LOG_BUFF_SIZE), mainCfg.eventLogSize); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_EVENT_LOG_OPTION), mainCfg.eventLogOption); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_IOP_EVENT_LOG_ADDR_HI), mainCfg.upperIOPeventLogAddress); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_IOP_EVENT_LOG_ADDR_LO), mainCfg.lowerIOPeventLogAddress); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_IOP_EVENT_LOG_BUFF_SIZE), mainCfg.IOPeventLogSize); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_IOP_EVENT_LOG_OPTION), mainCfg.IOPeventLogOption); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_FATAL_ERROR_INTERRUPT), mainCfg.FatalErrorInterrupt); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_PRECTD_PRESETD), mainCfg.portRecoveryResetTimer); SA_DBG3(("mpiInitialize: Offset 0x%08x upperEventLogAddress 0x%x\n",(bit32)(MSGUCfgTblDWIdx + MAIN_EVENT_LOG_ADDR_HI), mainCfg.upperEventLogAddress )); SA_DBG3(("mpiInitialize: Offset 0x%08x lowerEventLogAddress 0x%x\n",(bit32)(MSGUCfgTblDWIdx + MAIN_EVENT_LOG_ADDR_LO), mainCfg.lowerEventLogAddress )); SA_DBG3(("mpiInitialize: Offset 0x%08x eventLogSize 0x%x\n",(bit32)(MSGUCfgTblDWIdx + MAIN_EVENT_LOG_BUFF_SIZE), mainCfg.eventLogSize )); SA_DBG3(("mpiInitialize: Offset 0x%08x eventLogOption 0x%x\n",(bit32)(MSGUCfgTblDWIdx + MAIN_EVENT_LOG_OPTION), mainCfg.eventLogOption )); SA_DBG3(("mpiInitialize: Offset 0x%08x upperIOPeventLogAddress 0x%x\n",(bit32)(MSGUCfgTblDWIdx + MAIN_IOP_EVENT_LOG_ADDR_HI), mainCfg.upperIOPeventLogAddress )); SA_DBG3(("mpiInitialize: Offset 0x%08x lowerIOPeventLogAddress 0x%x\n",(bit32)(MSGUCfgTblDWIdx + MAIN_IOP_EVENT_LOG_ADDR_LO), mainCfg.lowerIOPeventLogAddress )); SA_DBG3(("mpiInitialize: Offset 0x%08x IOPeventLogSize 0x%x\n",(bit32)(MSGUCfgTblDWIdx + MAIN_IOP_EVENT_LOG_BUFF_SIZE), mainCfg.IOPeventLogSize )); SA_DBG3(("mpiInitialize: Offset 0x%08x IOPeventLogOption 0x%x\n",(bit32)(MSGUCfgTblDWIdx + MAIN_IOP_EVENT_LOG_OPTION), mainCfg.IOPeventLogOption )); SA_DBG3(("mpiInitialize: Offset 0x%08x FatalErrorInterrupt 0x%x\n",(bit32)(MSGUCfgTblDWIdx + MAIN_FATAL_ERROR_INTERRUPT), mainCfg.FatalErrorInterrupt )); SA_DBG3(("mpiInitialize: Offset 0x%08x PortRecoveryResetTimer 0x%x\n",(bit32)(MSGUCfgTblDWIdx + MAIN_PRECTD_PRESETD), mainCfg.portRecoveryResetTimer )); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_IRAD_RESERVED), mainCfg.interruptReassertionDelay); SA_DBG3(("mpiInitialize: Offset 0x%08x InterruptReassertionDelay 0x%x\n",(bit32)(MSGUCfgTblDWIdx + MAIN_IRAD_RESERVED), mainCfg.interruptReassertionDelay )); mIdx++; /* skip the ci and pi memory region */ mIdx++; mIdx++; smTrace(hpDBG_VERY_LOUD,"72",mIdx); /* TP:72 mIdx */ smTrace(hpDBG_VERY_LOUD,"Bc",maxinbound); /* TP:Bc maxinbound */ smTrace(hpDBG_VERY_LOUD,"Bd",pcibar); /* TP:Bd pcibar */ /* index offset */ indexoffset = 0; memOffset = 0; /* Memory regions for the inbound queues */ for(qIdx = 0; qIdx < maxinbound; qIdx++) { /* point back to the begin then plus offset to next queue */ smTrace(hpDBG_VERY_LOUD,"Bd",pcibar); /* TP:Bd pcibar */ MSGUCfgTblDWIdx = saveOffset; MSGUCfgTblDWIdx += inboundoffset; MSGUCfgTblDWIdx += (sizeof(spc_inboundQueueDescriptor_t) * qIdx); SA_DBG1(("mpiInitialize: A saveOffset 0x%x MSGUCfgTblDWIdx 0x%x\n",saveOffset ,MSGUCfgTblDWIdx)); /* if the MPI configuration says that this queue is disabled ... */ if(0 == config->inboundQueues[qIdx].numElements) { /* ... Clears the configuration table for this queue */ inQueueCfg.elementPriSizeCount= 0; inQueueCfg.upperBaseAddress = 0; inQueueCfg.lowerBaseAddress = 0; inQueueCfg.ciUpperBaseAddress = 0; inQueueCfg.ciLowerBaseAddress = 0; /* skip inQueueCfg.PIPCIBar (PM8000 write access) */ /* skip inQueueCfg.PIOffset (PM8000 write access) */ /* Update the inbound configuration table in SPC GSM */ mpiUpdateIBQueueCfgTable(agRoot, &inQueueCfg, MSGUCfgTblDWIdx, pcibar); } /* If the queue is enabled, then ... */ else { bit32 memSize = config->inboundQueues[qIdx].numElements * config->inboundQueues[qIdx].elementSize; bit32 remainder = memSize & 127; /* Calculate the size of this queue padded to 128 bytes */ if (remainder > 0) { memSize += (128 - remainder); } /* ... first checks that the memory region has the right size */ if( (memoryAllocated->region[mIdx].totalLength - memOffset < memSize) || (NULL == memoryAllocated->region[mIdx].virtPtr) || (0 == memoryAllocated->region[mIdx].totalLength)) { SA_DBG1(("mpiInitialize: ERROR The memory region does not have the right size for this inbound queue")); smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "m3"); return AGSA_RC_FAILURE; } else { /* Then, using the MPI configuration argument, initializes the corresponding element on the saRoot */ saRoot->inboundQueue[qIdx].numElements = config->inboundQueues[qIdx].numElements; saRoot->inboundQueue[qIdx].elementSize = config->inboundQueues[qIdx].elementSize; saRoot->inboundQueue[qIdx].priority = config->inboundQueues[qIdx].priority; si_memcpy(&saRoot->inboundQueue[qIdx].memoryRegion, &memoryAllocated->region[mIdx], sizeof(mpiMem_t)); saRoot->inboundQueue[qIdx].memoryRegion.virtPtr = (bit8 *)saRoot->inboundQueue[qIdx].memoryRegion.virtPtr + memOffset; saRoot->inboundQueue[qIdx].memoryRegion.physAddrLower += memOffset; saRoot->inboundQueue[qIdx].memoryRegion.elementSize = memSize; saRoot->inboundQueue[qIdx].memoryRegion.totalLength = memSize; saRoot->inboundQueue[qIdx].memoryRegion.numElements = 1; /* Initialize the local copy of PIs, CIs */ SA_DBG1(("mpiInitialize: queue %d PI CI zero\n",qIdx)); saRoot->inboundQueue[qIdx].producerIdx = 0; saRoot->inboundQueue[qIdx].consumerIdx = 0; saRoot->inboundQueue[qIdx].agRoot = agRoot; /* MPI memory region for inbound CIs are 2 */ saRoot->inboundQueue[qIdx].ciPointer = (((bit8 *)(memoryAllocated->region[MPI_CI_INDEX].virtPtr)) + qIdx * 4); /* ... and in the local structure we will use to copy to the HW configuration table */ /* CI base address */ inQueueCfg.elementPriSizeCount= config->inboundQueues[qIdx].numElements | (config->inboundQueues[qIdx].elementSize << SHIFT16) | (config->inboundQueues[qIdx].priority << SHIFT30); inQueueCfg.upperBaseAddress = saRoot->inboundQueue[qIdx].memoryRegion.physAddrUpper; inQueueCfg.lowerBaseAddress = saRoot->inboundQueue[qIdx].memoryRegion.physAddrLower; inQueueCfg.ciUpperBaseAddress = memoryAllocated->region[MPI_CI_INDEX].physAddrUpper; inQueueCfg.ciLowerBaseAddress = memoryAllocated->region[MPI_CI_INDEX].physAddrLower + qIdx * 4; /* write the configured data of inbound queue to SPC GSM */ mpiUpdateIBQueueCfgTable(agRoot, &inQueueCfg, MSGUCfgTblDWIdx, pcibar); /* get inbound PI PCI Bar and Offset */ /* get the PI PCI Bar offset and convert it to logical BAR */ IB_PIPCIBar = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + IB_PIPCI_BAR)); saRoot->inboundQueue[qIdx].PIPCIBar = mpiGetPCIBarIndex(agRoot, IB_PIPCIBar); saRoot->inboundQueue[qIdx].PIPCIOffset = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + IB_PIPCI_BAR_OFFSET)); saRoot->inboundQueue[qIdx].qNumber = qIdx; memOffset += memSize; if ((0 == ((qIdx + 1) % MAX_QUEUE_EACH_MEM)) || (qIdx == (maxinbound - 1))) { mIdx++; indexoffset += MAX_QUEUE_EACH_MEM; memOffset = 0; } } /* else for memeory ok */ } /* queue enable */ } /* loop for inbound queue */ smTrace(hpDBG_VERY_LOUD,"73",0); /* TP:73 outbound queues */ /* index offset */ indexoffset = 0; memOffset = 0; /* Let's process the memory regions for the outbound queues */ for(qIdx = 0; qIdx < maxoutbound; qIdx++) { /* point back to the begin then plus offset to next queue */ MSGUCfgTblDWIdx = saveOffset; MSGUCfgTblDWIdx += outboundoffset; MSGUCfgTblDWIdx += (sizeof(spc_outboundQueueDescriptor_t) * qIdx); /* if the MPI configuration says that this queue is disabled ... */ if(0 == config->outboundQueues[qIdx].numElements) { /* ... Clears the configuration table for this queue */ outQueueCfg.upperBaseAddress = 0; outQueueCfg.lowerBaseAddress = 0; outQueueCfg.piUpperBaseAddress = 0; outQueueCfg.piLowerBaseAddress = 0; /* skip outQueueCfg.CIPCIBar = 0; read access only */ /* skip outQueueCfg.CIOffset = 0; read access only */ outQueueCfg.elementSizeCount = 0; outQueueCfg.interruptVecCntDelay = 0; /* Updated the configuration table in SPC GSM */ mpiUpdateOBQueueCfgTable(agRoot, &outQueueCfg, MSGUCfgTblDWIdx, pcibar); } /* If the outbound queue is enabled, then ... */ else { bit32 memSize = config->outboundQueues[qIdx].numElements * config->outboundQueues[qIdx].elementSize; bit32 remainder = memSize & 127; /* Calculate the size of this queue padded to 128 bytes */ if (remainder > 0) { memSize += (128 - remainder); } /* ... first checks that the memory region has the right size */ if((memoryAllocated->region[mIdx].totalLength - memOffset < memSize) || (NULL == memoryAllocated->region[mIdx].virtPtr) || (0 == memoryAllocated->region[mIdx].totalLength)) { SA_DBG1(("ERROR: The memory region does not have the right size for this outbound queue")); smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "m3"); return AGSA_RC_FAILURE; } else { /* Then, using the MPI configuration argument, initializes the corresponding element on the MPI context ... */ saRoot->outboundQueue[qIdx].numElements = config->outboundQueues[qIdx].numElements; saRoot->outboundQueue[qIdx].elementSize = config->outboundQueues[qIdx].elementSize; si_memcpy(&saRoot->outboundQueue[qIdx].memoryRegion, &memoryAllocated->region[mIdx], sizeof(mpiMem_t)); saRoot->outboundQueue[qIdx].memoryRegion.virtPtr = (bit8 *)saRoot->outboundQueue[qIdx].memoryRegion.virtPtr + memOffset; saRoot->outboundQueue[qIdx].memoryRegion.physAddrLower += memOffset; saRoot->outboundQueue[qIdx].memoryRegion.elementSize = memSize; saRoot->outboundQueue[qIdx].memoryRegion.totalLength = memSize; saRoot->outboundQueue[qIdx].memoryRegion.numElements = 1; saRoot->outboundQueue[qIdx].producerIdx = 0; saRoot->outboundQueue[qIdx].consumerIdx = 0; saRoot->outboundQueue[qIdx].agRoot = agRoot; /* MPI memory region for outbound PIs are 3 */ saRoot->outboundQueue[qIdx].piPointer = (((bit8 *)(memoryAllocated->region[MPI_CI_INDEX + 1].virtPtr))+ qIdx * 4); /* ... and in the local structure we will use to copy to the HW configuration table */ outQueueCfg.upperBaseAddress = saRoot->outboundQueue[qIdx].memoryRegion.physAddrUpper; outQueueCfg.lowerBaseAddress = saRoot->outboundQueue[qIdx].memoryRegion.physAddrLower; /* PI base address */ outQueueCfg.piUpperBaseAddress = memoryAllocated->region[MPI_CI_INDEX + 1].physAddrUpper; outQueueCfg.piLowerBaseAddress = memoryAllocated->region[MPI_CI_INDEX + 1].physAddrLower + qIdx * 4; outQueueCfg.elementSizeCount = config->outboundQueues[qIdx].numElements | (config->outboundQueues[qIdx].elementSize << SHIFT16); /* enable/disable interrupt - use saSystemInterruptsActive() API */ /* instead of ossaHwRegWrite(agRoot, MSGU_ODMR, 0); */ /* Outbound Doorbell Auto disable */ /* LL does not use ossaHwRegWriteExt(agRoot, PCIBAR1, SPC_ODAR, 0xffffffff); */ if (config->outboundQueues[qIdx].interruptEnable) { /* enable interrupt flag bit30 of outbound table */ outQueueCfg.elementSizeCount |= OB_PROPERTY_INT_ENABLE; } if(smIS_SPCV(agRoot)) { outQueueCfg.interruptVecCntDelay = ((config->outboundQueues[qIdx].interruptVector & INT_VEC_BITS ) << SHIFT24); } else { outQueueCfg.interruptVecCntDelay = (config->outboundQueues[qIdx].interruptDelay & INT_DELAY_BITS) | ((config->outboundQueues[qIdx].interruptThreshold & INT_THR_BITS ) << SHIFT16) | ((config->outboundQueues[qIdx].interruptVector & INT_VEC_BITS ) << SHIFT24); } /* create a VectorIndex Bit Map */ if (qIdx < OQ_NUM_32) { saRoot->interruptVecIndexBitMap[config->outboundQueues[qIdx].interruptVector] |= (1 << qIdx); SA_DBG2(("mpiInitialize:below 32 saRoot->interruptVecIndexBitMap[config->outboundQueues[qIdx].interruptVector] 0x%08x\n",saRoot->interruptVecIndexBitMap[config->outboundQueues[qIdx].interruptVector])); } else { saRoot->interruptVecIndexBitMap1[config->outboundQueues[qIdx].interruptVector] |= (1 << (qIdx - OQ_NUM_32)); SA_DBG2(("mpiInitialize:Above 32 saRoot->interruptVecIndexBitMap1[config->outboundQueues[qIdx].interruptVector] 0x%08x\n",saRoot->interruptVecIndexBitMap1[config->outboundQueues[qIdx].interruptVector])); } /* Update the outbound configuration table */ mpiUpdateOBQueueCfgTable(agRoot, &outQueueCfg, MSGUCfgTblDWIdx, pcibar); /* read the CI PCIBar offset and convert it to logical bar */ OB_CIPCIBar = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + OB_CIPCI_BAR)); saRoot->outboundQueue[qIdx].CIPCIBar = mpiGetPCIBarIndex(agRoot, OB_CIPCIBar); saRoot->outboundQueue[qIdx].CIPCIOffset = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + OB_CIPCI_BAR_OFFSET)); saRoot->outboundQueue[qIdx].DIntTOffset = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + OB_DYNAMIC_COALES_OFFSET)); saRoot->outboundQueue[qIdx].qNumber = qIdx; memOffset += memSize; if ((0 == ((qIdx + 1) % MAX_QUEUE_EACH_MEM)) || (qIdx == (maxoutbound - 1))) { mIdx++; indexoffset += MAX_QUEUE_EACH_MEM; memOffset =0; } } } } /* calculate number of vectors */ saRoot->numInterruptVectors = 0; for (qIdx = 0; qIdx < MAX_NUM_VECTOR; qIdx++) { if ((saRoot->interruptVecIndexBitMap[qIdx]) || (saRoot->interruptVecIndexBitMap1[qIdx])) { (saRoot->numInterruptVectors)++; } } SA_DBG2(("mpiInitialize:(saRoot->numInterruptVectors) 0x%x\n",(saRoot->numInterruptVectors))); if(smIS_SPCV(agRoot)) { /* setup interrupt vector table */ mpiWrIntVecTable(agRoot,config); } if(smIS_SPCV(agRoot)) { mpiWrAnalogSetupTable(agRoot,config); } /* setup phy analog registers */ mpiWriteCALAll(agRoot, &config->phyAnalogConfig); { bit32 pcibar = 0; bit32 TableOffset; pcibar = siGetPciBar(agRoot); TableOffset = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0); TableOffset &= SCRATCH_PAD0_OFFSET_MASK; SA_DBG1(("mpiInitialize: mpiContextTable TableOffset 0x%08X contains 0x%08X\n",TableOffset,ossaHwRegReadExt(agRoot, pcibar, TableOffset ))); SA_ASSERT( (ossaHwRegReadExt(agRoot, pcibar, TableOffset ) == 0x53434D50), "Config table signiture"); SA_DBG1(("mpiInitialize: AGSA_MPI_MAIN_CONFIGURATION_TABLE 0x%08X\n", 0)); SA_DBG1(("mpiInitialize: AGSA_MPI_GENERAL_STATUS_TABLE 0x%08X\n", (ossaHwRegReadExt(agRoot, pcibar, TableOffset+MAIN_GST_OFFSET) & 0xFFFF ))); SA_DBG1(("mpiInitialize: AGSA_MPI_INBOUND_QUEUE_CONFIGURATION_TABLE 0x%08X\n", (ossaHwRegReadExt(agRoot, pcibar, TableOffset+MAIN_IBQ_OFFSET) & 0xFFFF))); SA_DBG1(("mpiInitialize: AGSA_MPI_OUTBOUND_QUEUE_CONFIGURATION_TABLE 0x%08X\n", (ossaHwRegReadExt(agRoot, pcibar, TableOffset+MAIN_OBQ_OFFSET) & 0xFFFF))); SA_DBG1(("mpiInitialize: AGSA_MPI_SAS_PHY_ANALOG_SETUP_TABLE 0x%08X\n", (ossaHwRegReadExt(agRoot, pcibar, TableOffset+MAIN_ANALOG_SETUP_OFFSET) & 0xFFFF ))); SA_DBG1(("mpiInitialize: AGSA_MPI_INTERRUPT_VECTOR_TABLE 0x%08X\n", (ossaHwRegReadExt(agRoot, pcibar, TableOffset+MAIN_INT_VEC_TABLE_OFFSET) & 0xFFFF))); SA_DBG1(("mpiInitialize: AGSA_MPI_PER_SAS_PHY_ATTRIBUTE_TABLE 0x%08X\n", (ossaHwRegReadExt(agRoot, pcibar, TableOffset+MAIN_PHY_ATTRIBUTE_OFFSET) & 0xFFFF))); SA_DBG1(("mpiInitialize: AGSA_MPI_OUTBOUND_QUEUE_FAILOVER_TABLE 0x%08X\n", (ossaHwRegReadExt(agRoot, pcibar, TableOffset+MAIN_MOQFOT_MOQFOES) & 0xFFFF))); } if(agNULL != saRoot->swConfig.mpiContextTable ) { agsaMPIContext_t * context = (agsaMPIContext_t * )saRoot->swConfig.mpiContextTable; bit32 length = saRoot->swConfig.mpiContextTablelen; bit32 pcibar = 0; bit32 TableOffset; pcibar = siGetPciBar(agRoot); TableOffset = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0); TableOffset &= SCRATCH_PAD0_OFFSET_MASK; SA_DBG1(("mpiInitialize: mpiContextTable TableOffset 0x%08X contains 0x%08X\n",TableOffset,ossaHwRegReadExt(agRoot, pcibar, TableOffset ))); SA_ASSERT( (ossaHwRegReadExt(agRoot, pcibar, TableOffset ) == 0x53434D50), "Config table signiture"); if ( (ossaHwRegReadExt(agRoot, pcibar, TableOffset ) != 0x53434D50)) { SA_DBG1(("mpiInitialize: TableOffset 0x%x reads 0x%x expect 0x%x \n",TableOffset,ossaHwRegReadExt(agRoot, pcibar, TableOffset ),0x53434D50)); } if(context ) { SA_DBG1(("mpiInitialize: MPITableType 0x%x context->offset 0x%x context->value 0x%x\n",context->MPITableType,context->offset,context->value)); while( length != 0) { switch(context->MPITableType) { bit32 OffsetInMain; case AGSA_MPI_MAIN_CONFIGURATION_TABLE: SA_DBG1(("mpiInitialize: AGSA_MPI_MAIN_CONFIGURATION_TABLE %d 0x%x + 0x%x = 0x%x\n",context->MPITableType,TableOffset, context->offset, context->value)); OffsetInMain = TableOffset; ossaHwRegWriteExt(agRoot, pcibar, OffsetInMain + (context->offset * 4) , context->value); break; case AGSA_MPI_GENERAL_STATUS_TABLE: SA_DBG1(("mpiInitialize: AGSA_MPI_GENERAL_STATUS_TABLE %d offset 0x%x + 0x%x = 0x%x\n",context->MPITableType ,TableOffset+MAIN_GST_OFFSET, context->offset, context->value )); OffsetInMain = (ossaHwRegReadExt(agRoot, pcibar, TableOffset+MAIN_GST_OFFSET ) & 0xFFFF) + TableOffset; ossaHwRegWriteExt(agRoot, pcibar, OffsetInMain + (context->offset * 4), context->value); break; case AGSA_MPI_INBOUND_QUEUE_CONFIGURATION_TABLE: SA_DBG1(("mpiInitialize: AGSA_MPI_INBOUND_QUEUE_CONFIGURATION_TABLE %d offset 0x%x + 0x%x = 0x%x\n",context->MPITableType,TableOffset+MAIN_IBQ_OFFSET, context->offset, context->value)); OffsetInMain = (ossaHwRegReadExt(agRoot, pcibar, TableOffset+MAIN_IBQ_OFFSET ) & 0xFFFF) + TableOffset; ossaHwRegWriteExt(agRoot, pcibar, OffsetInMain + (context->offset * 4), context->value); break; case AGSA_MPI_OUTBOUND_QUEUE_CONFIGURATION_TABLE: SA_DBG1(("mpiInitialize: AGSA_MPI_OUTBOUND_QUEUE_CONFIGURATION_TABLE %d offset 0x%x + 0x%x = 0x%x\n",context->MPITableType,TableOffset+MAIN_OBQ_OFFSET, context->offset, context->value)); OffsetInMain = (ossaHwRegReadExt(agRoot, pcibar, TableOffset+MAIN_OBQ_OFFSET ) & 0xFFFF) + TableOffset; ossaHwRegWriteExt(agRoot, pcibar, OffsetInMain + (context->offset * 4), context->value); break; case AGSA_MPI_SAS_PHY_ANALOG_SETUP_TABLE: SA_DBG1(("mpiInitialize: AGSA_MPI_SAS_PHY_ANALOG_SETUP_TABLE %d offset 0x%x + 0x%x = 0x%x\n",context->MPITableType,TableOffset+MAIN_ANALOG_SETUP_OFFSET, context->offset, context->value)); OffsetInMain = (ossaHwRegReadExt(agRoot, pcibar, TableOffset+ MAIN_ANALOG_SETUP_OFFSET) & 0xFFFF) + TableOffset; ossaHwRegWriteExt(agRoot, pcibar, OffsetInMain + (context->offset * 4), context->value); break; case AGSA_MPI_INTERRUPT_VECTOR_TABLE: SA_DBG1(("mpiInitialize: AGSA_MPI_INTERRUPT_VECTOR_TABLE %d offset 0x%x + 0x%x = 0x%x\n",context->MPITableType,TableOffset+MAIN_INT_VEC_TABLE_OFFSET, context->offset, context->value)); OffsetInMain = (ossaHwRegReadExt(agRoot, pcibar, TableOffset+ MAIN_INT_VEC_TABLE_OFFSET) & 0xFFFF) + TableOffset; ossaHwRegWriteExt(agRoot, pcibar, OffsetInMain + (context->offset * 4), context->value); break; case AGSA_MPI_PER_SAS_PHY_ATTRIBUTE_TABLE: SA_DBG1(("mpiInitialize: AGSA_MPI_PER_SAS_PHY_ATTRIBUTE_TABLE %d offset 0x%x + 0x%x = 0x%x\n",context->MPITableType,TableOffset+MAIN_PHY_ATTRIBUTE_OFFSET, context->offset, context->value)); OffsetInMain = (ossaHwRegReadExt(agRoot, pcibar, TableOffset+MAIN_PHY_ATTRIBUTE_OFFSET ) & 0xFFFF) + TableOffset; ossaHwRegWriteExt(agRoot, pcibar, OffsetInMain + (context->offset * 4), context->value); break; case AGSA_MPI_OUTBOUND_QUEUE_FAILOVER_TABLE: SA_DBG1(("mpiInitialize: AGSA_MPI_OUTBOUND_QUEUE_FAILOVER_TABLE %d offset 0x%x + 0x%x = 0x%x\n",context->MPITableType,TableOffset+MAIN_MOQFOT_MOQFOES, context->offset, context->value)); OffsetInMain = (ossaHwRegReadExt(agRoot, pcibar, TableOffset+MAIN_MOQFOT_MOQFOES ) & 0xFFFF) + TableOffset; ossaHwRegWriteExt(agRoot, pcibar, OffsetInMain + (context->offset * 4), context->value); break; default: SA_DBG1(("mpiInitialize: error MPITableType unknown %d offset 0x%x value 0x%x\n",context->MPITableType, context->offset, context->value)); break; } if(smIS_SPC12V(agRoot)) { if (saRoot->ControllerInfo.fwInterfaceRev > 0x301 ) { SA_DBG1(("mpiInitialize: MAIN_AWT_MIDRANGE 0x%08X\n", ossaHwRegReadExt(agRoot, pcibar, TableOffset + MAIN_AWT_MIDRANGE) )); } } if(length >= sizeof(agsaMPIContext_t)) { length -= sizeof(agsaMPIContext_t); context++; } else { length = 0; } } } SA_DBG1(("mpiInitialize: context %p saRoot->swConfig.mpiContextTable %p %d\n",context,saRoot->swConfig.mpiContextTable,context == saRoot->swConfig.mpiContextTable ? 1 : 0)); if ( (ossaHwRegReadExt(agRoot, pcibar, TableOffset ) != 0x53434D50)) { SA_DBG1(("mpiInitialize:TableOffset 0x%x reads 0x%x expect 0x%x \n",TableOffset,ossaHwRegReadExt(agRoot, pcibar, TableOffset ),0x53434D50)); } SA_ASSERT( (ossaHwRegReadExt(agRoot, pcibar, TableOffset ) == 0x53434D50), "Config table signiture After"); } /* At this point the Message Unit configuration table is set up. Now we need to ring the doorbell */ togglevalue = 0; smTrace(hpDBG_VERY_LOUD,"74", siHalRegReadExt(agRoot, GEN_MSGU_IBDB_SET, MSGU_IBDB_SET )); /* TP:74 Doorbell */ /* Write bit0=1 to Inbound DoorBell Register to tell the SPC FW the table is updated */ siHalRegWriteExt(agRoot, GEN_MSGU_IBDB_SET, MSGU_IBDB_SET, SPC_MSGU_CFG_TABLE_UPDATE); if(siHalRegReadExt(agRoot, GEN_MSGU_IBDB_SET, MSGU_IBDB_SET ) & SPC_MSGU_CFG_TABLE_UPDATE) { SA_DBG1(("mpiInitialize: SPC_MSGU_CFG_TABLE_UPDATE (0x%X) \n", siHalRegReadExt(agRoot, GEN_MSGU_IBDB_SET, MSGU_IBDB_SET))); } else { SA_DBG1(("mpiInitialize: SPC_MSGU_CFG_TABLE_UPDATE not set (0x%X)\n", siHalRegReadExt(agRoot, GEN_MSGU_IBDB_SET, MSGU_IBDB_SET))); ossaStallThread(agRoot, WAIT_INCREMENT); } smTrace(hpDBG_VERY_LOUD,"A5", siHalRegReadExt(agRoot, GEN_MSGU_IBDB_SET, MSGU_IBDB_SET )); /* TP:A5 Doorbell */ /* // ossaHwRegWrite(agRoot, MSGU_IBDB_SET, SPC_MSGU_CFG_TABLE_UPDATE); MSGU_WRITE_IDR(SPC_MSGU_CFG_TABLE_UPDATE); */ /* wait until Inbound DoorBell Clear Register toggled */ WaitLonger: max_wait_time = WAIT_SECONDS(gWait_2); /* 2 sec */ max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT); do { ossaStallThread(agRoot, WAIT_INCREMENT); value = MSGU_READ_IDR; value &= SPC_MSGU_CFG_TABLE_UPDATE; } while ((value != togglevalue) && (max_wait_count -= WAIT_INCREMENT)); smTrace(hpDBG_VERY_LOUD,"80", max_wait_count); /* TP:80 TP max_wait_count */ if (!max_wait_count && mpiStartToggleFailed < 5 ) { SA_DBG1(("mpiInitialize: mpiStartToggleFailed count %d\n", mpiStartToggleFailed)); mpiStartToggleFailed++; goto WaitLonger; } if (!max_wait_count ) { SA_DBG1(("mpiInitialize: TIMEOUT:IBDB value/toggle = 0x%x 0x%x\n", value, togglevalue)); MSGUCfgTblDWIdx = saveOffset; GSTLenMPIS = ossaHwRegReadExt(agRoot, pcibar, (bit32)MSGUCfgTblDWIdx + (bit32)(mainCfg.GSTOffset + GST_GSTLEN_MPIS_OFFSET)); SA_DBG1(("mpiInitialize: MPI State = 0x%x\n", GSTLenMPIS)); smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "m3"); return AGSA_RC_FAILURE; } smTrace(hpDBG_VERY_LOUD,"81", mpiStartToggleFailed ); /* TP:81 TP */ /* check the MPI-State for initialization */ MSGUCfgTblDWIdx = saveOffset; GSTLenMPIS = ossaHwRegReadExt(agRoot, pcibar, (bit32)MSGUCfgTblDWIdx + (bit32)(mainCfg.GSTOffset + GST_GSTLEN_MPIS_OFFSET)); if ( (GST_MPI_STATE_UNINIT == (GSTLenMPIS & GST_MPI_STATE_MASK)) && ( mpiUnInitFailed < 5 ) ) { SA_DBG1(("mpiInitialize: MPI State = 0x%x mpiUnInitFailed count %d\n", GSTLenMPIS & GST_MPI_STATE_MASK,mpiUnInitFailed)); ossaStallThread(agRoot, (20 * 1000)); mpiUnInitFailed++; goto WaitLonger; } if (GST_MPI_STATE_INIT != (GSTLenMPIS & GST_MPI_STATE_MASK)) { SA_DBG1(("mpiInitialize: Error Not GST_MPI_STATE_INIT MPI State = 0x%x\n", GSTLenMPIS & GST_MPI_STATE_MASK)); smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "m3"); return AGSA_RC_FAILURE; } smTrace(hpDBG_VERY_LOUD,"82", 0); /* TP:82 TP */ /* check MPI Initialization error */ GSTLenMPIS = GSTLenMPIS >> SHIFT16; if (0x0000 != GSTLenMPIS) { SA_DBG1(("mpiInitialize: MPI Error = 0x%x\n", GSTLenMPIS)); smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "m3"); return AGSA_RC_FAILURE; } smTrace(hpDBG_VERY_LOUD,"83", 0); /* TP:83 TP */ /* reread IQ PI offset from SPC if IQ/OQ > 32 */ if ((maxinbound > IQ_NUM_32) || (maxoutbound > OQ_NUM_32)) { for(qIdx = 0; qIdx < maxinbound; qIdx++) { /* point back to the begin then plus offset to next queue */ MSGUCfgTblDWIdx = saveOffset; MSGUCfgTblDWIdx += inboundoffset; MSGUCfgTblDWIdx += (sizeof(spc_inboundQueueDescriptor_t) * qIdx); saRoot->inboundQueue[qIdx].PIPCIOffset = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + IB_PIPCI_BAR_OFFSET)); } } smTrace(hpDBG_VERY_LOUD,"84", 0); /* TP:84 TP */ /* at least one inbound queue and one outbound queue enabled */ if ((0 == config->inboundQueues[0].numElements) || (0 == config->outboundQueues[0].numElements)) { SA_DBG1(("mpiInitialize: Error,IQ0 or OQ0 have to enable\n")); smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "m3"); return AGSA_RC_FAILURE; } smTrace(hpDBG_VERY_LOUD,"85", 0); /* TP:85 TP */ /* clean the inbound queues */ for (i = 0; i < config->numInboundQueues; i ++) { if(0 != config->inboundQueues[i].numElements) { circularIQ = &saRoot->inboundQueue[i]; si_memset(circularIQ->memoryRegion.virtPtr, 0, circularIQ->memoryRegion.totalLength); si_memset(saRoot->inboundQueue[i].ciPointer, 0, sizeof(bit32)); if(smIS_SPCV(agRoot)) { ossaHwRegWriteExt(circularIQ->agRoot, circularIQ->PIPCIBar, circularIQ->PIPCIOffset, 0); SA_DBG1(("mpiInitialize: SPC V writes IQ %2d offset 0x%x\n",i ,circularIQ->PIPCIOffset)); } } } smTrace(hpDBG_VERY_LOUD,"86", 0); /* TP:86 TP */ /* clean the outbound queues */ for (i = 0; i < config->numOutboundQueues; i ++) { if(0 != config->outboundQueues[i].numElements) { circularOQ = &saRoot->outboundQueue[i]; si_memset(circularOQ->memoryRegion.virtPtr, 0, circularOQ->memoryRegion.totalLength); si_memset(saRoot->outboundQueue[i].piPointer, 0, sizeof(bit32)); if(smIS_SPCV(agRoot)) { ossaHwRegWriteExt(circularOQ->agRoot, circularOQ->CIPCIBar, circularOQ->CIPCIOffset, 0); SA_DBG2(("mpiInitialize: SPC V writes OQ %2d offset 0x%x\n",i ,circularOQ->CIPCIOffset)); } } } smTrace(hpDBG_VERY_LOUD,"75",0); /* TP:75 AAP1 IOP */ /* read back AAP1 and IOP event log address and size */ MSGUCfgTblDWIdx = saveOffset; value = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_EVENT_LOG_ADDR_HI)); saRoot->mainConfigTable.upperEventLogAddress = value; SA_DBG1(("mpiInitialize: upperEventLogAddress 0x%x\n", value)); value = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_EVENT_LOG_ADDR_LO)); saRoot->mainConfigTable.lowerEventLogAddress = value; SA_DBG1(("mpiInitialize: lowerEventLogAddress 0x%x\n", value)); value = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_EVENT_LOG_BUFF_SIZE)); saRoot->mainConfigTable.eventLogSize = value; SA_DBG1(("mpiInitialize: eventLogSize 0x%x\n", value)); value = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_EVENT_LOG_OPTION)); saRoot->mainConfigTable.eventLogOption = value; SA_DBG1(("mpiInitialize: eventLogOption 0x%x\n", value)); SA_DBG1(("mpiInitialize: EventLog dd /p %08X`%08X L %x\n",saRoot->mainConfigTable.upperEventLogAddress,saRoot->mainConfigTable.lowerEventLogAddress,saRoot->mainConfigTable.eventLogSize/4 )); value = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_IOP_EVENT_LOG_ADDR_HI)); saRoot->mainConfigTable.upperIOPeventLogAddress = value; SA_DBG1(("mpiInitialize: upperIOPLogAddress 0x%x\n", value)); value = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_IOP_EVENT_LOG_ADDR_LO)); saRoot->mainConfigTable.lowerIOPeventLogAddress = value; SA_DBG1(("mpiInitialize: lowerIOPLogAddress 0x%x\n", value)); SA_DBG1(("mpiInitialize: IOPLog dd /p %08X`%08X L %x\n",saRoot->mainConfigTable.upperIOPeventLogAddress,saRoot->mainConfigTable.lowerIOPeventLogAddress,saRoot->mainConfigTable.IOPeventLogSize/4 )); value = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_IOP_EVENT_LOG_BUFF_SIZE)); saRoot->mainConfigTable.IOPeventLogSize = value; SA_DBG1(("mpiInitialize: IOPeventLogSize 0x%x\n", value)); value = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_IOP_EVENT_LOG_OPTION)); saRoot->mainConfigTable.IOPeventLogOption = value; SA_DBG1(("mpiInitialize: IOPeventLogOption 0x%x\n", value)); value = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_FATAL_ERROR_INTERRUPT)); #ifdef SA_PRINTOUT_IN_WINDBG #ifndef DBG DbgPrint("mpiInitialize: EventLog (%d) dd /p %08X`%08X L %x\n", saRoot->mainConfigTable.eventLogOption, saRoot->mainConfigTable.upperEventLogAddress, saRoot->mainConfigTable.lowerEventLogAddress, saRoot->mainConfigTable.eventLogSize/4 ); DbgPrint("mpiInitialize: IOPLog (%d) dd /p %08X`%08X L %x\n", saRoot->mainConfigTable.IOPeventLogOption, saRoot->mainConfigTable.upperIOPeventLogAddress, saRoot->mainConfigTable.lowerIOPeventLogAddress, saRoot->mainConfigTable.IOPeventLogSize/4 ); #endif /* DBG */ #endif /* SA_PRINTOUT_IN_WINDBG */ saRoot->mainConfigTable.FatalErrorInterrupt = value; smTrace(hpDBG_VERY_LOUD,"76",value); /* TP:76 FatalErrorInterrupt */ SA_DBG1(("mpiInitialize: hwConfig->hwOption %X\n", saRoot->hwConfig.hwOption )); SA_DBG1(("mpiInitialize: FatalErrorInterrupt 0x%x\n", value)); /* read back Register Dump offset and length */ value = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_FATAL_ERROR_RDUMP0_OFFSET)); saRoot->mainConfigTable.FatalErrorDumpOffset0 = value; SA_DBG1(("mpiInitialize: FatalErrorDumpOffset0 0x%x\n", value)); value = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_FATAL_ERROR_RDUMP0_LENGTH)); saRoot->mainConfigTable.FatalErrorDumpLength0 = value; SA_DBG1(("mpiInitialize: FatalErrorDumpLength0 0x%x\n", value)); value = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_FATAL_ERROR_RDUMP1_OFFSET)); saRoot->mainConfigTable.FatalErrorDumpOffset1 = value; SA_DBG1(("mpiInitialize: FatalErrorDumpOffset1 0x%x\n", value)); value = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_FATAL_ERROR_RDUMP1_LENGTH)); saRoot->mainConfigTable.FatalErrorDumpLength1 = value; SA_DBG1(("mpiInitialize: FatalErrorDumpLength1 0x%x\n", value)); value = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_PRECTD_PRESETD)); saRoot->mainConfigTable.PortRecoveryTimerPortResetTimer = value; SA_DBG1(("mpiInitialize: PortRecoveryTimerPortResetTimer 0x%x\n", value)); value = ossaHwRegReadExt(agRoot, pcibar, (bit32)(MSGUCfgTblDWIdx + MAIN_IRAD_RESERVED)); saRoot->mainConfigTable.InterruptReassertionDelay = value; SA_DBG1(("mpiInitialize: InterruptReassertionDelay 0x%x\n", value)); if(smIS_SPCV(agRoot)) { bit32 sp1; sp1= ossaHwRegRead(agRoot,V_Scratchpad_1_Register ); if(SCRATCH_PAD1_V_ERROR_STATE(sp1)) { SA_DBG1(("mpiInitialize: SCRATCH_PAD1_V_ERROR_STAT 0x%x\n",sp1 )); ret = AGSA_RC_FAILURE; } } smTraceFuncExit(hpDBG_VERY_LOUD, 'j', "m3"); return ret; } /*******************************************************************************/ /** \fn mpiWaitForConfigTable(agsaRoot_t *agRoot, spc_configMainDescriptor_t *config) * \brief Reading and Writing the Configuration Table * \param agsaRoot Pointer to a data structure containing LL layer context handles * \param config Pointer to Configuration Table * * Return: * AGSA_RC_SUCCESS if read the configuration table from SPC sucessful * AGSA_RC_FAILURE if read the configuration table from SPC failed */ /*******************************************************************************/ GLOBAL bit32 mpiWaitForConfigTable(agsaRoot_t *agRoot, spc_configMainDescriptor_t *config) { agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); bit32 MSGUCfgTblBase, ret = AGSA_RC_SUCCESS; bit32 CfgTblDWIdx; bit32 value, value1; bit32 max_wait_time; bit32 max_wait_count; bit32 Signature, ExpSignature; bit8 pcibar; SA_DBG2(("mpiWaitForConfigTable: Entering\n")); SA_ASSERT(NULL != agRoot, "agRoot argument cannot be null"); smTraceFuncEnter(hpDBG_VERY_LOUD,"m4"); /* check error state */ value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1,MSGU_SCRATCH_PAD_1); value1 = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2,MSGU_SCRATCH_PAD_2); if( smIS_SPC(agRoot) ) { SA_DBG1(("mpiWaitForConfigTable: Waiting for SPC FW becoming ready.P1 0x%X P2 0x%X\n",value,value1)); /* check AAP error */ if (SCRATCH_PAD1_ERR == (value & SCRATCH_PAD_STATE_MASK)) { /* error state */ SA_DBG1(("mpiWaitForConfigTable: AAP error state and code 0x%x, ScratchPad2=0x%x\n", value, value1)); #if defined(SALLSDK_DEBUG) SA_DBG1(("mpiWaitForConfigTable: SCRATCH_PAD0 value = 0x%x\n", siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0))); SA_DBG1(("mpiWaitForConfigTable: SCRATCH_PAD3 value = 0x%x\n", siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_3,MSGU_SCRATCH_PAD_3))); #endif smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "m4"); return AGSA_RC_FAILURE; } /* check IOP error */ if (SCRATCH_PAD2_ERR == (value1 & SCRATCH_PAD_STATE_MASK)) { /* error state */ SA_DBG1(("mpiWaitForConfigTable: IOP error state and code 0x%x, ScratchPad1=0x%x\n", value1, value)); #if defined(SALLSDK_DEBUG) SA_DBG1(("mpiWaitForConfigTable: SCRATCH_PAD0 value = 0x%x\n", siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0))); SA_DBG1(("mpiWaitForConfigTable: SCRATCH_PAD3 value = 0x%x\n", siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_3,MSGU_SCRATCH_PAD_3))); #endif smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "m4"); return AGSA_RC_FAILURE; } /* bit 4-31 of scratch pad1 should be zeros if it is not in error state */ #ifdef DONT_DO /* */ if (value & SCRATCH_PAD1_STATE_MASK) { /* error case */ SA_DBG1(("mpiWaitForConfigTable: wrong state failure, scratchPad1 0x%x\n", value)); SA_DBG1(("mpiWaitForConfigTable: ScratchPad0 AAP error code 0x%x\n", siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0))); #if defined(SALLSDK_DEBUG) SA_DBG1(("mpiWaitForConfigTable: SCRATCH_PAD2 value = 0x%x\n", siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2,MSGU_SCRATCH_PAD_0))); SA_DBG1(("mpiWaitForConfigTable: SCRATCH_PAD3 value = 0x%x\n", siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_3,MSGU_SCRATCH_PAD_3))); #endif smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "m4"); return AGSA_RC_FAILURE; } /* bit 4-31 of scratch pad2 should be zeros if it is not in error state */ if (value1 & SCRATCH_PAD2_STATE_MASK) { /* error case */ SA_DBG1(("mpiWaitForConfigTable: wrong state failure, scratchPad2 0x%x\n", value1)); SA_DBG1(("mpiWaitForConfigTable: ScratchPad3 IOP error code 0x%x\n",siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_3,MSGU_SCRATCH_PAD_3) )); #if defined(SALLSDK_DEBUG) SA_DBG1(("mpiWaitForConfigTable: SCRATCH_PAD0 value = 0x%x\n", siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0))); SA_DBG1(("mpiWaitForConfigTable: SCRATCH_PAD1 value = 0x%x\n", siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1,MSGU_SCRATCH_PAD_1))); #endif smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "m4"); return AGSA_RC_FAILURE; } #endif /* DONT_DO */ /* checking the fw and IOP in ready state */ max_wait_time = WAIT_SECONDS(gWait_2); /* 2 sec timeout */ max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT); /* wait until scratch pad 1 and 2 registers in ready state */ do { ossaStallThread(agRoot, WAIT_INCREMENT); value =siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1,MSGU_SCRATCH_PAD_1) & SCRATCH_PAD1_RDY; value1 =siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2,MSGU_SCRATCH_PAD_2) & SCRATCH_PAD2_RDY; if(smIS_SPCV(agRoot)) { SA_DBG1(("mpiWaitForConfigTable:VEN_DEV_SPCV force SCRATCH_PAD2 RDY 1 %08X 2 %08X\n" ,value,value1)); value1 =3; } if ((max_wait_count -= WAIT_INCREMENT) == 0) { SA_DBG1(("mpiWaitForConfigTable: Timeout!! SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1)); break; } } while ((value != SCRATCH_PAD1_RDY) || (value1 != SCRATCH_PAD2_RDY)); if (!max_wait_count) { SA_DBG1(("mpiWaitForConfigTable: timeout failure\n")); #if defined(SALLSDK_DEBUG) SA_DBG1(("mpiWaitForConfigTable: SCRATCH_PAD0 value = 0x%x\n", siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0))); SA_DBG1(("mpiWaitForConfigTable: SCRATCH_PAD3 value = 0x%x\n", siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_3,MSGU_SCRATCH_PAD_3))); #endif smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "m4"); return AGSA_RC_FAILURE; } }else { if(((value & SCRATCH_PAD1_V_BOOTSTATE_HDA_SEEPROM ) == SCRATCH_PAD1_V_BOOTSTATE_HDA_SEEPROM)) { SA_DBG1(("mpiWaitForConfigTable: HDA mode set in SEEPROM SP1 0x%X\n",value)); } if(((value & SCRATCH_PAD1_V_READY) != SCRATCH_PAD1_V_READY) || (value == 0xffffffff)) { SA_DBG1(("mpiWaitForConfigTable: Waiting for _V_ FW becoming ready.P1 0x%X P2 0x%X\n",value,value1)); /* checking the fw and IOP in ready state */ max_wait_time = WAIT_SECONDS(gWait_2); /* 2 sec timeout */ max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT); /* wait until scratch pad 1 and 2 registers in ready state */ do { ossaStallThread(agRoot, WAIT_INCREMENT); value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1,MSGU_SCRATCH_PAD_1); value1 = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2,MSGU_SCRATCH_PAD_2); if ((max_wait_count -= WAIT_INCREMENT) == 0) { SA_DBG1(("mpiWaitForConfigTable: Timeout!! SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1)); return AGSA_RC_FAILURE; } } while (((value & SCRATCH_PAD1_V_READY) != SCRATCH_PAD1_V_READY) || (value == 0xffffffff)); } } SA_DBG1(("mpiWaitForConfigTable: FW Ready, SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1)); /* read scratch pad0 to get PCI BAR and offset of configuration table */ MSGUCfgTblBase = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0); /* get offset */ CfgTblDWIdx = MSGUCfgTblBase & SCRATCH_PAD0_OFFSET_MASK; /* get PCI BAR */ MSGUCfgTblBase = (MSGUCfgTblBase & SCRATCH_PAD0_BAR_MASK) >> SHIFT26; if(smIS_SPC(agRoot)) { if( smIS_spc8081(agRoot)) { if (BAR4 != MSGUCfgTblBase) { SA_DBG1(("mpiWaitForConfigTable: smIS_spc8081 PCI BAR is not BAR4, bar=0x%x - failure\n", MSGUCfgTblBase)); smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "m4"); return AGSA_RC_FAILURE; } } else { if (BAR5 != MSGUCfgTblBase) { SA_DBG1(("mpiWaitForConfigTable: PCI BAR is not BAR5, bar=0x%x - failure\n", MSGUCfgTblBase)); smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "m4"); return AGSA_RC_FAILURE; } } } /* convert the PCI BAR to logical bar number */ pcibar = (bit8)mpiGetPCIBarIndex(agRoot, MSGUCfgTblBase); /* read signature from the configuration table */ Signature = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx); /* Error return if the signature is not "PMCS" */ ExpSignature = ('P') | ('M' << SHIFT8) | ('C' << SHIFT16) | ('S' << SHIFT24); if (Signature != ExpSignature) { SA_DBG1(("mpiWaitForConfigTable: Signature value = 0x%x\n", Signature)); smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "m4"); return AGSA_RC_FAILURE; } /* save Signature */ si_memcpy(&config->Signature, &Signature, sizeof(Signature)); /* read Interface Revsion from the configuration table */ config->InterfaceRev = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_INTERFACE_REVISION); /* read FW Revsion from the configuration table */ config->FWRevision = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_FW_REVISION); /* read Max Outstanding IO from the configuration table */ config->MaxOutstandingIO = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_MAX_OUTSTANDING_IO_OFFSET); /* read Max SGL and Max Devices from the configuration table */ config->MDevMaxSGL = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_MAX_SGL_OFFSET); /* read Controller Cap Flags from the configuration table */ config->ContrlCapFlag = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_CNTRL_CAP_OFFSET); /* read GST Table Offset from the configuration table */ config->GSTOffset = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_GST_OFFSET); /* read Inbound Queue Offset from the configuration table */ config->inboundQueueOffset = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_IBQ_OFFSET); /* read Outbound Queue Offset from the configuration table */ config->outboundQueueOffset = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_OBQ_OFFSET); if(smIS_SPCV(agRoot)) { ;/* SPCV - reserved field */ } else { /* read HDA Flags from the configuration table */ config->HDAModeFlags = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_HDA_FLAGS_OFFSET); } /* read analog Setting offset from the configuration table */ config->analogSetupTblOffset = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_ANALOG_SETUP_OFFSET); if(smIS_SPCV(agRoot)) { ;/* SPCV - reserved field */ /* read interrupt vector table offset */ config->InterruptVecTblOffset = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_INT_VEC_TABLE_OFFSET); /* read phy attribute table offset */ config->phyAttributeTblOffset = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_PHY_ATTRIBUTE_OFFSET); SA_DBG1(("mpiWaitForConfigTable: INT Vector Tble Offset = 0x%x\n", config->InterruptVecTblOffset)); SA_DBG1(("mpiWaitForConfigTable: Phy Attribute Tble Offset = 0x%x\n", config->phyAttributeTblOffset)); } else { ;/* SPC - Not used */ } /* read Error Dump Offset and Length */ config->FatalErrorDumpOffset0 = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_FATAL_ERROR_RDUMP0_OFFSET); config->FatalErrorDumpLength0 = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_FATAL_ERROR_RDUMP0_LENGTH); config->FatalErrorDumpOffset1 = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_FATAL_ERROR_RDUMP1_OFFSET); config->FatalErrorDumpLength1 = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_FATAL_ERROR_RDUMP1_LENGTH); SA_DBG1(("mpiWaitForConfigTable: Interface Revision value = 0x%08x\n", config->InterfaceRev)); SA_DBG1(("mpiWaitForConfigTable: FW Revision value = 0x%08x\n", config->FWRevision)); if(smIS_SPC(agRoot)) { SA_DBG1(("mpiWaitForConfigTable: sTSDK ver. 0x%08x\n", STSDK_LL_SPC_VERSION)); } if(smIS_SPC6V(agRoot)) { SA_DBG1(("mpiWaitForConfigTable: sTSDK ver. 0x%08x\n",STSDK_LL_VERSION )); } if(smIS_SPC12V(agRoot)) { SA_DBG1(("mpiWaitForConfigTable: sTSDK ver. 0x%08x\n",STSDK_LL_12G_VERSION )); } SA_DBG1(("mpiWaitForConfigTable: MaxOutstandingIO value = 0x%08x\n", config->MaxOutstandingIO)); SA_DBG1(("mpiWaitForConfigTable: MDevMaxSGL value = 0x%08x\n", config->MDevMaxSGL)); SA_DBG1(("mpiWaitForConfigTable: ContrlCapFlag value = 0x%08x\n", config->ContrlCapFlag)); SA_DBG1(("mpiWaitForConfigTable: GSTOffset value = 0x%08x\n", config->GSTOffset)); SA_DBG1(("mpiWaitForConfigTable: inboundQueueOffset value = 0x%08x\n", config->inboundQueueOffset)); SA_DBG1(("mpiWaitForConfigTable: outboundQueueOffset value = 0x%08x\n", config->outboundQueueOffset)); SA_DBG1(("mpiWaitForConfigTable: FatalErrorDumpOffset0 value = 0x%08x\n", config->FatalErrorDumpOffset0)); SA_DBG1(("mpiWaitForConfigTable: FatalErrorDumpLength0 value = 0x%08x\n", config->FatalErrorDumpLength0)); SA_DBG1(("mpiWaitForConfigTable: FatalErrorDumpOffset1 value = 0x%08x\n", config->FatalErrorDumpOffset1)); SA_DBG1(("mpiWaitForConfigTable: FatalErrorDumpLength1 value = 0x%08x\n", config->FatalErrorDumpLength1)); SA_DBG1(("mpiWaitForConfigTable: HDAModeFlags value = 0x%08x\n", config->HDAModeFlags)); SA_DBG1(("mpiWaitForConfigTable: analogSetupTblOffset value = 0x%08x\n", config->analogSetupTblOffset)); /* check interface version */ if(smIS_SPC6V(agRoot)) { if (config->InterfaceRev != STSDK_LL_INTERFACE_VERSION) { SA_DBG1(("mpiWaitForConfigTable: V sTSDK interface ver. 0x%x does not match InterfaceRev 0x%x warning!\n", STSDK_LL_INTERFACE_VERSION, config->InterfaceRev)); ret = AGSA_RC_VERSION_UNTESTED; if ((config->InterfaceRev & STSDK_LL_INTERFACE_VERSION_IGNORE_MASK) != (STSDK_LL_INTERFACE_VERSION & STSDK_LL_INTERFACE_VERSION_IGNORE_MASK)) { SA_DBG1(("mpiWaitForConfigTable: V sTSDK interface ver. 0x%x incompatible with InterfaceRev 0x%x warning!\n", STSDK_LL_INTERFACE_VERSION, config->InterfaceRev)); ret = AGSA_RC_VERSION_INCOMPATIBLE; smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "m4"); return ret; } } } else if(smIS_SPC12V(agRoot)) { if (config->InterfaceRev != STSDK_LL_12G_INTERFACE_VERSION) { SA_DBG1(("mpiWaitForConfigTable: 12g V sTSDK interface ver. 0x%x does not match InterfaceRev 0x%x warning!\n", STSDK_LL_12G_INTERFACE_VERSION, config->InterfaceRev)); ret = AGSA_RC_VERSION_UNTESTED; if ((config->InterfaceRev & STSDK_LL_INTERFACE_VERSION_IGNORE_MASK) != (STSDK_LL_12G_INTERFACE_VERSION & STSDK_LL_INTERFACE_VERSION_IGNORE_MASK)) { SA_DBG1(("mpiWaitForConfigTable: V sTSDK interface ver. 0x%x incompatible with InterfaceRev 0x%x warning!\n", STSDK_LL_12G_INTERFACE_VERSION, config->InterfaceRev)); ret = AGSA_RC_VERSION_INCOMPATIBLE; ret = AGSA_RC_VERSION_UNTESTED; smTraceFuncExit(hpDBG_VERY_LOUD, 'j', "m4"); return ret; } } } else { if (config->InterfaceRev != STSDK_LL_OLD_INTERFACE_VERSION) { SA_DBG1(("mpiWaitForConfigTable: SPC sTSDK interface ver. 0x%08x not compatible with InterfaceRev 0x%x warning!\n", STSDK_LL_INTERFACE_VERSION, config->InterfaceRev)); ret = AGSA_RC_VERSION_INCOMPATIBLE; smTraceFuncExit(hpDBG_VERY_LOUD, 'k', "m4"); return ret; } } /* Check FW versions */ if(smIS_SPC6V(agRoot)) { SA_DBG1(("mpiWaitForConfigTable:6 sTSDK ver. sa.h 0x%08x config 0x%08x\n", STSDK_LL_VERSION, config->FWRevision)); /* check FW and LL sTSDK version */ if (config->FWRevision != MATCHING_V_FW_VERSION ) { if (config->FWRevision > MATCHING_V_FW_VERSION) { SA_DBG1(("mpiWaitForConfigTable: sTSDK ver. 0x%x hadn't tested with FW ver. 0x%08x warning!\n", STSDK_LL_VERSION, config->FWRevision)); ret = AGSA_RC_VERSION_UNTESTED; } else if (config->FWRevision < MIN_FW_SPCVE_VERSION_SUPPORTED) { SA_DBG1(("mpiWaitForConfigTable: sTSDK ver. 0x%x not compatible with FW ver. 0x%08x warning!\n", STSDK_LL_VERSION, config->FWRevision)); ret = AGSA_RC_VERSION_INCOMPATIBLE; smTraceFuncExit(hpDBG_VERY_LOUD, 'l', "m4"); return ret; } else { SA_DBG1(("mpiWaitForConfigTable: sTSDK ver. 0x%x mismatch with FW ver. 0x%08x warning!\n",STSDK_LL_VERSION , config->FWRevision)); ret = AGSA_RC_VERSION_UNTESTED; } } }else if(smIS_SPC12V(agRoot)) { SA_DBG1(("mpiWaitForConfigTable:12 sTSDK ver. sa.h 0x%08x config 0x%08x\n", STSDK_LL_12G_VERSION, config->FWRevision)); /* check FW and LL sTSDK version */ if (config->FWRevision != MATCHING_12G_V_FW_VERSION ) { if (config->FWRevision > MATCHING_12G_V_FW_VERSION) { SA_DBG1(("mpiWaitForConfigTable: sTSDK ver. 0x%x hadn't tested with FW ver. 0x%08x warning!\n", STSDK_LL_12G_VERSION, config->FWRevision)); ret = AGSA_RC_VERSION_UNTESTED; } else if (config->FWRevision < MIN_FW_12G_SPCVE_VERSION_SUPPORTED) { SA_DBG1(("mpiWaitForConfigTable: sTSDK ver. 0x%x not compatible with FW ver. 0x%08x warning!\n", STSDK_LL_12G_VERSION, config->FWRevision)); ret = AGSA_RC_VERSION_INCOMPATIBLE; smTraceFuncExit(hpDBG_VERY_LOUD, 'm', "m4"); return ret; } else { SA_DBG1(("mpiWaitForConfigTable: sTSDK ver. 0x%x mismatch with FW ver. 0x%08x warning!\n",STSDK_LL_12G_VERSION , config->FWRevision)); ret = AGSA_RC_VERSION_UNTESTED; } } } else { if (config->FWRevision != MATCHING_SPC_FW_VERSION ) { if (config->FWRevision > MATCHING_SPC_FW_VERSION) { SA_DBG1(("mpiWaitForConfigTable: sTSDK ver. 0x%x hadn't tested with FW ver. 0x%08x warning!\n", STSDK_LL_SPC_VERSION, config->FWRevision)); ret = AGSA_RC_VERSION_UNTESTED; } else if (config->FWRevision < MIN_FW_SPC_VERSION_SUPPORTED) { SA_DBG1(("mpiWaitForConfigTable: sTSDK ver. 0x%x not compatible with FW ver. 0x%08x warning!\n", STSDK_LL_SPC_VERSION, config->FWRevision)); ret = AGSA_RC_VERSION_INCOMPATIBLE; smTraceFuncExit(hpDBG_VERY_LOUD, 'n', "m4"); return ret; } else { SA_DBG1(("mpiWaitForConfigTable: sTSDK ver. 0x%x mismatch with FW ver. 0x%08x warning!\n",STSDK_LL_SPC_VERSION , config->FWRevision)); ret = AGSA_RC_VERSION_UNTESTED; } } } SA_DBG1(("mpiWaitForConfigTable: ILA version 0x%08X\n", ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_ILAT_ILAV_ILASMRN_ILAMRN_ILAMJN) )); if(smIS_SPC12V(agRoot)) { if (config->InterfaceRev > 0x301 ) { SA_DBG1(("mpiWaitForConfigTable: MAIN_INACTIVE_ILA_REVSION 0x%08X\n", ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_INACTIVE_ILA_REVSION) )); SA_DBG1(("mpiWaitForConfigTable: MAIN_SEEPROM_REVSION 0x%08X\n", ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_SEEPROM_REVSION) )); } } if(smIS_SPC12V(agRoot)) { if (config->InterfaceRev > 0x301 ) { SA_DBG1(("mpiWaitForConfigTable: MAIN_AWT_MIDRANGE 0x%08X\n", ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_AWT_MIDRANGE) )); } } if(smIS_SFC(agRoot)) { /* always success for SFC*/ ret = AGSA_RC_SUCCESS; } if (agNULL != saRoot) { /* save the information */ saRoot->ControllerInfo.signature = Signature; saRoot->ControllerInfo.fwInterfaceRev = config->InterfaceRev; if(smIS_SPCV(agRoot)) { saRoot->ControllerInfo.hwRevision = (ossaHwRegReadConfig32(agRoot,8) & 0xFF); SA_DBG1(("mpiWaitForConfigTable: hwRevision 0x%x\n",saRoot->ControllerInfo.hwRevision )); } else { saRoot->ControllerInfo.hwRevision = SPC_READ_DEV_REV; } saRoot->ControllerInfo.fwRevision = config->FWRevision; saRoot->ControllerInfo.ilaRevision = config->ilaRevision; saRoot->ControllerInfo.maxPendingIO = config->MaxOutstandingIO; saRoot->ControllerInfo.maxSgElements = config->MDevMaxSGL & 0xFFFF; saRoot->ControllerInfo.maxDevices = (config->MDevMaxSGL & MAX_DEV_BITS) >> SHIFT16; saRoot->ControllerInfo.queueSupport = config->ContrlCapFlag & Q_SUPPORT_BITS; saRoot->ControllerInfo.phyCount = (bit8)((config->ContrlCapFlag & PHY_COUNT_BITS) >> SHIFT19); saRoot->ControllerInfo.sasSpecsSupport = (config->ContrlCapFlag & SAS_SPEC_BITS) >> SHIFT25; SA_DBG1(("mpiWaitForConfigTable: MaxOutstandingIO 0x%x swConfig->maxActiveIOs 0x%x\n", config->MaxOutstandingIO,saRoot->swConfig.maxActiveIOs )); if(smIS_SPCV(agRoot)) { ;/* SPCV - reserved field */ } else { saRoot->ControllerInfo.controllerSetting = (bit8)config->HDAModeFlags; } saRoot->ControllerInfo.sdkInterfaceRev = STSDK_LL_INTERFACE_VERSION; saRoot->ControllerInfo.sdkRevision = STSDK_LL_VERSION; saRoot->mainConfigTable.regDumpPCIBAR = pcibar; saRoot->mainConfigTable.FatalErrorDumpOffset0 = config->FatalErrorDumpOffset0; saRoot->mainConfigTable.FatalErrorDumpLength0 = config->FatalErrorDumpLength0; saRoot->mainConfigTable.FatalErrorDumpOffset1 = config->FatalErrorDumpOffset1; saRoot->mainConfigTable.FatalErrorDumpLength1 = config->FatalErrorDumpLength1; if(smIS_SPCV(agRoot)) { ;/* SPCV - reserved field */ } else { saRoot->mainConfigTable.HDAModeFlags = config->HDAModeFlags; } saRoot->mainConfigTable.analogSetupTblOffset = config->analogSetupTblOffset; if(smIS_SPCV(agRoot)) { saRoot->mainConfigTable.InterruptVecTblOffset = config->InterruptVecTblOffset; saRoot->mainConfigTable.phyAttributeTblOffset = config->phyAttributeTblOffset; saRoot->mainConfigTable.PortRecoveryTimerPortResetTimer = config->portRecoveryResetTimer; } SA_DBG1(("mpiWaitForConfigTable: Signature = 0x%x\n", Signature)); SA_DBG1(("mpiWaitForConfigTable: hwRevision = 0x%x\n", saRoot->ControllerInfo.hwRevision)); SA_DBG1(("mpiWaitForConfigTable: FW Revision = 0x%x\n", config->FWRevision)); SA_DBG1(("mpiWaitForConfigTable: Max Sgl = 0x%x\n", saRoot->ControllerInfo.maxSgElements)); SA_DBG1(("mpiWaitForConfigTable: Max Device = 0x%x\n", saRoot->ControllerInfo.maxDevices)); SA_DBG1(("mpiWaitForConfigTable: Queue Support = 0x%x\n", saRoot->ControllerInfo.queueSupport)); SA_DBG1(("mpiWaitForConfigTable: Phy Count = 0x%x\n", saRoot->ControllerInfo.phyCount)); SA_DBG1(("mpiWaitForConfigTable: sas Specs Support = 0x%x\n", saRoot->ControllerInfo.sasSpecsSupport)); } if(ret != AGSA_RC_SUCCESS ) { SA_DBG1(("mpiWaitForConfigTable: return 0x%x not AGSA_RC_SUCCESS warning!\n", ret)); } smTraceFuncExit(hpDBG_VERY_LOUD, 'o', "m4"); return ret; } /*******************************************************************************/ /** \fn mpiUnInitConfigTable(agsaRoot_t *agRoot, spc_configMainDescriptor_t *config) * \brief UnInitialization Configuration Table * \param agsaRoot Pointer to a data structure containing LL layer context handles * * Return: * AGSA_RC_SUCCESS if Un-initialize the configuration table sucessful * AGSA_RC_FAILURE if Un-initialize the configuration table failed */ /*******************************************************************************/ GLOBAL bit32 mpiUnInitConfigTable(agsaRoot_t *agRoot) { bit32 MSGUCfgTblBase; bit32 CfgTblDWIdx, GSTOffset, GSTLenMPIS; bit32 value, togglevalue; bit32 max_wait_time; bit32 max_wait_count; bit8 pcibar; smTraceFuncEnter(hpDBG_VERY_LOUD,"m7"); SA_DBG1(("mpiUnInitConfigTable: agRoot %p\n",agRoot)); SA_ASSERT(NULL != agRoot, "agRoot argument cannot be null"); togglevalue = 0; /* read scratch pad0 to get PCI BAR and offset of configuration table */ MSGUCfgTblBase =siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0); if(MSGUCfgTblBase == 0xFFFFFFFF) { SA_DBG1(("mpiUnInitConfigTable: MSGUCfgTblBase = 0x%x AGSA_RC_FAILURE\n",MSGUCfgTblBase)); return AGSA_RC_FAILURE; } /* get offset */ CfgTblDWIdx = MSGUCfgTblBase & SCRATCH_PAD0_OFFSET_MASK; /* get PCI BAR */ MSGUCfgTblBase = (MSGUCfgTblBase & SCRATCH_PAD0_BAR_MASK) >> SHIFT26; /* convert the PCI BAR to logical bar number */ pcibar = (bit8)mpiGetPCIBarIndex(agRoot, MSGUCfgTblBase); /* Write bit 1 to Inbound DoorBell Register */ siHalRegWriteExt(agRoot, GEN_MSGU_IBDB_SET, MSGU_IBDB_SET, SPC_MSGU_CFG_TABLE_RESET); /* wait until Inbound DoorBell Clear Register toggled */ max_wait_time = WAIT_SECONDS(gWait_2); /* 2 sec */ max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT); do { ossaStallThread(agRoot, WAIT_INCREMENT); value = MSGU_READ_IDR; value &= SPC_MSGU_CFG_TABLE_RESET; } while ((value != togglevalue) && (max_wait_count -= WAIT_INCREMENT)); if (!max_wait_count) { SA_DBG1(("mpiUnInitConfigTable: TIMEOUT:IBDB value/toggle = 0x%x 0x%x\n", value, togglevalue)); smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "m7"); if(smIS_SPC(agRoot) ) { return AGSA_RC_FAILURE; } } /* check the MPI-State for termination in progress */ /* wait until Inbound DoorBell Clear Register toggled */ max_wait_time = WAIT_SECONDS(gWait_2); /* 2 sec */ max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT); GSTOffset = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_GST_OFFSET); do { ossaStallThread(agRoot, WAIT_INCREMENT); if(GSTOffset == 0xFFFFFFFF) { SA_DBG1(("mpiUnInitConfigTable:AGSA_RC_FAILURE GSTOffset = 0x%x\n",GSTOffset)); return AGSA_RC_FAILURE; } GSTLenMPIS = ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + (bit32)(GSTOffset + GST_GSTLEN_MPIS_OFFSET)); if (GST_MPI_STATE_UNINIT == (GSTLenMPIS & GST_MPI_STATE_MASK)) { break; } } while (max_wait_count -= WAIT_INCREMENT); if (!max_wait_count) { SA_DBG1(("mpiUnInitConfigTable: TIMEOUT, MPI State = 0x%x\n", GSTLenMPIS & GST_MPI_STATE_MASK)); #if defined(SALLSDK_DEBUG) SA_DBG1(("mpiUnInitConfigTable: SCRATCH_PAD0 value = 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_SCRATCH_PAD_0))); SA_DBG1(("mpiUnInitConfigTable: SCRATCH_PAD1 value = 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_SCRATCH_PAD_1))); SA_DBG1(("mpiUnInitConfigTable: SCRATCH_PAD2 value = 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_SCRATCH_PAD_2))); SA_DBG1(("mpiUnInitConfigTable: SCRATCH_PAD3 value = 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_SCRATCH_PAD_3))); #endif smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "m7"); return AGSA_RC_FAILURE; } smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "m7"); return AGSA_RC_SUCCESS; } /*******************************************************************************/ /** \fn void mpiUpdateIBQueueCfgTable(agsaRoot_t *agRoot, spc_inboundQueueDescriptor_t *outQueueCfg, * bit32 QueueTableOffset,bit8 pcibar) * \brief Writing to the inbound queue of the Configuration Table * \param agsaRoot Pointer to a data structure containing both application and LL layer context handles * \param outQueueCfg Pointer to inbuond configuration area * \param QueueTableOffset Queue configuration table offset * \param pcibar PCI BAR * * Return: * None */ /*******************************************************************************/ GLOBAL void mpiUpdateIBQueueCfgTable(agsaRoot_t *agRoot, spc_inboundQueueDescriptor_t *inQueueCfg, bit32 QueueTableOffset, bit8 pcibar) { smTraceFuncEnter(hpDBG_VERY_LOUD,"m5"); smTrace(hpDBG_VERY_LOUD,"Ba",QueueTableOffset); /* TP:Ba QueueTableOffset */ smTrace(hpDBG_VERY_LOUD,"Bb",pcibar); /* TP:Bb pcibar */ ossaHwRegWriteExt(agRoot, pcibar, (bit32)(QueueTableOffset + IB_PROPERITY_OFFSET), inQueueCfg->elementPriSizeCount); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(QueueTableOffset + IB_BASE_ADDR_HI_OFFSET), inQueueCfg->upperBaseAddress); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(QueueTableOffset + IB_BASE_ADDR_LO_OFFSET), inQueueCfg->lowerBaseAddress); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(QueueTableOffset + IB_CI_BASE_ADDR_HI_OFFSET), inQueueCfg->ciUpperBaseAddress); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(QueueTableOffset + IB_CI_BASE_ADDR_LO_OFFSET), inQueueCfg->ciLowerBaseAddress); SA_DBG3(("mpiUpdateIBQueueCfgTable: Offset 0x%08x elementPriSizeCount 0x%x\n",(bit32)(QueueTableOffset + IB_PROPERITY_OFFSET), inQueueCfg->elementPriSizeCount)); SA_DBG3(("mpiUpdateIBQueueCfgTable: Offset 0x%08x upperBaseAddress 0x%x\n",(bit32)(QueueTableOffset + IB_BASE_ADDR_HI_OFFSET), inQueueCfg->upperBaseAddress)); SA_DBG3(("mpiUpdateIBQueueCfgTable: Offset 0x%08x lowerBaseAddress 0x%x\n",(bit32)(QueueTableOffset + IB_BASE_ADDR_LO_OFFSET), inQueueCfg->lowerBaseAddress)); SA_DBG3(("mpiUpdateIBQueueCfgTable: Offset 0x%08x ciUpperBaseAddress 0x%x\n",(bit32)(QueueTableOffset + IB_CI_BASE_ADDR_HI_OFFSET), inQueueCfg->ciUpperBaseAddress)); SA_DBG3(("mpiUpdateIBQueueCfgTable: Offset 0x%08x ciLowerBaseAddress 0x%x\n",(bit32)(QueueTableOffset + IB_CI_BASE_ADDR_LO_OFFSET), inQueueCfg->ciLowerBaseAddress)); smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "m5"); } /*******************************************************************************/ /** \fn void mpiUpdateOBQueueCfgTable(agsaRoot_t *agRoot, spc_outboundQueueDescriptor_t *outQueueCfg, * bit32 QueueTableOffset,bit8 pcibar) * \brief Writing to the inbound queue of the Configuration Table * \param agsaRoot Pointer to a data structure containing both application * and LL layer context handles * \param outQueueCfg Pointer to outbuond configuration area * \param QueueTableOffset Queue configuration table offset * \param pcibar PCI BAR * * Return: * None */ /*******************************************************************************/ GLOBAL void mpiUpdateOBQueueCfgTable(agsaRoot_t *agRoot, spc_outboundQueueDescriptor_t *outQueueCfg, bit32 QueueTableOffset, bit8 pcibar) { smTraceFuncEnter(hpDBG_VERY_LOUD,"m8"); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(QueueTableOffset + OB_PROPERITY_OFFSET), outQueueCfg->elementSizeCount); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(QueueTableOffset + OB_BASE_ADDR_HI_OFFSET), outQueueCfg->upperBaseAddress); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(QueueTableOffset + OB_BASE_ADDR_LO_OFFSET), outQueueCfg->lowerBaseAddress); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(QueueTableOffset + OB_PI_BASE_ADDR_HI_OFFSET), outQueueCfg->piUpperBaseAddress); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(QueueTableOffset + OB_PI_BASE_ADDR_LO_OFFSET), outQueueCfg->piLowerBaseAddress); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(QueueTableOffset + OB_INTERRUPT_COALES_OFFSET), outQueueCfg->interruptVecCntDelay); SA_DBG3(("mpiUpdateOBQueueCfgTable: Offset 0x%08x elementSizeCount 0x%x\n",(bit32)(QueueTableOffset + OB_PROPERITY_OFFSET), outQueueCfg->elementSizeCount)); SA_DBG3(("mpiUpdateOBQueueCfgTable: Offset 0x%08x upperBaseAddress 0x%x\n",(bit32)(QueueTableOffset + OB_BASE_ADDR_HI_OFFSET), outQueueCfg->upperBaseAddress)); SA_DBG3(("mpiUpdateOBQueueCfgTable: Offset 0x%08x lowerBaseAddress 0x%x\n",(bit32)(QueueTableOffset + OB_BASE_ADDR_LO_OFFSET), outQueueCfg->lowerBaseAddress)); SA_DBG3(("mpiUpdateOBQueueCfgTable: Offset 0x%08x piUpperBaseAddress 0x%x\n",(bit32)(QueueTableOffset + OB_PI_BASE_ADDR_HI_OFFSET), outQueueCfg->piUpperBaseAddress)); SA_DBG3(("mpiUpdateOBQueueCfgTable: Offset 0x%08x piLowerBaseAddress 0x%x\n",(bit32)(QueueTableOffset + OB_PI_BASE_ADDR_LO_OFFSET), outQueueCfg->piLowerBaseAddress)); SA_DBG3(("mpiUpdateOBQueueCfgTable: Offset 0x%08x interruptVecCntDelay 0x%x\n",(bit32)(QueueTableOffset + OB_INTERRUPT_COALES_OFFSET), outQueueCfg->interruptVecCntDelay)); smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "m8"); } /*******************************************************************************/ /** \fn void mpiUpdateOBQueueCfgTable(agsaRoot_t *agRoot, spc_outboundQueueDescriptor_t *outQueueCfg, * bit32 QueueTableOffset,bit8 pcibar) * \brief Writing to the inbound queue of the Configuration Table * \param agsaRoot Pointer to a data structure containing both application * and LL layer context handles * \param outQueueCfg Pointer to outbuond configuration area * \param QueueTableOffset Queue configuration table offset * \param pcibar PCI BAR * * Return: * None */ /*******************************************************************************/ GLOBAL void mpiUpdateFatalErrorTable(agsaRoot_t *agRoot, bit32 FerrTableOffset, bit32 lowerBaseAddress, bit32 upperBaseAddress, bit32 length, bit8 pcibar) { smTraceFuncEnter(hpDBG_VERY_LOUD,"2U"); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(FerrTableOffset + MPI_FATAL_EDUMP_TABLE_LO_OFFSET), lowerBaseAddress); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(FerrTableOffset + MPI_FATAL_EDUMP_TABLE_HI_OFFSET), upperBaseAddress); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(FerrTableOffset + MPI_FATAL_EDUMP_TABLE_LENGTH), length); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(FerrTableOffset + MPI_FATAL_EDUMP_TABLE_HANDSHAKE), 0); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(FerrTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS), 0); SA_DBG3(("mpiUpdateFatalErrorTable: Offset 0x%08x MPI_FATAL_EDUMP_TABLE_LO_OFFSET 0x%x\n",FerrTableOffset + MPI_FATAL_EDUMP_TABLE_LO_OFFSET, lowerBaseAddress)); SA_DBG3(("mpiUpdateFatalErrorTable: Offset 0x%08x MPI_FATAL_EDUMP_TABLE_HI_OFFSET 0x%x\n",FerrTableOffset + MPI_FATAL_EDUMP_TABLE_HI_OFFSET,upperBaseAddress )); SA_DBG3(("mpiUpdateFatalErrorTable: Offset 0x%08x MPI_FATAL_EDUMP_TABLE_LENGTH 0x%x\n",FerrTableOffset + MPI_FATAL_EDUMP_TABLE_LENGTH, length)); SA_DBG3(("mpiUpdateFatalErrorTable: Offset 0x%08x MPI_FATAL_EDUMP_TABLE_HANDSHAKE 0x%x\n",FerrTableOffset + MPI_FATAL_EDUMP_TABLE_HANDSHAKE,0 )); SA_DBG3(("mpiUpdateFatalErrorTable: Offset 0x%08x MPI_FATAL_EDUMP_TABLE_STATUS 0x%x\n",FerrTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS,0 )); smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2U"); } /*******************************************************************************/ /** \fn bit32 mpiGetPCIBarIndex(agsaRoot_t *agRoot, pciBar) * \brief Get PCI BAR Index from PCI BAR * \param agsaRoot Pointer to a data structure containing both application and LL layer context handles * \param pciBar - PCI BAR * * Return: * PCI BAR Index */ /*******************************************************************************/ GLOBAL bit32 mpiGetPCIBarIndex(agsaRoot_t *agRoot, bit32 pciBar) { switch(pciBar) { case BAR0: case BAR1: pciBar = PCIBAR0; break; case BAR2: case BAR3: pciBar = PCIBAR1; break; case BAR4: pciBar = PCIBAR2; break; case BAR5: pciBar = PCIBAR3; break; default: pciBar = PCIBAR0; break; } return pciBar; } /*******************************************************************************/ /** \fn void mpiReadGSTTable(agsaRoot_t *agRoot, spc_GSTableDescriptor_t *mpiGSTable) * \brief Reading the General Status Table * * \param agsaRoot Handles for this instance of SAS/SATA LLL * \param mpiGSTable Pointer of General Status Table * * Return: * None */ /*******************************************************************************/ GLOBAL void mpiReadGSTable(agsaRoot_t *agRoot, spc_GSTableDescriptor_t *mpiGSTable) { bit32 CFGTableOffset, TableOffset; bit32 GSTableOffset; bit8 i, pcibar; smTraceFuncEnter(hpDBG_VERY_LOUD,"m9"); /* get offset of the configuration table */ TableOffset = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0); if(0xFFFFFFFF == TableOffset) { SA_ASSERT(0xFFFFFFFF == TableOffset, "Chip PCI dead"); SA_DBG1(("mpiReadGSTable: Chip PCI dead TableOffset 0x%x\n", TableOffset)); return; } // SA_DBG1(("mpiReadGSTable: TableOffset 0x%x\n", TableOffset)); CFGTableOffset = TableOffset & SCRATCH_PAD0_OFFSET_MASK; /* get PCI BAR */ TableOffset = (TableOffset & SCRATCH_PAD0_BAR_MASK) >> SHIFT26; /* convert the PCI BAR to logical bar number */ pcibar = (bit8)mpiGetPCIBarIndex(agRoot, TableOffset); /* read GST Table Offset from the configuration table */ GSTableOffset = ossaHwRegReadExt(agRoot, pcibar, (bit32)CFGTableOffset + MAIN_GST_OFFSET); // SA_DBG1(("mpiReadGSTable: GSTableOffset 0x%x\n",GSTableOffset )); GSTableOffset = CFGTableOffset + GSTableOffset; mpiGSTable->GSTLenMPIS = ossaHwRegReadExt(agRoot, pcibar, (bit32)(GSTableOffset + GST_GSTLEN_MPIS_OFFSET)); mpiGSTable->IQFreezeState0 = ossaHwRegReadExt(agRoot, pcibar, (bit32)(GSTableOffset + GST_IQ_FREEZE_STATE0_OFFSET)); mpiGSTable->IQFreezeState1 = ossaHwRegReadExt(agRoot, pcibar, (bit32)(GSTableOffset + GST_IQ_FREEZE_STATE1_OFFSET)); mpiGSTable->MsguTcnt = ossaHwRegReadExt(agRoot, pcibar, (bit32)(GSTableOffset + GST_MSGUTCNT_OFFSET)); mpiGSTable->IopTcnt = ossaHwRegReadExt(agRoot, pcibar, (bit32)(GSTableOffset + GST_IOPTCNT_OFFSET)); mpiGSTable->Iop1Tcnt = ossaHwRegReadExt(agRoot, pcibar, (bit32)(GSTableOffset + GST_IOP1TCNT_OFFSET)); SA_DBG4(("mpiReadGSTable: GSTLenMPIS 0x%x\n", mpiGSTable->GSTLenMPIS)); SA_DBG4(("mpiReadGSTable: GSTLen 0x%x\n", (mpiGSTable->GSTLenMPIS & 0xfff8) >> SHIFT3)); SA_DBG4(("mpiReadGSTable: IQFreezeState0 0x%x\n", mpiGSTable->IQFreezeState0)); SA_DBG4(("mpiReadGSTable: IQFreezeState1 0x%x\n", mpiGSTable->IQFreezeState1)); SA_DBG4(("mpiReadGSTable: MsguTcnt 0x%x\n", mpiGSTable->MsguTcnt)); SA_DBG4(("mpiReadGSTable: IopTcnt 0x%x\n", mpiGSTable->IopTcnt)); SA_DBG4(("mpiReadGSTable: Iop1Tcnt 0x%x\n", mpiGSTable->Iop1Tcnt)); if(smIS_SPCV(agRoot)) { /***** read Phy State from SAS Phy Attribute Table */ TableOffset = ossaHwRegReadExt(agRoot, pcibar, (bit32)CFGTableOffset + MAIN_PHY_ATTRIBUTE_OFFSET); TableOffset &= 0x00FFFFFF; TableOffset = TableOffset + CFGTableOffset; for (i = 0; i < 8; i++) { mpiGSTable->PhyState[i] = ossaHwRegReadExt(agRoot, pcibar, (bit32)(TableOffset + i * sizeof(phyAttrb_t))); SA_DBG4(("mpiReadGSTable: PhyState[0x%x] 0x%x\n", i, mpiGSTable->PhyState[i])); } } else { for (i = 0; i < 8; i++) { mpiGSTable->PhyState[i] = ossaHwRegReadExt(agRoot, pcibar, (bit32)(GSTableOffset + GST_PHYSTATE_OFFSET + i * 4)); SA_DBG4(("mpiReadGSTable: PhyState[0x%x] 0x%x\n", i, mpiGSTable->PhyState[i])); } } mpiGSTable->GPIOpins = ossaHwRegReadExt(agRoot, pcibar, (bit32)(GSTableOffset + GST_GPIO_PINS_OFFSET)); SA_DBG4(("mpiReadGSTable: GPIOpins 0x%x\n", mpiGSTable->GPIOpins)); for (i = 0; i < 8; i++) { mpiGSTable->recoverErrInfo[i] = ossaHwRegReadExt(agRoot, pcibar, (bit32)(GSTableOffset + GST_RERRINFO_OFFSET)); SA_DBG4(("mpiReadGSTable: recoverErrInfo[0x%x] 0x%x\n", i, mpiGSTable->recoverErrInfo[i])); } smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "m9"); } /*******************************************************************************/ /** \fn void siInitResources(agsaRoot_t *agRoot) * Initialization of LL resources * * \param agsaRoot Handles for this instance of SAS/SATA LLL * \param memoryAllocated Point to the data structure that holds the different * chunks of memory that are required * * Return: * None */ /*******************************************************************************/ GLOBAL void siInitResources(agsaRoot_t *agRoot, agsaMemoryRequirement_t *memoryAllocated, agsaHwConfig_t *hwConfig, agsaSwConfig_t *swConfig, bit32 usecsPerTick) { agsaLLRoot_t *saRoot; agsaDeviceDesc_t *pDeviceDesc; agsaIORequestDesc_t *pRequestDesc; agsaTimerDesc_t *pTimerDesc; agsaPort_t *pPort; agsaPortMap_t *pPortMap; agsaDeviceMap_t *pDeviceMap; agsaIOMap_t *pIOMap; bit32 maxNumIODevices; bit32 i, j; mpiICQueue_t *circularIQ; mpiOCQueue_t *circularOQ; if (agNULL == agRoot) { return; } /* Get the saRoot memory address */ saRoot = (agsaLLRoot_t *) (memoryAllocated->agMemory[LLROOT_MEM_INDEX].virtPtr); agRoot->sdkData = (void *) saRoot; /* Setup Device link */ /* Save the information of allocated device Link memory */ saRoot->deviceLinkMem = memoryAllocated->agMemory[DEVICELINK_MEM_INDEX]; si_memset(saRoot->deviceLinkMem.virtPtr, 0, saRoot->deviceLinkMem.totalLength); SA_DBG2(("siInitResources: [%d] saRoot->deviceLinkMem VirtPtr=%p PhysicalLo=%x Count=%x Total=%x type %x\n" , DEVICELINK_MEM_INDEX, saRoot->deviceLinkMem.virtPtr, saRoot->deviceLinkMem.phyAddrLower, saRoot->deviceLinkMem.numElements, saRoot->deviceLinkMem.totalLength, saRoot->deviceLinkMem.type)); maxNumIODevices = swConfig->numDevHandles; SA_DBG2(("siInitResources: maxNumIODevices=%d, swConfig->numDevHandles=%d \n", maxNumIODevices, swConfig->numDevHandles)); /* Setup free IO Devices link list */ saLlistInitialize(&(saRoot->freeDevicesList)); for ( i = 0; i < (bit32) maxNumIODevices; i ++ ) { /* get the pointer to the device descriptor */ pDeviceDesc = (agsaDeviceDesc_t *) AGSAMEM_ELEMENT_READ(&(saRoot->deviceLinkMem), i); /* Initialize device descriptor */ saLlinkInitialize(&(pDeviceDesc->linkNode)); pDeviceDesc->initiatorDevHandle.osData = agNULL; pDeviceDesc->initiatorDevHandle.sdkData = agNULL; pDeviceDesc->targetDevHandle.osData = agNULL; pDeviceDesc->targetDevHandle.sdkData = agNULL; pDeviceDesc->deviceType = SAS_SATA_UNKNOWN_DEVICE; pDeviceDesc->pPort = agNULL; pDeviceDesc->DeviceMapIndex = 0; saLlistInitialize(&(pDeviceDesc->pendingIORequests)); /* Add the device descriptor to the free IO device link list */ saLlistAdd(&(saRoot->freeDevicesList), &(pDeviceDesc->linkNode)); } /* Setup IO Request link */ /* Save the information of allocated IO Request Link memory */ saRoot->IORequestMem = memoryAllocated->agMemory[IOREQLINK_MEM_INDEX]; si_memset(saRoot->IORequestMem.virtPtr, 0, saRoot->IORequestMem.totalLength); SA_DBG2(("siInitResources: [%d] saRoot->IORequestMem VirtPtr=%p PhysicalLo=%x Count=%x Total=%x type %x\n", IOREQLINK_MEM_INDEX, saRoot->IORequestMem.virtPtr, saRoot->IORequestMem.phyAddrLower, saRoot->IORequestMem.numElements, saRoot->IORequestMem.totalLength, saRoot->IORequestMem.type)); /* Setup free IO Request link list */ saLlistIOInitialize(&(saRoot->freeIORequests)); saLlistIOInitialize(&(saRoot->freeReservedRequests)); for ( i = 0; i < swConfig->maxActiveIOs; i ++ ) { /* get the pointer to the request descriptor */ pRequestDesc = (agsaIORequestDesc_t *) AGSAMEM_ELEMENT_READ(&(saRoot->IORequestMem), i); /* Initialize request descriptor */ saLlinkIOInitialize(&(pRequestDesc->linkNode)); pRequestDesc->valid = agFALSE; pRequestDesc->requestType = AGSA_REQ_TYPE_UNKNOWN; pRequestDesc->pIORequestContext = agNULL; pRequestDesc->HTag = i; pRequestDesc->pDevice = agNULL; pRequestDesc->pPort = agNULL; /* Add the request descriptor to the free IO Request link list */ /* Add the request descriptor to the free Reserved Request link list */ /* SMP request must get service so reserve one request when first SMP completes */ if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) { saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequestDesc->linkNode)); } else { saLlistIOAdd(&(saRoot->freeIORequests), &(pRequestDesc->linkNode)); } } /* Setup timer link */ /* Save the information of allocated timer Link memory */ saRoot->timerLinkMem = memoryAllocated->agMemory[TIMERLINK_MEM_INDEX]; si_memset(saRoot->timerLinkMem.virtPtr, 0, saRoot->timerLinkMem.totalLength); SA_DBG2(("siInitResources: [%d] saRoot->timerLinkMem VirtPtr=%p PhysicalLo=%x Count=%x Total=%x type %x\n", TIMERLINK_MEM_INDEX, saRoot->timerLinkMem.virtPtr, saRoot->timerLinkMem.phyAddrLower, saRoot->timerLinkMem.numElements, saRoot->timerLinkMem.totalLength, saRoot->timerLinkMem.type)); /* Setup free timer link list */ saLlistInitialize(&(saRoot->freeTimers)); for ( i = 0; i < NUM_TIMERS; i ++ ) { /* get the pointer to the timer descriptor */ pTimerDesc = (agsaTimerDesc_t *) AGSAMEM_ELEMENT_READ(&(saRoot->timerLinkMem), i); /* Initialize timer descriptor */ saLlinkInitialize(&(pTimerDesc->linkNode)); pTimerDesc->valid = agFALSE; pTimerDesc->timeoutTick = 0; pTimerDesc->pfnTimeout = agNULL; pTimerDesc->Event = 0; pTimerDesc->pParm = agNULL; /* Add the timer descriptor to the free timer link list */ saLlistAdd(&(saRoot->freeTimers), &(pTimerDesc->linkNode)); } /* Setup valid timer link list */ saLlistInitialize(&(saRoot->validTimers)); /* Setup Phys */ /* Setup PhyCount */ saRoot->phyCount = (bit8) hwConfig->phyCount; /* Init Phy data structure */ for ( i = 0; i < saRoot->phyCount; i ++ ) { saRoot->phys[i].pPort = agNULL; saRoot->phys[i].phyId = (bit8) i; /* setup phy status is PHY_STOPPED */ PHY_STATUS_SET(&(saRoot->phys[i]), PHY_STOPPED); } /* Setup Ports */ /* Setup PortCount */ saRoot->portCount = saRoot->phyCount; /* Setup free port link list */ saLlistInitialize(&(saRoot->freePorts)); for ( i = 0; i < saRoot->portCount; i ++ ) { /* get the pointer to the port */ pPort = &(saRoot->ports[i]); /* Initialize port */ saLlinkInitialize(&(pPort->linkNode)); pPort->portContext.osData = agNULL; pPort->portContext.sdkData = pPort; pPort->portId = 0; pPort->portIdx = (bit8) i; pPort->status = PORT_NORMAL; for ( j = 0; j < saRoot->phyCount; j ++ ) { pPort->phyMap[j] = agFALSE; } saLlistInitialize(&(pPort->listSASATADevices)); /* Add the port to the free port link list */ saLlistAdd(&(saRoot->freePorts), &(pPort->linkNode)); } /* Setup valid port link list */ saLlistInitialize(&(saRoot->validPorts)); /* Init sysIntsActive */ saRoot->sysIntsActive = agFALSE; /* setup timer tick granunarity */ saRoot->usecsPerTick = usecsPerTick; /* initialize LL timer tick */ saRoot->timeTick = 0; /* initialize device (de)registration callback fns */ saRoot->DeviceRegistrationCB = agNULL; saRoot->DeviceDeregistrationCB = agNULL; /* Initialize the PortMap for port context */ for ( i = 0; i < saRoot->portCount; i ++ ) { pPortMap = &(saRoot->PortMap[i]); pPortMap->PortContext = agNULL; pPortMap->PortID = PORT_MARK_OFF; pPortMap->PortStatus = PORT_NORMAL; saRoot->autoDeregDeviceflag[i] = 0; } /* Initialize the DeviceMap for device handle */ for ( i = 0; i < MAX_IO_DEVICE_ENTRIES; i ++ ) { pDeviceMap = &(saRoot->DeviceMap[i]); pDeviceMap->DeviceHandle = agNULL; pDeviceMap->DeviceIdFromFW = i; } /* Initialize the IOMap for IOrequest */ for ( i = 0; i < MAX_ACTIVE_IO_REQUESTS; i ++ ) { pIOMap = &(saRoot->IOMap[i]); pIOMap->IORequest = agNULL; pIOMap->Tag = MARK_OFF; } /* clean the inbound queues */ for (i = 0; i < saRoot->QueueConfig.numInboundQueues; i ++) { if(0 != saRoot->inboundQueue[i].numElements) { circularIQ = &saRoot->inboundQueue[i]; si_memset(circularIQ->memoryRegion.virtPtr, 0, circularIQ->memoryRegion.totalLength); si_memset(saRoot->inboundQueue[i].ciPointer, 0, sizeof(bit32)); } } /* clean the outbound queues */ for (i = 0; i < saRoot->QueueConfig.numOutboundQueues; i ++) { if(0 != saRoot->outboundQueue[i].numElements) { circularOQ = &saRoot->outboundQueue[i]; si_memset(circularOQ->memoryRegion.virtPtr, 0, circularOQ->memoryRegion.totalLength); si_memset(saRoot->outboundQueue[i].piPointer, 0, sizeof(bit32)); circularOQ->producerIdx = 0; circularOQ->consumerIdx = 0; SA_DBG3(("siInitResource: Q %d Clean PI 0x%03x CI 0x%03x\n", i,circularOQ->producerIdx, circularOQ->consumerIdx)); } } return; } /*******************************************************************************/ /** \fn void mpiReadCALTable(agsaRoot_t *agRoot, * spc_SPASTable_t *mpiCALTable, bit32 index) * \brief Reading the Phy Analog Setup Register Table * \param agsaRoot Handles for this instance of SAS/SATA LLL * \param mpiCALTable Pointer of Phy Calibration Table * * Return: * None */ /*******************************************************************************/ GLOBAL void mpiReadCALTable(agsaRoot_t *agRoot, spc_SPASTable_t *mpiCALTable, bit32 index) { bit32 CFGTableOffset, TableOffset; bit32 CALTableOffset; bit8 pcibar; /* get offset of the configuration table */ TableOffset = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0); CFGTableOffset = TableOffset & SCRATCH_PAD0_OFFSET_MASK; /* get PCI BAR */ TableOffset = (TableOffset & SCRATCH_PAD0_BAR_MASK) >> SHIFT26; /* convert the PCI BAR to logical bar number */ pcibar = (bit8)mpiGetPCIBarIndex(agRoot, TableOffset); /* read Calibration Table Offset from the configuration table */ CALTableOffset = ossaHwRegReadExt(agRoot, pcibar, (bit32)CFGTableOffset + MAIN_ANALOG_SETUP_OFFSET); if(smIS_SPCV(agRoot)) { CALTableOffset &= 0x00FFFFFF; } CALTableOffset = CFGTableOffset + CALTableOffset + (index * ANALOG_SETUP_ENTRY_SIZE * 4); mpiCALTable->spaReg0 = ossaHwRegReadExt(agRoot, pcibar, (bit32)(CALTableOffset + TX_PORT_CFG1_OFFSET)); mpiCALTable->spaReg1 = ossaHwRegReadExt(agRoot, pcibar, (bit32)(CALTableOffset + TX_PORT_CFG2_OFFSET)); mpiCALTable->spaReg2 = ossaHwRegReadExt(agRoot, pcibar, (bit32)(CALTableOffset + TX_PORT_CFG3_OFFSET)); mpiCALTable->spaReg3 = ossaHwRegReadExt(agRoot, pcibar, (bit32)(CALTableOffset + TX_CFG_OFFSET)); mpiCALTable->spaReg4 = ossaHwRegReadExt(agRoot, pcibar, (bit32)(CALTableOffset + RV_PORT_CFG1_OFFSET)); mpiCALTable->spaReg5 = ossaHwRegReadExt(agRoot, pcibar, (bit32)(CALTableOffset + RV_PORT_CFG2_OFFSET)); mpiCALTable->spaReg6 = ossaHwRegReadExt(agRoot, pcibar, (bit32)(CALTableOffset + RV_CFG1_OFFSET)); mpiCALTable->spaReg7 = ossaHwRegReadExt(agRoot, pcibar, (bit32)(CALTableOffset + RV_CFG2_OFFSET)); SA_DBG3(("mpiReadCALTable: spaReg0 0x%x\n", mpiCALTable->spaReg0)); SA_DBG3(("mpiReadCALTable: spaReg1 0x%x\n", mpiCALTable->spaReg1)); SA_DBG3(("mpiReadCALTable: spaReg2 0x%x\n", mpiCALTable->spaReg2)); SA_DBG3(("mpiReadCALTable: spaReg3 0x%x\n", mpiCALTable->spaReg3)); SA_DBG3(("mpiReadCALTable: spaReg4 0x%x\n", mpiCALTable->spaReg4)); SA_DBG3(("mpiReadCALTable: spaReg5 0x%x\n", mpiCALTable->spaReg5)); SA_DBG3(("mpiReadCALTable: spaReg6 0x%x\n", mpiCALTable->spaReg6)); SA_DBG3(("mpiReadCALTable: spaReg7 0x%x\n", mpiCALTable->spaReg7)); } /*******************************************************************************/ /** \fn void mpiWriteCALTable(agsaRoot_t *agRoot, * spc_SPASTable_t *mpiCALTable, index) * \brief Writing the Phy Analog Setup Register Table * \param agsaRoot Handles for this instance of SAS/SATA LLL * \param mpiCALTable Pointer of Phy Calibration Table * * Return: * None */ /*******************************************************************************/ GLOBAL void mpiWriteCALTable(agsaRoot_t *agRoot, spc_SPASTable_t *mpiCALTable, bit32 index) { bit32 CFGTableOffset, TableOffset; bit32 CALTableOffset; bit8 pcibar; smTraceFuncEnter(hpDBG_VERY_LOUD,"m6"); /* get offset of the configuration table */ TableOffset = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0); CFGTableOffset = TableOffset & SCRATCH_PAD0_OFFSET_MASK; /* get PCI BAR */ TableOffset = (TableOffset & SCRATCH_PAD0_BAR_MASK) >> SHIFT26; /* convert the PCI BAR to logical bar number */ pcibar = (bit8)mpiGetPCIBarIndex(agRoot, TableOffset); /* read Calibration Table Offset from the configuration table */ CALTableOffset = ossaHwRegReadExt(agRoot, pcibar, (bit32)CFGTableOffset + MAIN_ANALOG_SETUP_OFFSET); if(smIS_SPCV(agRoot)) { CALTableOffset &= 0x00FFFFFF; } CALTableOffset = CFGTableOffset + CALTableOffset + (index * ANALOG_SETUP_ENTRY_SIZE * 4); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(CALTableOffset + TX_PORT_CFG1_OFFSET), mpiCALTable->spaReg0); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(CALTableOffset + TX_PORT_CFG2_OFFSET), mpiCALTable->spaReg1); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(CALTableOffset + TX_PORT_CFG3_OFFSET), mpiCALTable->spaReg2); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(CALTableOffset + TX_CFG_OFFSET), mpiCALTable->spaReg3); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(CALTableOffset + RV_PORT_CFG1_OFFSET), mpiCALTable->spaReg4); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(CALTableOffset + RV_PORT_CFG2_OFFSET), mpiCALTable->spaReg5); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(CALTableOffset + RV_CFG1_OFFSET), mpiCALTable->spaReg6); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(CALTableOffset + RV_CFG2_OFFSET), mpiCALTable->spaReg7); SA_DBG4(("mpiWriteCALTable: Offset 0x%08x spaReg0 0x%x 0x%x 0x%x 0x%x\n",(bit32)(CALTableOffset + TX_PORT_CFG1_OFFSET), mpiCALTable->spaReg0, mpiCALTable->spaReg1, mpiCALTable->spaReg2, mpiCALTable->spaReg3)); SA_DBG4(("mpiWriteCALTable: Offset 0x%08x spaReg4 0x%x 0x%x 0x%x 0x%x\n",(bit32)(CALTableOffset + RV_PORT_CFG1_OFFSET), mpiCALTable->spaReg4, mpiCALTable->spaReg5, mpiCALTable->spaReg6, mpiCALTable->spaReg7)); smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "m6"); } /*******************************************************************************/ /** \fn void mpiWriteCALAll(agsaRoot_t *agRoot, * agsaPhyAnalogSetupTable_t *mpiCALTable) * \brief Writing the Phy Analog Setup Register Table * \param agsaRoot Handles for this instance of SAS/SATA LLL * \param mpiCALTable Pointer of Phy Calibration Table * * Return: * None */ /*******************************************************************************/ GLOBAL void mpiWriteCALAll(agsaRoot_t *agRoot, agsaPhyAnalogSetupTable_t *mpiCALTable) { bit8 i; smTraceFuncEnter(hpDBG_VERY_LOUD,"mz"); if(smIS_SPCV(agRoot)) { smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "mz"); return; } for (i = 0; i < MAX_INDEX; i++) { mpiWriteCALTable(agRoot, (spc_SPASTable_t *)&mpiCALTable->phyAnalogSetupRegisters[i], i); } smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "mz"); } GLOBAL void mpiWrAnalogSetupTable(agsaRoot_t *agRoot, mpiConfig_t *config ) { bit32 AnalogTableBase,CFGTableOffset, value,phy; bit32 AnalogtableSize; bit8 pcibar; value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0); pcibar = (bit8)mpiGetPCIBarIndex(agRoot, value); CFGTableOffset = value & SCRATCH_PAD0_OFFSET_MASK; AnalogtableSize = AnalogTableBase = ossaHwRegReadExt(agRoot,pcibar , (bit32)CFGTableOffset + MAIN_ANALOG_SETUP_OFFSET); AnalogtableSize &= 0xFF000000; AnalogtableSize >>= SHIFT24; AnalogTableBase &= 0x00FFFFFF; AnalogTableBase = CFGTableOffset + AnalogTableBase; // config->phyAnalogConfig.phyAnalogSetupRegisters[0].spaRegister0 = 0; SA_DBG1(("mpiWrAnalogSetupTable:Analogtable Base Offset %08X pcibar %d\n",AnalogTableBase, pcibar )); SA_DBG1(("mpiWrAnalogSetupTable:%d %d\n",(int)sizeof(agsaPhyAnalogSetupRegisters_t), AnalogtableSize)); for(phy = 0; phy < 10; phy++) /* upto 10 phys See PM*/ { ossaHwRegWriteExt(agRoot, pcibar,(AnalogTableBase + ( AnalogtableSize * phy)+ 0 ),config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister0 ); ossaHwRegWriteExt(agRoot, pcibar,(AnalogTableBase + ( AnalogtableSize * phy)+ 4 ),config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister1 ); ossaHwRegWriteExt(agRoot, pcibar,(AnalogTableBase + ( AnalogtableSize * phy)+ 8 ),config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister2 ); ossaHwRegWriteExt(agRoot, pcibar,(AnalogTableBase + ( AnalogtableSize * phy)+ 12),config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister3 ); ossaHwRegWriteExt(agRoot, pcibar,(AnalogTableBase + ( AnalogtableSize * phy)+ 16),config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister4 ); ossaHwRegWriteExt(agRoot, pcibar,(AnalogTableBase + ( AnalogtableSize * phy)+ 20),config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister5 ); ossaHwRegWriteExt(agRoot, pcibar,(AnalogTableBase + ( AnalogtableSize * phy)+ 24),config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister6 ); ossaHwRegWriteExt(agRoot, pcibar,(AnalogTableBase + ( AnalogtableSize * phy)+ 28),config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister7 ); ossaHwRegWriteExt(agRoot, pcibar,(AnalogTableBase + ( AnalogtableSize * phy)+ 32),config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister8 ); ossaHwRegWriteExt(agRoot, pcibar,(AnalogTableBase + ( AnalogtableSize * phy)+ 36),config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister9 ); SA_DBG4(("mpiWrAnalogSetupTable:phy %d Offset 0x%08x spaRegister0 0x%x 0x%x\n",phy, (bit32) AnalogTableBase+ (AnalogtableSize * phy) + 0,config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister0 ,ossaHwRegReadExt(agRoot, pcibar,AnalogTableBase + ( AnalogtableSize * phy)+ 0 ))); SA_DBG4(("mpiWrAnalogSetupTable:phy %d Offset 0x%08x spaRegister1 0x%x 0x%x\n",phy, (bit32) AnalogTableBase+ (AnalogtableSize * phy) + 4,config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister1 ,ossaHwRegReadExt(agRoot, pcibar,AnalogTableBase + ( AnalogtableSize * phy)+ 4 ))); SA_DBG4(("mpiWrAnalogSetupTable:phy %d Offset 0x%08x spaRegister2 0x%x\n",phy, (bit32) AnalogTableBase+ (AnalogtableSize * phy) + 8,config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister2 )); SA_DBG4(("mpiWrAnalogSetupTable:phy %d Offset 0x%08x spaRegister3 0x%x\n",phy, (bit32) AnalogTableBase+ (AnalogtableSize * phy) +12,config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister3 )); SA_DBG4(("mpiWrAnalogSetupTable:phy %d Offset 0x%08x spaRegister4 0x%x\n",phy, (bit32) AnalogTableBase+ (AnalogtableSize * phy) +16,config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister4 )); SA_DBG4(("mpiWrAnalogSetupTable:phy %d Offset 0x%08x spaRegister5 0x%x\n",phy, (bit32) AnalogTableBase+ (AnalogtableSize * phy) +20,config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister5 )); SA_DBG4(("mpiWrAnalogSetupTable:phy %d Offset 0x%08x spaRegister6 0x%x\n",phy, (bit32) AnalogTableBase+ (AnalogtableSize * phy) +24,config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister6 )); SA_DBG4(("mpiWrAnalogSetupTable:phy %d Offset 0x%08x spaRegister7 0x%x\n",phy, (bit32) AnalogTableBase+ (AnalogtableSize * phy) +28,config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister7 )); SA_DBG4(("mpiWrAnalogSetupTable:phy %d Offset 0x%08x spaRegister8 0x%x\n",phy, (bit32) AnalogTableBase+ (AnalogtableSize * phy) +32,config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister8 )); SA_DBG4(("mpiWrAnalogSetupTable:phy %d Offset 0x%08x spaRegister9 0x%x\n",phy, (bit32) AnalogTableBase+ (AnalogtableSize * phy) +36,config->phyAnalogConfig.phyAnalogSetupRegisters[phy].spaRegister9 )); } } GLOBAL void mpiWrIntVecTable(agsaRoot_t *agRoot, mpiConfig_t* config ) { bit32 CFGTableOffset, value; bit32 INTVTableOffset; bit32 ValuetoWrite; bit8 pcibar, i,obq; /* get offset of the configuration table */ value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0); CFGTableOffset = value & SCRATCH_PAD0_OFFSET_MASK; /* get PCI BAR */ value = (value & SCRATCH_PAD0_BAR_MASK) >> SHIFT26; /* convert the PCI BAR to logical bar number */ pcibar = (bit8)mpiGetPCIBarIndex(agRoot, value); /* read Interrupt Table Offset from the main configuration table */ INTVTableOffset = ossaHwRegReadExt(agRoot, pcibar, (bit32)CFGTableOffset + MAIN_INT_VEC_TABLE_OFFSET); INTVTableOffset &= 0x00FFFFFF; INTVTableOffset = CFGTableOffset + INTVTableOffset; SA_DBG1(("mpiWrIntVecTable: Base Offset %08X\n",(bit32)(INTVTableOffset + INT_VT_Coal_CNT_TO ) )); for (i = 0; i < MAX_NUM_VECTOR; i ++) { bit32 found=0; for (obq = 0; obq < MAX_NUM_VECTOR; obq++) { /* find OBQ for vector i */ if( config->outboundQueues[obq].interruptVector == i ) { found=1; break; } } if(!found ) { continue; } ValuetoWrite = (( config->outboundQueues[obq].interruptDelay << SHIFT15) | config->outboundQueues[obq].interruptThreshold ); ossaHwRegWriteExt(agRoot, pcibar, (bit32)(INTVTableOffset + INT_VT_Coal_CNT_TO + i * sizeof(InterruptVT_t)), ValuetoWrite ); SA_DBG3(("mpiWrIntVecTable: Q %d interruptDelay 0x%X interruptThreshold 0x%X \n",i, config->outboundQueues[i].interruptDelay, config->outboundQueues[i].interruptThreshold )); SA_DBG3(("mpiWrIntVecTable: %d INT_VT_Coal_CNT_TO Bar %d Offset %3X Writing 0x%08x\n",i, pcibar, (bit32)(INTVTableOffset + INT_VT_Coal_CNT_TO + i * sizeof(InterruptVT_t)), ValuetoWrite)); } for (i = 0; i < MAX_NUM_VECTOR; i++) { /* read interrupt colescing control and timer */ value = ossaHwRegReadExt(agRoot, pcibar, (bit32)(INTVTableOffset + INT_VT_Coal_CNT_TO + i * sizeof(InterruptVT_t))); SA_DBG4(("mpiWrIntVecTable: Offset 0x%08x Interrupt Colescing iccict[%02d] 0x%x\n", (bit32)(INTVTableOffset + INT_VT_Coal_CNT_TO + i * sizeof(InterruptVT_t)), i, value)); } } GLOBAL void mpiWrPhyAttrbTable(agsaRoot_t *agRoot, sasPhyAttribute_t *phyAttrib) { bit32 CFGTableOffset, value; bit32 PHYTableOffset; bit8 pcibar, i; /* get offset of the configuration table */ value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0); CFGTableOffset = value & SCRATCH_PAD0_OFFSET_MASK; /* get PCI BAR */ value = (value & SCRATCH_PAD0_BAR_MASK) >> SHIFT26; /* convert the PCI BAR to logical bar number */ pcibar = (bit8)mpiGetPCIBarIndex(agRoot, value); /* read Phy Attribute Table Offset from the configuration table */ PHYTableOffset = ossaHwRegReadExt(agRoot, pcibar, (bit32)CFGTableOffset + MAIN_PHY_ATTRIBUTE_OFFSET); PHYTableOffset &=0x00FFFFFF; PHYTableOffset = CFGTableOffset + PHYTableOffset + PHY_EVENT_OQ; SA_DBG1(("mpiWrPhyAttrbTable: PHYTableOffset 0x%08x\n", PHYTableOffset)); /* write OQ event per phy */ for (i = 0; i < MAX_VALID_PHYS; i ++) { ossaHwRegWriteExt(agRoot, pcibar, (bit32)(PHYTableOffset + i * sizeof(phyAttrb_t)), phyAttrib->phyAttribute[i].phyEventOQ); SA_DBG3(("mpiWrPhyAttrbTable:%d Offset 0x%08x phyAttribute 0x%x\n",i,(bit32)(PHYTableOffset + i * sizeof(phyAttrb_t)), phyAttrib->phyAttribute[i].phyEventOQ )); } for (i = 0; i < MAX_VALID_PHYS; i ++) { value = ossaHwRegReadExt(agRoot, pcibar, (bit32)(PHYTableOffset + i * sizeof(phyAttrb_t))); SA_DBG1(("mpiWrPhyAttrbTable: OQ Event per phy[%x] 0x%x\n", i, value)); } } #ifdef TEST /******************************************************************/ /*******************************************************************************/ /** \fn mpiFreezeInboundQueue(agsaRoot_t *agRoot) * \brief Freeze the inbound queue * * \param agRoot Handles for this instance of SAS/SATA hardware * \param bitMapQueueNum0 bit map for inbound queue number 0 - 31 to freeze * \param bitMapQueueNum1 bit map for inbound queue number 32 - 63 to freeze * * Return: * AGSA_RC_SUCCESS if Un-initialize the configuration table sucessful * AGSA_RC_FAILURE if Un-initialize the configuration table failed */ /*******************************************************************************/ GLOBAL bit32 mpiFreezeInboundQueue(agsaRoot_t *agRoot, bit32 bitMapQueueNum0, bit32 bitMapQueueNum1) { bit32 value, togglevalue; bit32 max_wait_time; bit32 max_wait_count; SA_DBG2(("Entering function:mpiFreezeInboundQueue\n")); SA_ASSERT(NULL != agRoot, "agRoot argument cannot be null"); togglevalue = 0; if (bitMapQueueNum0) { /* update the inbound queue number to HOST_SCRATCH_PAD1 register for queue 0 to 31 */ SA_DBG1(("mpiFreezeInboundQueue: SCRATCH_PAD0 value = 0x%x\n", siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_0))); SA_DBG1(("mpiFreezeInboundQueue: SCRATCH_PAD3 value = 0x%x\n", siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_3,MSGU_SCRATCH_PAD_3))); value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0,MSGU_SCRATCH_PAD_1); value |= bitMapQueueNum0; siHalRegWriteExt(agRoot, GEN_MSGU_HOST_SCRATCH_PAD_1, MSGU_HOST_SCRATCH_PAD_1, value); } if (bitMapQueueNum1) { /* update the inbound queue number to HOST_SCRATCH_PAD2 register for queue 32 to 63 */ value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2,MSGU_SCRATCH_PAD_2); value |= bitMapQueueNum1; siHalRegWriteExt(agRoot, GEN_MSGU_HOST_SCRATCH_PAD_2, MSGU_HOST_SCRATCH_PAD_2, value); } /* Write bit 2 to Inbound DoorBell Register */ siHalRegWriteExt(agRoot, GEN_MSGU_IBDB_SET, MSGU_IBDB_SET, IBDB_IBQ_FREEZE); /* wait until Inbound DoorBell Clear Register toggled */ max_wait_time = WAIT_SECONDS(gWait_2); /* 2 sec */ max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT); do { ossaStallThread(agRoot, WAIT_INCREMENT); /* Read Inbound DoorBell Register - for RevB */ // value = ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_IBDB_SET); value = MSGU_READ_IDR; value &= IBDB_IBQ_FREEZE; } while ((value != togglevalue) && (max_wait_count -= WAIT_INCREMENT)); if (!max_wait_count) { SA_DBG1(("mpiFreezeInboundQueue: IBDB value/toggle = 0x%x 0x%x\n", value, togglevalue)); return AGSA_RC_FAILURE; } return AGSA_RC_SUCCESS; } /******************************************************************************/ /** \fn mpiUnFreezeInboundQueue(agsaRoot_t *agRoot) * \brief Freeze the inbound queue * * \param agRoot Handles for this instance of SAS/SATA hardware * \param bitMapQueueNum0 bit map for inbound queue number 0 - 31 to freeze * \param bitMapQueueNum1 bit map for inbound queue number 32 - 63 to freeze * * Return: * AGSA_RC_SUCCESS if Un-initialize the configuration table sucessful * AGSA_RC_FAILURE if Un-initialize the configuration table failed */ /******************************************************************************/ GLOBAL bit32 mpiUnFreezeInboundQueue(agsaRoot_t *agRoot, bit32 bitMapQueueNum0, bit32 bitMapQueueNum1) { bit32 value, togglevalue; bit32 max_wait_time; bit32 max_wait_count; SA_DBG2(("Entering function:mpiUnFreezeInboundQueue\n")); SA_ASSERT(NULL != agRoot, "agRoot argument cannot be null"); togglevalue = 0; if (bitMapQueueNum0) { /* update the inbound queue number to HOST_SCRATCH_PAD1 register - for queue 0 to 31 */ value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1,MSGU_SCRATCH_PAD_1); value |= bitMapQueueNum0; siHalRegWriteExt(agRoot, GEN_MSGU_HOST_SCRATCH_PAD_1, MSGU_HOST_SCRATCH_PAD_1, value); } if (bitMapQueueNum1) { /* update the inbound queue number to HOST_SCRATCH_PAD2 register - for queue 32 to 63 */ value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2,MSGU_SCRATCH_PAD_2); value |= bitMapQueueNum1; siHalRegWriteExt(agRoot, GEN_MSGU_HOST_SCRATCH_PAD_2, MSGU_HOST_SCRATCH_PAD_2, value); } /* Write bit 2 to Inbound DoorBell Register */ siHalRegWriteExt(agRoot, GEN_MSGU_IBDB_SET, MSGU_IBDB_SET, IBDB_IBQ_UNFREEZE); /* wait until Inbound DoorBell Clear Register toggled */ max_wait_time = WAIT_SECONDS(gWait_2); /* 2 sec */ max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT); do { ossaStallThread(agRoot, WAIT_INCREMENT); /* Read Inbound DoorBell Register - for RevB */ value = MSGU_READ_IDR; value &= IBDB_IBQ_UNFREEZE; } while ((value != togglevalue) && (max_wait_count -= WAIT_INCREMENT)); if (!max_wait_count) { SA_DBG1(("mpiUnFreezeInboundQueue: IBDB value/toggle = 0x%x 0x%x\n", value, togglevalue)); return AGSA_RC_FAILURE; } return AGSA_RC_SUCCESS; } #endif /* TEST ****************************************************************/ GLOBAL bit32 si_check_V_HDA(agsaRoot_t *agRoot) { bit32 ret = AGSA_RC_SUCCESS; bit32 hda_status = 0; hda_status = (ossaHwRegReadExt(agRoot, PCIBAR0, SPC_V_HDA_RESPONSE_OFFSET+28)); SA_DBG1(("si_check_V_HDA: hda_status 0x%08X\n",hda_status )); if((hda_status & SPC_V_HDAR_RSPCODE_MASK) == SPC_V_HDAR_IDLE) { /* HDA mode */ SA_DBG1(("si_check_V_HDA: HDA mode, value = 0x%x\n", hda_status)); ret = AGSA_RC_HDA_NO_FW_RUNNING; } return(ret); } GLOBAL bit32 si_check_V_Ready(agsaRoot_t *agRoot) { bit32 ret = AGSA_RC_SUCCESS; bit32 SCRATCH_PAD1; bit32 max_wait_time; bit32 max_wait_count; /* ILA */ max_wait_time = (200 * 1000); /* wait 200 milliseconds */ max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT); do { ossaStallThread(agRoot, WAIT_INCREMENT); SCRATCH_PAD1 = ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_SCRATCH_PAD_1); } while (((SCRATCH_PAD1 & SCRATCH_PAD1_V_ILA_MASK) != SCRATCH_PAD1_V_ILA_MASK) && (max_wait_count -= WAIT_INCREMENT)); if (!max_wait_count) { SA_DBG1(("si_check_V_Ready: SCRATCH_PAD1_V_ILA_MASK (0x%x) not set SCRATCH_PAD1 = 0x%x\n",SCRATCH_PAD1_V_ILA_MASK, SCRATCH_PAD1)); return( AGSA_RC_FAILURE); } /* RAAE */ max_wait_time = (200 * 1000); /* wait 200 milliseconds */ max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT); do { ossaStallThread(agRoot, WAIT_INCREMENT); SCRATCH_PAD1 = ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_SCRATCH_PAD_1); } while (((SCRATCH_PAD1 & SCRATCH_PAD1_V_RAAE_MASK) != SCRATCH_PAD1_V_RAAE_MASK) && (max_wait_count -= WAIT_INCREMENT)); if (!max_wait_count) { SA_DBG1(("si_check_V_Ready: SCRATCH_PAD1_V_RAAE_MASK (0x%x) not set SCRATCH_PAD1 = 0x%x\n",SCRATCH_PAD1_V_RAAE_MASK, SCRATCH_PAD1)); return( AGSA_RC_FAILURE); } /* IOP0 */ max_wait_time = (200 * 1000); /* wait 200 milliseconds */ max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT); do { ossaStallThread(agRoot, WAIT_INCREMENT); SCRATCH_PAD1 = ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_SCRATCH_PAD_1); } while (((SCRATCH_PAD1 & SCRATCH_PAD1_V_IOP0_MASK) != SCRATCH_PAD1_V_IOP0_MASK) && (max_wait_count -= WAIT_INCREMENT)); if (!max_wait_count) { SA_DBG1(("si_check_V_Ready: SCRATCH_PAD1_V_IOP0_MASK (0x%x) not set SCRATCH_PAD1 = 0x%x\n",SCRATCH_PAD1_V_IOP0_MASK ,SCRATCH_PAD1)); return( AGSA_RC_FAILURE); } /* IOP1 */ max_wait_time = (200 * 1000); /* wait 200 milliseconds */ max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT); do { ossaStallThread(agRoot, WAIT_INCREMENT); SCRATCH_PAD1 = ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_SCRATCH_PAD_1); } while (((SCRATCH_PAD1 & SCRATCH_PAD1_V_IOP1_MASK) != SCRATCH_PAD1_V_IOP1_MASK) && (max_wait_count -= WAIT_INCREMENT)); if (!max_wait_count) { SA_DBG1(("si_check_V_Ready: SCRATCH_PAD1_V_IOP1_MASK (0x%x) not set SCRATCH_PAD1 = 0x%x\n",SCRATCH_PAD1_V_IOP1_MASK, SCRATCH_PAD1)); // return( AGSA_RC_FAILURE); } return(ret); } GLOBAL bit32 siScratchDump(agsaRoot_t *agRoot) { bit32 SCRATCH_PAD1; bit32 ret =0; #ifdef SALLSDK_DEBUG bit32 SCRATCH_PAD2; bit32 SCRATCH_PAD3; bit32 SCRATCH_PAD0; SCRATCH_PAD0 = ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_SCRATCH_PAD_0); SCRATCH_PAD2 = ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_SCRATCH_PAD_2); SCRATCH_PAD3 = ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_SCRATCH_PAD_3); #endif /* SALLSDK_DEBUG */ SCRATCH_PAD1 = ossaHwRegReadExt(agRoot, PCIBAR0, MSGU_SCRATCH_PAD_1); SA_DBG1(("siScratchDump: SCRATCH_PAD 0 0x%08x 1 0x%08x 2 0x%08x 3 0x%08x\n",SCRATCH_PAD0,SCRATCH_PAD1,SCRATCH_PAD2,SCRATCH_PAD3 )); if((SCRATCH_PAD1 & SCRATCH_PAD1_V_RESERVED) == SCRATCH_PAD1_V_RESERVED ) { SA_DBG1(("siScratchDump: SCRATCH_PAD1 SCRATCH_PAD1_V_RESERVED 0x%08x\n", SCRATCH_PAD1_V_RESERVED)); } else { if((SCRATCH_PAD1 & SCRATCH_PAD1_V_RAAE_MASK) == SCRATCH_PAD1_V_RAAE_MASK ) { SA_DBG1(("siScratchDump: SCRATCH_PAD1 valid 0x%08x\n",SCRATCH_PAD0 )); SA_DBG1(("siScratchDump: RAAE ready 0x%08x\n",SCRATCH_PAD1 & SCRATCH_PAD1_V_RAAE_MASK)); } if((SCRATCH_PAD1 & SCRATCH_PAD1_V_ILA_MASK) == SCRATCH_PAD1_V_ILA_MASK) { SA_DBG1(("siScratchDump: ILA ready 0x%08x\n", SCRATCH_PAD1 & SCRATCH_PAD1_V_ILA_MASK)); } if(SCRATCH_PAD1 & SCRATCH_PAD1_V_BOOTSTATE_MASK) { SA_DBG1(("siScratchDump: BOOTSTATE not success 0x%08x\n",SCRATCH_PAD1 & SCRATCH_PAD1_V_BOOTSTATE_MASK)); } if((SCRATCH_PAD1 & SCRATCH_PAD1_V_IOP0_MASK) == SCRATCH_PAD1_V_IOP0_MASK) { SA_DBG1(("siScratchDump: IOP0 ready 0x%08x\n",SCRATCH_PAD1 & SCRATCH_PAD1_V_IOP0_MASK)); } if((SCRATCH_PAD1 & SCRATCH_PAD1_V_IOP1_MASK) == SCRATCH_PAD1_V_IOP1_MASK) { SA_DBG1(("siScratchDump: IOP1 ready 0x%08x\n",SCRATCH_PAD1 & SCRATCH_PAD1_V_IOP1_MASK )); } if((SCRATCH_PAD1 & SCRATCH_PAD1_V_READY) == SCRATCH_PAD1_V_READY) { SA_DBG1(("siScratchDump: SCRATCH_PAD1_V_READY 0x%08x\n",SCRATCH_PAD1 & SCRATCH_PAD1_V_READY )); } if((SCRATCH_PAD1 & SCRATCH_PAD1_V_BOOTSTATE_MASK) == SCRATCH_PAD1_V_BOOTSTATE_MASK) { SA_DBG1(("siScratchDump: SCRATCH_PAD1_V_BOOTSTATE_MASK 0x%08x\n",SCRATCH_PAD1 & SCRATCH_PAD1_V_BOOTSTATE_MASK )); } } return(ret); } void si_macro_check(agsaRoot_t *agRoot) { SA_DBG1(("si_macro_check:smIS_SPC %d\n",smIS_SPC(agRoot) )); SA_DBG1(("si_macro_check:smIS_HIL %d\n",smIS_HIL(agRoot) )); SA_DBG1(("si_macro_check:smIS_SFC %d\n",smIS_SFC(agRoot) )); SA_DBG1(("si_macro_check:smIS_spc8001 %d\n",smIS_spc8001(agRoot) )); SA_DBG1(("si_macro_check:smIS_spc8081 %d\n",smIS_spc8081(agRoot) )); SA_DBG1(("si_macro_check:smIS_SPCV8008 %d\n",smIS_SPCV8008(agRoot) )); SA_DBG1(("si_macro_check:smIS_SPCV8009 %d\n",smIS_SPCV8009(agRoot) )); SA_DBG1(("si_macro_check:smIS_SPCV8018 %d\n",smIS_SPCV8018(agRoot) )); SA_DBG1(("si_macro_check:smIS_SPCV8019 %d\n",smIS_SPCV8019(agRoot) )); SA_DBG1(("si_macro_check:smIS_ADAP8088 %d\n",smIS_ADAP8088(agRoot) )); SA_DBG1(("si_macro_check:smIS_ADAP8089 %d\n",smIS_ADAP8089(agRoot) )); SA_DBG1(("si_macro_check:smIS_SPCV8070 %d\n",smIS_SPCV8070(agRoot) )); SA_DBG1(("si_macro_check:smIS_SPCV8071 %d\n",smIS_SPCV8071(agRoot) )); SA_DBG1(("si_macro_check:smIS_SPCV8072 %d\n",smIS_SPCV8072(agRoot) )); SA_DBG1(("si_macro_check:smIS_SPCV8073 %d\n",smIS_SPCV8073(agRoot) )); SA_DBG1(("si_macro_check:smIS_SPCV8074 %d\n",smIS_SPCV8074(agRoot) )); SA_DBG1(("si_macro_check:smIS_SPCV8075 %d\n",smIS_SPCV8075(agRoot) )); SA_DBG1(("si_macro_check:smIS_SPCV8076 %d\n",smIS_SPCV8076(agRoot) )); SA_DBG1(("si_macro_check:smIS_SPCV8077 %d\n",smIS_SPCV8077(agRoot) )); SA_DBG1(("si_macro_check:smIS_SPCV9015 %d\n",smIS_SPCV9015(agRoot) )); SA_DBG1(("si_macro_check:smIS_SPCV9060 %d\n",smIS_SPCV9060(agRoot) )); SA_DBG1(("si_macro_check:smIS_SPCV %d\n",smIS_SPCV(agRoot) )); SA_DBG1(("si_macro_check:smIS64bInt %d\n", smIS64bInt(agRoot) )); }