void pp_timeout_rand(struct pp_instance *ppi, int index, int logval) { static uint32_t seed; uint32_t rval; int millisec; if (!seed) { uint32_t *p; /* use the least 32 bits of the mac address as seed */ p = (void *)(&DSDEF(ppi)->clockIdentity) + sizeof(ClockIdentity) - 4; seed = *p; } /* From uclibc: they make 11 + 10 + 10 bits, we stop at 21 */ seed *= 1103515245; seed += 12345; rval = (unsigned int) (seed / 65536) % 2048; seed *= 1103515245; seed += 12345; rval <<= 10; rval ^= (unsigned int) (seed / 65536) % 1024; millisec = (1 << logval) * 400; /* This is 40% of the nominal value */ millisec = (millisec * 2) + rval % millisec; pp_timeout_set(ppi, index, millisec); }
int wr_s_lock(struct pp_instance *ppi, unsigned char *pkt, int plen) { struct wr_dsport *wrp = WR_DSPOR(ppi); int enable = 0; if (ppi->is_new_state) { wrp->wrStateRetry = WR_STATE_RETRY; enable = 1; } else if (pp_timeout_z(ppi, PP_TO_EXT_0)) { wrp->ops->locking_disable(ppi); if (wr_handshake_retry(ppi)) enable = 1; else return 0; /* non-wr already */ } if (enable) { wrp->ops->locking_enable(ppi); pp_timeout_set(ppi, PP_TO_EXT_0, WR_S_LOCK_TIMEOUT_MS); } if (wrp->ops->locking_poll(ppi, 0) == WR_SPLL_READY) { ppi->next_state = WRS_LOCKED; wrp->ops->locking_disable(ppi); } ppi->next_delay = wrp->wrStateTimeout; return 0; }
/* * We enter here from WRS_CALIBRATION. If master we wait for * a CALIBRATE message, if slave we wait for LINK_ON. */ int wr_calibrated(struct pp_instance *ppi, unsigned char *pkt, int plen) { struct wr_dsport *wrp = WR_DSPOR(ppi); MsgSignaling wrsig_msg; if (ppi->is_new_state) pp_timeout_set(ppi, PP_TO_EXT_0, wrp->wrStateTimeout); if (pp_timeout_z(ppi, PP_TO_EXT_0)) { /* * FIXME: We should implement a retry by re-sending * the "calibrated" message, moving it here from the * previous state (sub-state 8 of "state-wr-calibration" */ wr_handshake_fail(ppi); return 0; /* non-wr */ } if (plen == 0) goto out; if (ppi->received_ptp_header.messageType == PPM_SIGNALING) { msg_unpack_wrsig(ppi, pkt, &wrsig_msg, &(wrp->msgTmpWrMessageID)); if ((wrp->msgTmpWrMessageID == CALIBRATE) && (wrp->wrMode == WR_MASTER)) ppi->next_state = WRS_RESP_CALIB_REQ; else if ((wrp->msgTmpWrMessageID == WR_MODE_ON) && (wrp->wrMode == WR_SLAVE)) ppi->next_state = WRS_WR_LINK_ON; } out: ppi->next_delay = wrp->wrStateTimeout; return 0; }