📄 ixtimesyncacc.c
字号:
/** * @file IxTimeSyncAcc.c * * @author Intel Corporation * @date 07 July 2004 * * @brief Source file for IXP400 Access Layer to IEEE 1588(TM) Precision * Clock Synchronisation Protocol Hardware Assist. * * @par * IXP400 SW Release version 2.1 * * -- Copyright Notice -- * * @par * Copyright (c) 2001-2005, Intel Corporation. * All rights reserved. * * @par * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Intel Corporation nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * * @par * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * * @par * -- End of Copyright Notice -- *//* * System defined include files */#ifdef __ixp46X#include "IxOsal.h"/* * User defined include files */#include "IxTimeSyncAcc.h"#include "IxTimeSyncAcc_p.h"#include "IxFeatureCtrl.h"/* * Support functions definitions *//* Function for setting the base address registers */PRIVATE IX_STATUSixTimeSyncAccBlPlBaseAddressesSet (void){ /* Local variables */ UINT32 blRegsVirtualBaseAddr = (UINT32) NULL; UINT32 plRegsVirtualBaseAddr = (UINT32) NULL; UINT32 ptpPortNum = 0; /* Memory mapping of the Block Level registers starting address */ blRegsVirtualBaseAddr = (UINT32)IX_OSAL_MEM_MAP ( IXP400_TIMESYNCACC_BLREGS_BASEADDR, IXP400_TIMESYNCACC_BLREGS_MEMMAP_SIZE); if ((UINT32)NULL == blRegsVirtualBaseAddr) { /* Virtual memory mapping failed */ return IX_FAIL; } /* end of if ((UINT32)NULL == blRegsVirtualBaseAddr) */ /* Memory mapping of the Port Level registers starting address */ plRegsVirtualBaseAddr = (UINT32)IX_OSAL_MEM_MAP ( IXP400_TIMESYNCACC_PLREGS_BASEADDR, IXP400_TIMESYNCACC_PLREGS_MEMMAP_SIZE); if ((UINT32)NULL == plRegsVirtualBaseAddr) { /* Virtual memory mapping failed */ /* Unmap the virtual mapping of Block Level registers */ IX_OSAL_MEM_UNMAP(blRegsVirtualBaseAddr); return IX_FAIL; } /* end of if ((UINT32)NULL == plRegsVirtualBaseAddr) */ /* Virtual Addresses assignment for Block Level Registers */ ixTsRegisters.blRegisters.tsControl = blRegsVirtualBaseAddr + IXP400_TIMESYNCACC_TSC_OFFSET; ixTsRegisters.blRegisters.tsEvent = blRegsVirtualBaseAddr + IXP400_TIMESYNCACC_TSE_OFFSET; ixTsRegisters.blRegisters.tsAddend = blRegsVirtualBaseAddr + IXP400_TIMESYNCACC_ADD_OFFSET; ixTsRegisters.blRegisters.tsAccum = blRegsVirtualBaseAddr + IXP400_TIMESYNCACC_ACC_OFFSET; ixTsRegisters.blRegisters.tsSysTimeLo = blRegsVirtualBaseAddr + IXP400_TIMESYNCACC_STL_OFFSET; ixTsRegisters.blRegisters.tsSysTimeHi = blRegsVirtualBaseAddr + IXP400_TIMESYNCACC_STH_OFFSET; ixTsRegisters.blRegisters.tsTrgtLo = blRegsVirtualBaseAddr + IXP400_TIMESYNCACC_TTL_OFFSET; ixTsRegisters.blRegisters.tsTrgtHi = blRegsVirtualBaseAddr + IXP400_TIMESYNCACC_TTH_OFFSET; ixTsRegisters.blRegisters.tsASMSLo = blRegsVirtualBaseAddr + IXP400_TIMESYNCACC_ASSL_OFFSET; ixTsRegisters.blRegisters.tsASMSHi = blRegsVirtualBaseAddr + IXP400_TIMESYNCACC_ASSH_OFFSET; ixTsRegisters.blRegisters.tsAMMSLo = blRegsVirtualBaseAddr + IXP400_TIMESYNCACC_AMSL_OFFSET; ixTsRegisters.blRegisters.tsAMMSHi = blRegsVirtualBaseAddr + IXP400_TIMESYNCACC_AMSH_OFFSET; /* Virtual Addresses assignment for Port Level Registers */ for (ptpPortNum = 0; ptpPortNum < IXP400_TIMESYNCACC_MAX_1588PTP_PORT; ptpPortNum++) { ixTsRegisters.plRegisters[ptpPortNum].tsChControl = plRegsVirtualBaseAddr + IXP400_TIMESYNCACC_CC_OFFSET(ptpPortNum); ixTsRegisters.plRegisters[ptpPortNum].tsChEvent = plRegsVirtualBaseAddr + IXP400_TIMESYNCACC_CE_OFFSET(ptpPortNum); ixTsRegisters.plRegisters[ptpPortNum].tsTxSnapLo = plRegsVirtualBaseAddr + IXP400_TIMESYNCACC_XSL_OFFSET(ptpPortNum); ixTsRegisters.plRegisters[ptpPortNum].tsTxSnapHi = plRegsVirtualBaseAddr + IXP400_TIMESYNCACC_XSH_OFFSET(ptpPortNum); ixTsRegisters.plRegisters[ptpPortNum].tsRxSnapLo = plRegsVirtualBaseAddr + IXP400_TIMESYNCACC_RSL_OFFSET(ptpPortNum); ixTsRegisters.plRegisters[ptpPortNum].tsRxSnapHi = plRegsVirtualBaseAddr + IXP400_TIMESYNCACC_RSH_OFFSET(ptpPortNum); ixTsRegisters.plRegisters[ptpPortNum].tsSrcUUIDLo = plRegsVirtualBaseAddr + IXP400_TIMESYNCACC_UID_OFFSET(ptpPortNum); ixTsRegisters.plRegisters[ptpPortNum].tsSrcUUIDHi = plRegsVirtualBaseAddr + IXP400_TIMESYNCACC_SID_OFFSET(ptpPortNum); } /* end of for (ptpPortNum = 0; ptpPortNum < IXP400_TIMESYNCACC_MAX_1588PTP_PORT; ptpPortNum++ ) */ return IX_SUCCESS;} /* end of ixTimeSyncAccBlPlBaseAddressesSet() function *//* Function to perform the following for Initialsation Check * * - Check for the correct hardware platform * - NPE Port fused-out status * - Virtual Memory Map assignment */PRIVATE IxTimeSyncAccInitStatusixTimeSyncAccInitCheck (void){ /* Check for IXP46X device */ if(IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X != ixFeatureCtrlDeviceRead()) {#ifndef NDEBUG ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccInitCheck(): " "TimeSync not supported on this device\n", 0,0,0,0,0,0);#endif /* end of #ifndef NDEBUG */ return IXP400_TIMESYNCACC_INIT_TS_SUPPORT_FAIL; } /* end of if (IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X != ixFeatureCtrlDeviceRead()) */ /* * Secure mutex to protect the initialisation sequence so as to * avoid the possibility of two public APIs invoking this function * which can result in corruption of the memory mapping of virtual * addresses in the registers data structures. */ if (IX_SUCCESS != ixOsalMutexInit(&ixTsInitChkMutex)) { return IXP400_TIMESYNCACC_INIT_MUTEX_FAIL; } /* end of if (IX_SUCCESS != ixOsalMutexInit(&ixTsInitChkMutex)) */ if (IX_SUCCESS != ixOsalMutexLock(&ixTsInitChkMutex, IX_OSAL_WAIT_FOREVER)) { /* * Return failure without destroying the init mutex here * since, there is a possibility that task/thread switch * over after initialisation of the mutex before locking * the mutex. This allows the other task/thread to have * the initialisation sequence complete successfully and * will eventually release the mutex at the end of init. */ return IXP400_TIMESYNCACC_INIT_MUTEX_FAIL; } /* end of if (IX_SUCCESS != ixOsalMutexLock(&ixTsInitChkMutex, IX_OSAL_WAIT_FOREVER)) */ /* * Initialised before? * * NOTE: This would be possible, if multiple public APIs are invoked * where the initialisation condition is verified for FALSE but has * been subjected to context switch. Now other APIs completed the * initialisation successfully and updates the status to TRUE, but * the API which will resume later has the knowledge of FALSE status * only and enters this function and will still be able to make out * that the status now is TRUE as if it succeeded in initialisation * checks. */ if (TRUE == ixTs1588HardwareAssistEnabled) { /* Release the init mutex */ IXP400_TIMESYNCACC_MUTEX_RELEASE(ixTsInitChkMutex); return IXP400_TIMESYNCACC_INIT_SUCCESS; } /* end of (TRUE == ixTs1588HardwareAssistEnabled) */ /* * Check TimeSync/ECC Fuse-Out Status * * NOTE: Feature Control uses #define - IX_FEATURECTRL_ECC_TIMESYNC for * both the TimeSync and ECC feature of SDRAM Controller */ if (IX_FEATURE_CTRL_COMPONENT_ENABLED == ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ECC_TIMESYNC)) { /* Set Initialisation Check Status */ ixTs1588HardwareAssistEnabled = TRUE; } /* else of if (IX_FEATURE_CTRL_COMPONENT_ENABLED == ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ECC_TIMESYNC)) */ else { /* Release the init mutex */ IXP400_TIMESYNCACC_MUTEX_RELEASE(ixTsInitChkMutex); return IXP400_TIMESYNCACC_INIT_TS_DISABLED_FAIL; } /* end of if (IX_FEATURE_CTRL_COMPONENT_ENABLED == ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ECC_TIMESYNC)) */ /* * Initialise other mutexes */ if (IX_SUCCESS != ixOsalMutexInit(&ixTsSysTimeMutex)) { /* Release the init mutex */ IXP400_TIMESYNCACC_MUTEX_RELEASE(ixTsInitChkMutex); return IXP400_TIMESYNCACC_INIT_MUTEX_FAIL; } /* end of if (IX_SUCCESS != ixOsalMutexInit(&ixTsSysTimeMutex)) */ /* Update NPEs Fused-Out status */ if (IX_FEATURE_CTRL_COMPONENT_ENABLED == ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)) { ixTsNpeEnabled[IXP400_TIMESYNCACC_NPEA] = TRUE; } /* end of if (IX_FEATURE_CTRL_COMPONENT_ENABLED == ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)) */ if (IX_FEATURE_CTRL_COMPONENT_ENABLED == ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)) { ixTsNpeEnabled[IXP400_TIMESYNCACC_NPEB] = TRUE; } /* end of if (IX_FEATURE_CTRL_COMPONENT_ENABLED == ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)) */ if (IX_FEATURE_CTRL_COMPONENT_ENABLED == ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)) { ixTsNpeEnabled[IXP400_TIMESYNCACC_NPEC] = TRUE; } /* end of if (IX_FEATURE_CTRL_COMPONENT_ENABLED == ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)) */ /* Register the TimeSync Interrupt Service Routine */ if (IX_SUCCESS != ixOsalIrqBind((UINT32) IRQ_IXP400_INTC_TSYNC, (IxOsalVoidFnVoidPtr) ixTimeSyncAccIsr, (void *) NULL)) { /* Destroy the system time mutex */ ixOsalMutexDestroy(&ixTsSysTimeMutex); /* Release the init mutex */ IXP400_TIMESYNCACC_MUTEX_RELEASE(ixTsInitChkMutex); /* Reset Initialisation Check Status */ ixTs1588HardwareAssistEnabled = FALSE; return IXP400_TIMESYNCACC_INIT_ISR_BIND_FAIL; } /* end of if (IX_SUCCESS != ixOsalIrqBind((UINT32) IRQ_IXP400_INTC_TSYNC, (IxOsalVoidFnVoidPtr) ixTimeSyncAccIsr, (void *) NULL)) */ /* Assign memory mapped virtual addresses */ if (IX_SUCCESS != ixTimeSyncAccBlPlBaseAddressesSet()) { /* Destroy the system time mutex */ ixOsalMutexDestroy(&ixTsSysTimeMutex); /* Release the init mutex */ IXP400_TIMESYNCACC_MUTEX_RELEASE(ixTsInitChkMutex); /* Reset Initialisation Check Status */ ixTs1588HardwareAssistEnabled = FALSE; /* Deregister TimeSync Interrupt Service Routine */ ixOsalIrqUnbind((UINT32) IRQ_IXP400_INTC_TSYNC); return IXP400_TIMESYNCACC_INIT_MEM_ASGN_FAIL; } /* end of if (IX_SUCCESS != ixTimeSyncAccBlPlBaseAddressesSet()) */ /* Clear the snapshot availability condition for both master aux and slave aux */ ixTimeSyncAccEventAmmsFlagClear(); ixTimeSyncAccEventAsmsFlagClear(); /* Release the init mutex */ IXP400_TIMESYNCACC_MUTEX_RELEASE(ixTsInitChkMutex); return IXP400_TIMESYNCACC_INIT_SUCCESS;} /* end of ixTimeSyncAccInitCheck() function *//* Function to determine the port mode */PRIVATE IxTimeSyncAcc1588PTPPortModeixTimeSyncAccPTPPortModeGet(IxTimeSyncAcc1588PTPPort ptpPort){ /* Local variables */ BOOL masterMode = FALSE; BOOL allMsgMode = FALSE; IxTimeSyncAcc1588PTPPortMode ptpPortMode = IX_TIMESYNCACC_1588PTP_PORT_SLAVE; /* Get the Mode of the PTP Port */ masterMode = ixTimeSyncAccControlPTPPortMasterModeGet(ptpPort); allMsgMode = ixTimeSyncAccControlPTPPortPTPMsgTimestampGet(ptpPort); /* Is ANY mode (all message timestamp mode) on? */ if (FALSE == allMsgMode) { /* Is Master mode on? */ if (TRUE == masterMode) { ptpPortMode = IX_TIMESYNCACC_1588PTP_PORT_MASTER; } /* if (TRUE == masterMode) */ else { ptpPortMode = IX_TIMESYNCACC_1588PTP_PORT_SLAVE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -