/** * * A New Announce Packet has been received. We need to decode it and rerun the * Best Master Clock Algorithm (BMCA) * * @param InstancePtr is a pointer to the XAvb instance to be worked on * @param PtpFrameBaseAddr is the base address of the received Announce Packet * in the Rx PTP Packet Buffer * * @return None. But an updated True/False decision as to whether this device * should operate as a clock master or a slave is written into the * CurrentBmc data structure. * * @note None. * *****************************************************************************/ void XAvb_DecodeRxAnnounceFrame(XAvb * InstancePtr, u32 PtpFrameBaseAddr) { u32 NewMaster = 0; XAvb_BmcData RxAnnounceFrame; /** Read the attributes for the new Announce frame received */ XAvb_ReadAnnounceFrame(InstancePtr->Config.BaseAddress, PtpFrameBaseAddr, &RxAnnounceFrame); /** If the received packet's clockIdentity matches our * clockIdentity, ignore the packet */ if( XAvb_ComparePortIdentity(InstancePtr->Config.BaseAddress, InstancePtr->portIdLocal, RxAnnounceFrame.SourcePortIdentity) ) { xil_printf("Got an announce from myself.. ignoring\r\n"); return; } /** If the received packet's stepsRemoved field is >= 255, * ignore the packet */ if( RxAnnounceFrame.stepsRemoved >= 255 ) { xil_printf("Got an announce with stepsRemoved > 255.. ignoring\r\n"); return; } /** If the Announce packet's GMID matches that of our current GM * record, then update its records based on the current packet, * just in case something (such as priority) has changed. */ if( XAvb_CompareClockIdentity(InstancePtr->Config.BaseAddress, RxAnnounceFrame.GrandmasterIdentity, InstancePtr->CurrentBmc.GrandmasterIdentity) ) { /** update timeout information */ InstancePtr->PtpCounters.CounterAnnounceInterval = 0; XAvb_UpdateBmcRecords(&RxAnnounceFrame, &InstancePtr->CurrentBmc); /** Compare against this device's information to see if we should be GM */ XAvb_DecodeTxAnnounceFrame(InstancePtr); } else if( InstancePtr->CurrentBmc.IAmTheRtcMaster ) { /** run BMCA on this announce to see if it is better than me */ NewMaster = XAvb_BestMasterClockAlgorithm(&RxAnnounceFrame, &InstancePtr->CurrentBmc); if (NewMaster == 1) { /** Update records with the NEW best master */ XAvb_UpdateBmcRecords(&RxAnnounceFrame, &InstancePtr->CurrentBmc); /** Capture the Announce Receipt Timeout Interval. * Reset the announce receipt timeout interval to use the new value. */ XAvb_ReadAnnounceReceiptTimeout(InstancePtr->Config.BaseAddress, PtpFrameBaseAddr, &RxAnnounceFrame); InstancePtr->CurrentBmc.AnnounceIntervalDuration = XAvb_ConvertLogMeanToDuration(RxAnnounceFrame.logMessageInterval); #ifdef DEBUG_XAVB_LEVEL1 xil_printf("\r\r\nXAvb_DecodeRxAnnounceFrame()"); xil_printf("\r\n-----------------------"); xil_printf("\r\nWinning Announce Frame"); xil_printf("\r\n-----------------------"); xil_printf("\r\nGM ID upper %x", InstancePtr->CurrentBmc.GrandmasterIdentity.ClockIdentityUpper); xil_printf("\r\nGM ID lower %x", InstancePtr->CurrentBmc.GrandmasterIdentity.ClockIdentityLower); xil_printf("\r\nPriority1 %x", InstancePtr->CurrentBmc.GrandmasterPriority1); xil_printf("\r\nclockClass %x", InstancePtr->CurrentBmc.ClockQuality.clockClass); xil_printf("\r\nPriority2 %x", InstancePtr->CurrentBmc.GrandmasterPriority2); #endif /** New Rx Announce Packet has won - so this device cannot be a master */ xil_printf("\r\n* XAvb_DecodeRxAnnounceFrame()::BMC : I am a SLAVE"); XAvb_BecomeRtcSlave(InstancePtr); } } }
/** * * This function resets all of the AVB device driver functions to the start-up * (reset) defaults. * * @param InstancePtr is a pointer to the Xavb instance to be worked on. * * @return None. * * @note None. * ******************************************************************************/ void XAvb_Reset(XAvb * InstancePtr) { /** Assert bad arguments and conditions */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /** * Perform a Software Reset of the AVB Core. * This will reset both the transmitter and receiver paths. * The RTC counter is not reset here. */ XAvb_WriteReg(InstancePtr->Config.BaseAddress, XAVB_SW_RESET_OFFSET, XAVB_SW_RESET_TX_AND_RX_PATHS); /** * Set IEEE specification default values in the device's data structure */ xil_printf("\r\n*** XAvb_Reset() : Call XAvb_BecomeRtcMaster() *** \r\n"); XAvb_BecomeRtcMaster(InstancePtr,0); XAvb_ChangePeerASCapability(InstancePtr, 0); InstancePtr->PtpIsRunning = 0; InstancePtr->PtpRecords.LinkDelay = 0; InstancePtr->SignallingFrameData.SyncIntervalDuration = XAvb_ConvertLogMeanToDuration(XAVB_DEFAULT_LOG_MEAN_SYNC_INTERVAL); InstancePtr->SignallingFrameData.LinkDelayIntervalDuration = XAvb_ConvertLogMeanToDuration(XAVB_DEFAULT_LOG_MEAN_PDELAY_REQ_INTERVAL); InstancePtr->SignallingFrameData.AnnounceIntervalDuration = XAvb_ConvertLogMeanToDuration(XAVB_DEFAULT_LOG_MEAN_ANNOUNCE_INTERVAL); InstancePtr->latestMDSyncReceive.SyncIntervalDuration = XAvb_ConvertLogMeanToDuration(XAVB_DEFAULT_LOG_MEAN_SYNC_INTERVAL); /** Update logMeanMessageInterval in the pre-loaded TX SYNC message buffer */ XAvb_UpdateLogMeanMessageInterval(InstancePtr->Config.BaseAddress, XAVB_PTP_TX_SYNC_OFFSET, InstancePtr->SignallingFrameData.SyncIntervalDuration); /** Update logMeanMessageInterval in the pre-loaded TX FOLLOW_UP message buffer */ XAvb_UpdateLogMeanMessageInterval(InstancePtr->Config.BaseAddress, XAVB_PTP_TX_FOLLOW_UP_OFFSET, InstancePtr->SignallingFrameData.SyncIntervalDuration); /** Update logMeanMessageInterval in the pre-loaded TX PDELAYREQ message buffer */ XAvb_UpdateLogMeanMessageInterval(InstancePtr->Config.BaseAddress, XAVB_PTP_TX_PDELAYREQ_OFFSET, InstancePtr->SignallingFrameData.LinkDelayIntervalDuration); /** Update logMeanMessageInterval in the pre-loaded TX ANNOUNCE message buffer */ XAvb_UpdateLogMeanMessageInterval(InstancePtr->Config.BaseAddress, XAVB_PTP_TX_ANNOUNCE_OFFSET, InstancePtr->SignallingFrameData.AnnounceIntervalDuration); /** * Initialise other driver variables in the device's data structure */ InstancePtr->PtpCounters.RxPtpHardPointer = 0; InstancePtr->PtpCounters.RxPtpSoftPointer = 0xFF; InstancePtr->PtpCounters.CounterSyncInterval = 0; InstancePtr->PtpCounters.CounterLinkDelayInterval = 0; InstancePtr->PtpCounters.CounterAnnounceInterval = 0; InstancePtr->PtpCounters.CounterSyncEvents = 0; InstancePtr->StateMachineData.lostResponses = 0; InstancePtr->StateMachineData.rcvdPDelayResp = 0; InstancePtr->StateMachineData.rcvdPDelayRespFollowUp = 0; #ifdef DEBUG_XAVB_LEVEL1 xil_printf("\r\n** XAvb_Reset(): PTP Driver Reset **"); #endif }