📄 apcoam.c
字号:
/******************************************************************************* * * Copyright, 1996, Lucent Technologies, Inc. * * $Id: apcoam.c 1.56 2001/09/27 19:26:37 vikas1 Exp $ * * Description: This file contains functions which perform * OAM cell insertions in ingress and egress direction. * ******************************************************************************/#include "apcextrn.h"#include "apcoam.h"#include "apccram.h"ApcRtn_t apcReturnPMX(u8 devNum, INT pmx);/******************************************************************************//* PM Table Fields */VCTFields_t PMTblFields[] ={ { 0, 28, 0x10000000}, { 0, 27, 0x08000000}, { 0, 26, 0x04000000}, { 0, 25, 0x02000000}, { 0, 18, 0x01FC0000}, { 0, 16, 0x00030000}};/********************************************************************************************************* * * Function Name: ApcRtn_t apcWaitforBGprocess(u8 devNum, u8 mphyPort) * * Description: Obtain maximum window between the times BG process * visits the processing of entries corresponding to the * MPHY. The LUT1Busy bit would indicate whether the * BG process is done with the LU tables corresponding to * a certain MPHY. * * Return Value: Error/Success flag. * * Side Effects: none. * * Considerations: Context switch should be prevented by disabling the interrupts. * ********************************************************************************************************/ApcRtn_tapcWaitforBGprocess(u8 devNum, u8 mphyPort){ u32 cnt1, cnt2, cnt3; u32 bgTSC, oldTSC; /* Initializing the counters to non-zero value to prevent it from returning an error */ cnt1 = cnt2 = cnt3 = 1; if (mphyPort == 0) { oldTSC = apcReadRegister(devNum, RCFIG13); for (cnt1 = APC_1_SEC_DELAY; cnt1 > 0 ; cnt1--) { bgTSC = apcReadRegister(devNum, rBGTSC) & 0x1FFFFF; if (bgTSC >= oldTSC) break; oldTSC = bgTSC; } } else { for (cnt1 = APC_1_SEC_DELAY; cnt1 > 0 ; cnt1--) { if ((apcReadRegister(devNum, rBGLUX1) & 0x1F) == (mphyPort-1)) break; } for (cnt2 = APC_1_SEC_DELAY; cnt2 > 0 ; cnt2--) { if ((apcReadRegister(devNum, rBGLUX1) & 0x1F) == mphyPort) break; } } for (cnt3 = APC_1_SEC_DELAY; cnt3 > 0 ; cnt3--) { if ((apcReadRegister(devNum, rBGLUX1) & 0x1F) != mphyPort) break; } if ((cnt1 == 0) || (cnt2 == 0) || (cnt3 == 0)) return APC_BG_TIMEOUT_ERROR; return APC_SUCCESS;}u32apcReadCRAMselectiveFix(u8 devNum, u32 cramAddr, ApcCRAMupdateMode_t updateMode){ u32 cfg2Val; u8 oamEnabled; cfg2Val = apcReadRegister(devNum, RCFIG2); oamEnabled = GET_FIELD(apcReadRegister(devNum, RCFIG5), ENOAMP_MASK, ENOAMP_SHFT); if ((cfg2Val & 0x1) && (oamEnabled)) { return apcReadCRAMselective(devNum, cramAddr, updateMode); } return apcReadCRAM(devNum, cramAddr);}ApcRtn_tapcWriteCRAMselectiveFix(u8 devNum, u32 cramAddr, u32 data, u8 mphy){ u32 cfg2Val; u8 oamEnabled; ApcRtn_t retval; cfg2Val = apcReadRegister(devNum, RCFIG2); oamEnabled = GET_FIELD(apcReadRegister(devNum, RCFIG5), ENOAMP_MASK, ENOAMP_SHFT); if ((cfg2Val & 0x1) && (oamEnabled)) { /* Check whether the chip version is less than 3e */ if (Version[devNum] <= 6) { retval = apcWaitforBGprocess(devNum, mphy); if (retval == APC_BG_TIMEOUT_ERROR) return APC_BG_TIMEOUT_ERROR; } apcWriteCRAMselective(devNum, cramAddr, data); return SUCCESS; } apcWriteCRAM(devNum, cramAddr, data); return APC_SUCCESS; }ApcRtn_tcheckSpaceinIIQ(u8 devNum){ u32 stat3; stat3 = apcReadStat3(devNum); if (stat3 & STAT3_IIRQ_FULL) return APC_NO_SPACE_IIQ; else return APC_SUCCESS;}/******************************************************************************/ApcRtn_tcheckSpaceinEIQ(u8 devNum){ u32 stat3; stat3 = apcReadStat3(devNum); if (stat3 & STAT3_EIRQ_FULL) return APC_NO_SPACE_EIQ; else return APC_SUCCESS;}/******************************************************************************* * * Function Name: ApcRtn_t apcSendIngressOAMcell (InsIngressOAMInfo_t *iInsOAMcell) * * Description: To insert an AIS cell (F4 or F5 flow) into the ingress stream * for a particular connection indicating local defect type. * * Return Value: Error/Success flag. * * Side Effects: none. * * Special Considerations: none. * ******************************************************************************/ApcRtn_tapcSendIngressOAMcell(InsIngressOAMInfo_t *iInsOAMcell){ u32 iiqWord = 0; if (APC_NO_SPACE_IIQ == checkSpaceinIIQ(iInsOAMcell->devNum)) return APC_NO_SPACE_IIQ; /* insert an oam cell into ingress stream */ SET_FIELD(iiqWord, iInsOAMcell->fmDefectType, IIQFMD_MASK, IIQFMD_SHFT); SET_FIELD(iiqWord, iInsOAMcell->insertedCellType, IIQICT_MASK, IIQICT_SHFT); SET_FIELD(iiqWord, iInsOAMcell->oamFlowType, IIQOAF_MASK, IIQOAF_SHFT); SET_FIELD(iiqWord, iInsOAMcell->ingressLUT3Index, IIQIL3_MASK, IIQIL3_SHFT); apcWriteRegister(iInsOAMcell->devNum, rIIQ_REG_0, iiqWord); return APC_SUCCESS;}/******************************************************************************* * * Function Name: ApcRtn_t apcSendEgressOAMcell (InsEgressOAMInfo_t *eInsOAMcell) * * Description: Call to perform the following: * To insert an AIS cell to a MPHY port to forward AIS fault * detection. * To insert an backward RDI cell into the egress stream to a MPHY port. * To insert an forward PM cell into the egress stream to a MPHY port. * To insert an CC cell into the egress stream to a MPHY port. * * Return Value: Error/Success flag. * * Side Effects: none. * * Special Considerations: none. * ******************************************************************************/ApcRtn_tapcSendEgressOAMcell(InsEgressOAMInfo_t *eInsOAMcell){ u32 eiqWord = 0; if (APC_NO_SPACE_EIQ == checkSpaceinEIQ(eInsOAMcell->devNum)) return APC_NO_SPACE_EIQ; /* insert an oam cell into egress stream */ SET_FIELD(eiqWord, eInsOAMcell->fmDefectType, EIQFMD_MASK, EIQFMD_SHFT); SET_FIELD(eiqWord, eInsOAMcell->egressMPHY, EIQEPY_MASK, EIQEPY_SHFT); SET_FIELD(eiqWord, eInsOAMcell->insertedCellType, EIQICT_MASK, EIQICT_SHFT); SET_FIELD(eiqWord, eInsOAMcell->egressVCX, EIQEVX_MASK, EIQEVX_SHFT); apcWriteRegister(eInsOAMcell->devNum, rEIQ_REG_0, eiqWord); return APC_SUCCESS;}/******************************************************************************* * * Function Name: INT apcGetLUT3OAMField(u8 devNum, int OAM_Field, u32 lut3Addr) * * Description: Call to get the value of the OAM_Field in the LUT3 OAM entry * * Return: LUT3OAMField * Special Consideration: the lut3Addr should point to the oamentry, which is LUX3 * (found by apcGetIngressLUT333_VCX ) +1. ******************************************************************************/INTapcGetLUT3OAMField( u8 devNum, int oam_field, u32 lut3Addr){ u32 lut3OamEntry; LUT3_OAM_t lut3oam; lut3OamEntry = apcReadCRAM(devNum, apcLUT3BaseAddr[devNum]+lut3Addr); APC_GET_LUT3_OAM(lut3oam, lut3OamEntry); switch (oam_field) { case LUT3_OAME2E: return lut3oam.oam_e2e; case LUT3_OAMSEG: return lut3oam.oam_seg; case LUT3_FMSTATE: return lut3oam.fm_state; case LUT3_FMDEFTYP: return lut3oam.fm_deftype; case LUT3_FMTIMER: return lut3oam.timer; default: return -1; }}/******************************************************************************* * * Function Name: INT apcGetIVTOAMField(u8 devNum, int IVT_Field, VCIndex vcEntry) * * Description: Call this function to get the IVT OAM fields * * Return: IVTField * ******************************************************************************/INTapcGetIVTOAMField( u8 devNum, int IVT_Field, VCIndex_t vcEntry){ u32 data[MAX_IVT_WORDS]; IngVCTEntry_t ivt; apcReadIVTWords(devNum, vcEntry, data); apcGetIVTFields(data, &ivt); switch (IVT_Field) { case FMSTATE: return ivt.word4.fm_state; case FMDEFTYP: return ivt.word4.fm_deftype; case CCSINK: return ivt.word4.cc_sink; case CCSOURCE: return ivt.word4.cc_src; default: return -1; }}/******************************************************************************* * * Function Name: ApcRtn_t apcSetOAMCellCapture(OAMBadCellTypes_t *pOAMCellTypes) * * Description: Call to enable/disable OAM capture for unsupported or * undefined OAM cells (set in rCfig2) * ******************************************************************************/ApcRtn_tapcSetOAMCellCapture(u8 devNum, OAMBadCellTypes_t *pOAMCellTypes, int flag){ u32 cfg2; cfg2 = apcReadRegister(devNum, RCFIG2); /* if pOAMCellTypes == unsupported, set ?? in rCfig2 */ if (pOAMCellTypes->ccorrupt) { SET_FIELD(cfg2, flag, ENPERC_MASK, ENPERC_SHFT); } if (pOAMCellTypes->cunsupported) { SET_FIELD(cfg2, flag, ENUSOC_MASK, ENUSOC_SHFT); } /* if pOAMCellTypes == undefined, set ?? in rCfig2 */ if (pOAMCellTypes->cundefined) { SET_FIELD(cfg2, flag, ENUDOC_MASK, ENUDOC_SHFT); } apcWriteRegister(devNum, RCFIG2, cfg2); return APC_SUCCESS;}/******************************************************************************* * * Function Name: ApcRtn_t apcEnableOAMContinuityCheck(OAMCCInfo_t *ccInfo) * * Description: Call to enable Continuity Check upon notification * from deactivation/activation cells. This is * called by the application. * * Set the ccsink, ccsink, ccsource, and ccflowtype * * Return Value: Error/Success flag. * * Side Effects: none. * * Special Considerations: the lut3Addr should point to the oamentry, which is the lux3 (found * by apcGetIngressLUT3_VCX) + 1. ******************************************************************************/ApcRtn_tapcEnableOAMContinuityCheck(OAMCCInfo_t *ccInfo, u32 lut3Addr){ u8 devNum = ccInfo->devNum; u8 connType; u32 lut2Entry, lut2Addr; u32 lut3OamEntry; LUT3_OAM_t lut3oam; ApcRtn_t retval; lut2Addr = APC_LUT2_INDEX(devNum,ccInfo->mphy,ccInfo->vpi); lut2Entry = APC_RD_LUT2_ENTRY(devNum,ccInfo->mphy,ccInfo->vpi); /* connection type - if S == 0 -> VC switched */ connType = ((lut2Entry & APC_LUT2_S_VPC) ? APC_VP_FLAG : APC_VC_FLAG); /* check switching and vci 3/4, write to IVT or OAM entry */ if (connType == APC_VC_FLAG && (ccInfo->vci == F4_SEG_VCI || ccInfo->vci == F4_E2E_VCI)) { /* this Read sets Selective Update mode for subsequent Write */ lut3OamEntry = apcReadCRAMselectiveFix(devNum, apcLUT3BaseAddr[devNum]+lut3Addr, ApcLUT3OAMselectiveUpdate); APC_GET_LUT3_OAM(lut3oam, lut3OamEntry); lut3oam.cc_ftype = ccInfo->ccflowtype; lut3oam.cc_sink = ccInfo->ccsink; lut3oam.cc_src = ccInfo->ccsource; lut3OamEntry = APC_LUT3_OAM(lut3oam); /* write back to CRAM (lut3oam) */ /* this Write clears Selective Update mode */ retval = apcWriteCRAMselectiveFix(devNum, apcLUT3BaseAddr[devNum]+lut3Addr, lut3OamEntry, ccInfo->mphy); return retval; } else { /* Write the CCSink and CCSource to the IVT */ apcWriteConnInfo_Ing(devNum, ccInfo->vcx, ccInfo->ccsink, CCSINK); apcWriteConnInfo_Ing(devNum, ccInfo->vcx, ccInfo->ccsource, CCSOURCE); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -