154359Sroberto/******************************************************************************
254359Sroberto *                                                                            *
354359Sroberto * Copyright (c) David L. Mills 1993, 1994                                    *
454359Sroberto *                                                                            *
554359Sroberto * Permission to use, copy, modify, and distribute this software and its      *
654359Sroberto * documentation for any purpose and without fee is hereby granted, provided  *
754359Sroberto * that the above copyright notice appears in all copies and that both the    *
854359Sroberto * copyright notice and this permission notice appear in supporting           *
954359Sroberto * documentation, and that the name University of Delaware not be used in     *
1054359Sroberto * advertising or publicity pertaining to distribution of the software        *
1154359Sroberto * without specific, written prior permission.  The University of Delaware    *
1254359Sroberto * makes no representations about the suitability this software for any       *
1354359Sroberto * purpose.  It is provided "as is" without express or implied warranty.      *
1454359Sroberto *                                                                            *
1554359Sroberto ******************************************************************************/
1654359Sroberto
1754359Sroberto/*
1854359Sroberto * Modification history timex.h
1954359Sroberto *
2054359Sroberto * 26 Sep 94	David L. Mills
2154359Sroberto *	Added defines for hybrid phase/frequency-lock loop.
2254359Sroberto *
2354359Sroberto * 19 Mar 94	David L. Mills
2454359Sroberto *	Moved defines from kernel routines to header file and added new
2554359Sroberto *	defines for PPS phase-lock loop.
2654359Sroberto *
2754359Sroberto * 20 Feb 94	David L. Mills
2854359Sroberto *	Revised status codes and structures for external clock and PPS
2954359Sroberto *	signal discipline.
3054359Sroberto *
3154359Sroberto * 28 Nov 93	David L. Mills
3254359Sroberto *	Adjusted parameters to improve stability and increase poll
3354359Sroberto *	interval.
3454359Sroberto *
3554359Sroberto * 17 Sep 93    David L. Mills
3654359Sroberto *      Created file
3754359Sroberto */
3854359Sroberto/*
3954359Sroberto * This header file defines the Network Time Protocol (NTP) interfaces
4054359Sroberto * for user and daemon application programs. These are implemented using
4154359Sroberto * private syscalls and data structures and require specific kernel
4254359Sroberto * support.
4354359Sroberto *
4454359Sroberto * NAME
4554359Sroberto *	ntp_gettime - NTP user application interface
4654359Sroberto *
4754359Sroberto * SYNOPSIS
4854359Sroberto *	#include <sys/timex.h>
4954359Sroberto *
5054359Sroberto *	int syscall(SYS_ntp_gettime, tptr)
5154359Sroberto *
5254359Sroberto *	int SYS_ntp_gettime		defined in syscall.h header file
5354359Sroberto *	struct ntptimeval *tptr		pointer to ntptimeval structure
5454359Sroberto *
5554359Sroberto * NAME
5654359Sroberto *	ntp_adjtime - NTP daemon application interface
5754359Sroberto *
5854359Sroberto * SYNOPSIS
5954359Sroberto *	#include <sys/timex.h>
6054359Sroberto *
6154359Sroberto *	int syscall(SYS_ntp_adjtime, mode, tptr)
6254359Sroberto *
6354359Sroberto *	int SYS_ntp_adjtime		defined in syscall.h header file
6454359Sroberto *	struct timex *tptr		pointer to timex structure
6554359Sroberto *
6654359Sroberto */
6754359Sroberto#ifndef _SYS_TIMEX_H_
6854359Sroberto#define _SYS_TIMEX_H_ 1
6954359Sroberto
7054359Sroberto#ifndef MSDOS			/* Microsoft specific */
7154359Sroberto#include <sys/syscall.h>
7254359Sroberto#endif /* MSDOS */
7354359Sroberto
7454359Sroberto/*
7554359Sroberto * The following defines establish the engineering parameters of the
7654359Sroberto * phase-lock loop (PLL) model used in the kernel implementation. These
7754359Sroberto * parameters have been carefully chosen by analysis for good stability
7854359Sroberto * and wide dynamic range.
7954359Sroberto *
8054359Sroberto * The hz variable is defined in the kernel build environment. It
8154359Sroberto * establishes the timer interrupt frequency, 100 Hz for the SunOS
8254359Sroberto * kernel, 256 Hz for the Ultrix kernel and 1024 Hz for the OSF/1
8354359Sroberto * kernel. SHIFT_HZ expresses the same value as the nearest power of two
8454359Sroberto * in order to avoid hardware multiply operations.
8554359Sroberto *
8654359Sroberto * SHIFT_KG and SHIFT_KF establish the damping of the PLL and are chosen
8754359Sroberto * for a slightly underdamped convergence characteristic. SHIFT_KH
8854359Sroberto * establishes the damping of the FLL and is chosen by wisdom and black
8954359Sroberto * art.
9054359Sroberto *
9154359Sroberto * MAXTC establishes the maximum time constant of the PLL. With the
9254359Sroberto * SHIFT_KG and SHIFT_KF values given and a time constant range from
9354359Sroberto * zero to MAXTC, the PLL will converge in 15 minutes to 16 hours,
9454359Sroberto * respectively.
9554359Sroberto */
9654359Sroberto#define SHIFT_HZ 7		/* log2(hz) */
9754359Sroberto#define SHIFT_KG 6		/* phase factor (shift) */
9854359Sroberto#define SHIFT_KF 16		/* PLL frequency factor (shift) */
9954359Sroberto#define SHIFT_KH 2		/* FLL frequency factor (shift) */
10054359Sroberto#define MAXTC 6			/* maximum time constant (shift) */
10154359Sroberto
10254359Sroberto/*
10354359Sroberto * The following defines establish the scaling of the various variables
10454359Sroberto * used by the PLL. They are chosen to allow the greatest precision
10554359Sroberto * possible without overflow of a 32-bit word.
10654359Sroberto *
10754359Sroberto * SHIFT_SCALE defines the scaling (shift) of the time_phase variable,
10854359Sroberto * which serves as a an extension to the low-order bits of the system
10954359Sroberto * clock variable time.tv_usec.
11054359Sroberto *
11154359Sroberto * SHIFT_UPDATE defines the scaling (shift) of the time_offset variable,
11254359Sroberto * which represents the current time offset with respect to standard
11354359Sroberto * time.
11454359Sroberto *
11554359Sroberto * SHIFT_USEC defines the scaling (shift) of the time_freq and
11654359Sroberto * time_tolerance variables, which represent the current frequency
11754359Sroberto * offset and maximum frequency tolerance.
11854359Sroberto *
11954359Sroberto * FINEUSEC is 1 us in SHIFT_UPDATE units of the time_phase variable.
12054359Sroberto */
12154359Sroberto#define SHIFT_SCALE 22		/* phase scale (shift) */
12254359Sroberto#define SHIFT_UPDATE (SHIFT_KG + MAXTC) /* time offset scale (shift) */
12354359Sroberto#define SHIFT_USEC 16		/* frequency offset scale (shift) */
12454359Sroberto#define FINEUSEC (1L << SHIFT_SCALE) /* 1 us in phase units */
12554359Sroberto
12654359Sroberto/*
12754359Sroberto * The following defines establish the performance envelope of the PLL.
12854359Sroberto * They insure it operates within predefined limits, in order to satisfy
12954359Sroberto * correctness assertions. An excursion which exceeds these bounds is
13054359Sroberto * clamped to the bound and operation proceeds accordingly. In practice,
13154359Sroberto * this can occur only if something has failed or is operating out of
13254359Sroberto * tolerance, but otherwise the PLL continues to operate in a stable
13354359Sroberto * mode.
13454359Sroberto *
13554359Sroberto * MAXPHASE must be set greater than or equal to CLOCK.MAX (128 ms), as
13654359Sroberto * defined in the NTP specification. CLOCK.MAX establishes the maximum
13754359Sroberto * time offset allowed before the system time is reset, rather than
13854359Sroberto * incrementally adjusted. Here, the maximum offset is clamped to
13954359Sroberto * MAXPHASE only in order to prevent overflow errors due to defective
14054359Sroberto * protocol implementations.
14154359Sroberto *
14254359Sroberto * MAXFREQ is the maximum frequency tolerance of the CPU clock
14354359Sroberto * oscillator plus the maximum slew rate allowed by the protocol. It
14454359Sroberto * should be set to at least the frequency tolerance of the oscillator
14554359Sroberto * plus 100 ppm for vernier frequency adjustments. If the kernel
14654359Sroberto * PPS discipline code is configured (PPS_SYNC), the oscillator time and
14754359Sroberto * frequency are disciplined to an external source, presumably with
14854359Sroberto * negligible time and frequency error relative to UTC, and MAXFREQ can
14954359Sroberto * be reduced.
15054359Sroberto *
15154359Sroberto * MAXTIME is the maximum jitter tolerance of the PPS signal if the
15254359Sroberto * kernel PPS discipline code is configured (PPS_SYNC).
15354359Sroberto *
15454359Sroberto * MINSEC and MAXSEC define the lower and upper bounds on the interval
15554359Sroberto * between protocol updates.
15654359Sroberto */
15754359Sroberto#define MAXPHASE 512000L	/* max phase error (us) */
15854359Sroberto#ifdef PPS_SYNC
15954359Sroberto#define MAXFREQ (512L << SHIFT_USEC) /* max freq error (100 ppm) */
16054359Sroberto#define MAXTIME (200L << PPS_AVG) /* max PPS error (jitter) (200 us) */
16154359Sroberto#else
16254359Sroberto#define MAXFREQ (512L << SHIFT_USEC) /* max freq error (200 ppm) */
16354359Sroberto#endif /* PPS_SYNC */
16454359Sroberto#define MINSEC 16L		/* min interval between updates (s) */
16554359Sroberto#define MAXSEC 1200L		/* max interval between updates (s) */
16654359Sroberto
16754359Sroberto#ifdef PPS_SYNC
16854359Sroberto/*
16954359Sroberto * The following defines are used only if a pulse-per-second (PPS)
17054359Sroberto * signal is available and connected via a modem control lead, such as
17154359Sroberto * produced by the optional ppsclock feature incorporated in the Sun
17254359Sroberto * asynch driver. They establish the design parameters of the frequency-
17354359Sroberto * lock loop used to discipline the CPU clock oscillator to the PPS
17454359Sroberto * signal.
17554359Sroberto *
17654359Sroberto * PPS_AVG is the averaging factor for the frequency loop, as well as
17754359Sroberto * the time and frequency dispersion.
17854359Sroberto *
17954359Sroberto * PPS_SHIFT and PPS_SHIFTMAX specify the minimum and maximum
18054359Sroberto * calibration intervals, respectively, in seconds as a power of two.
18154359Sroberto *
18254359Sroberto * PPS_VALID is the maximum interval before the PPS signal is considered
18354359Sroberto * invalid and protocol updates used directly instead.
18454359Sroberto *
18554359Sroberto * MAXGLITCH is the maximum interval before a time offset of more than
18654359Sroberto * MAXTIME is believed.
18754359Sroberto */
18854359Sroberto#define PPS_AVG 2		/* pps averaging constant (shift) */
18954359Sroberto#define PPS_SHIFT 2		/* min interval duration (s) (shift) */
19054359Sroberto#define PPS_SHIFTMAX 8		/* max interval duration (s) (shift) */
19154359Sroberto#define PPS_VALID 120		/* pps signal watchdog max (s) */
19254359Sroberto#define MAXGLITCH 30		/* pps signal glitch max (s) */
19354359Sroberto#endif /* PPS_SYNC */
19454359Sroberto
19554359Sroberto/*
19654359Sroberto * The following defines and structures define the user interface for
19754359Sroberto * the ntp_gettime() and ntp_adjtime() system calls.
19854359Sroberto *
19954359Sroberto * Control mode codes (timex.modes)
20054359Sroberto */
20154359Sroberto#define MOD_OFFSET	0x0001	/* set time offset */
20254359Sroberto#define MOD_FREQUENCY	0x0002	/* set frequency offset */
20354359Sroberto#define MOD_MAXERROR	0x0004	/* set maximum time error */
20454359Sroberto#define MOD_ESTERROR	0x0008	/* set estimated time error */
20554359Sroberto#define MOD_STATUS	0x0010	/* set clock status bits */
20654359Sroberto#define MOD_TIMECONST	0x0020	/* set pll time constant */
20754359Sroberto#define MOD_CANSCALE	0x0040	/* kernel can scale offset field */
20854359Sroberto#define MOD_DOSCALE	0x0080	/* userland wants to scale offset field */
20954359Sroberto
21054359Sroberto/*
21154359Sroberto * Status codes (timex.status)
21254359Sroberto */
21354359Sroberto#define STA_PLL		0x0001	/* enable PLL updates (rw) */
21454359Sroberto#define STA_PPSFREQ	0x0002	/* enable PPS freq discipline (rw) */
21554359Sroberto#define STA_PPSTIME	0x0004	/* enable PPS time discipline (rw) */
21654359Sroberto#define STA_FLL		0x0008	/* select frequency-lock mode (rw) */
21754359Sroberto
21854359Sroberto#define STA_INS		0x0010	/* insert leap (rw) */
21954359Sroberto#define STA_DEL		0x0020	/* delete leap (rw) */
22054359Sroberto#define STA_UNSYNC	0x0040	/* clock unsynchronized (rw) */
22154359Sroberto#define STA_FREQHOLD	0x0080	/* hold frequency (rw) */
22254359Sroberto
22354359Sroberto#define STA_PPSSIGNAL	0x0100	/* PPS signal present (ro) */
22454359Sroberto#define STA_PPSJITTER	0x0200	/* PPS signal jitter exceeded (ro) */
22554359Sroberto#define STA_PPSWANDER	0x0400	/* PPS signal wander exceeded (ro) */
22654359Sroberto#define STA_PPSERROR	0x0800	/* PPS signal calibration error (ro) */
22754359Sroberto
22854359Sroberto#define STA_CLOCKERR	0x1000	/* clock hardware fault (ro) */
22954359Sroberto
23054359Sroberto#define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | \
23154359Sroberto    STA_PPSERROR | STA_CLOCKERR) /* read-only bits */
23254359Sroberto
23354359Sroberto/*
23454359Sroberto * Clock states (time_state)
23554359Sroberto */
23654359Sroberto#define TIME_OK		0	/* no leap second warning */
23754359Sroberto#define TIME_INS	1	/* insert leap second warning */
23854359Sroberto#define TIME_DEL	2	/* delete leap second warning */
23954359Sroberto#define TIME_OOP	3	/* leap second in progress */
24054359Sroberto#define TIME_WAIT	4	/* leap second has occurred */
24154359Sroberto#define TIME_ERROR	5	/* clock not synchronized */
24254359Sroberto
24354359Sroberto/*
24454359Sroberto * NTP user interface (ntp_gettime()) - used to read kernel clock values
24554359Sroberto *
24654359Sroberto * Note: maximum error = NTP synch distance = dispersion + delay / 2;
24754359Sroberto * estimated error = NTP dispersion.
24854359Sroberto */
24954359Srobertostruct ntptimeval {
25054359Sroberto	struct timeval time;	/* current time (ro) */
25154359Sroberto	long maxerror;		/* maximum error (us) (ro) */
25254359Sroberto	long esterror;		/* estimated error (us) (ro) */
25354359Sroberto};
25454359Sroberto
25554359Sroberto/*
25654359Sroberto * NTP daemon interface - (ntp_adjtime()) used to discipline CPU clock
25754359Sroberto * oscillator
25854359Sroberto */
25954359Srobertostruct timex {
26054359Sroberto	unsigned int modes;	/* clock mode bits (wo) */
26154359Sroberto	long offset;		/* time offset (us) (rw) */
26254359Sroberto	long freq;		/* frequency offset (scaled ppm) (rw) */
26354359Sroberto	long maxerror;		/* maximum error (us) (rw) */
26454359Sroberto	long esterror;		/* estimated error (us) (rw) */
26554359Sroberto	int status;		/* clock status bits (rw) */
26654359Sroberto	long constant;		/* pll time constant (rw) */
26754359Sroberto	long precision;		/* clock precision (us) (ro) */
26854359Sroberto	long tolerance;		/* clock frequency tolerance (scaled
26954359Sroberto				 * ppm) (ro) */
27054359Sroberto	/*
27154359Sroberto	 * The following read-only structure members are implemented
27254359Sroberto	 * only if the PPS signal discipline is configured in the
27354359Sroberto	 * kernel.
27454359Sroberto	 */
27554359Sroberto	long ppsfreq;		/* pps frequency (scaled ppm) (ro) */
27654359Sroberto	long jitter;		/* pps jitter (us) (ro) */
27754359Sroberto	int shift;		/* interval duration (s) (shift) (ro) */
27854359Sroberto	long stabil;		/* pps stability (scaled ppm) (ro) */
27954359Sroberto	long jitcnt;		/* jitter limit exceeded (ro) */
28054359Sroberto	long calcnt;		/* calibration intervals (ro) */
28154359Sroberto	long errcnt;		/* calibration errors (ro) */
28254359Sroberto	long stbcnt;		/* stability limit exceeded (ro) */
28354359Sroberto
28454359Sroberto};
28554359Sroberto#ifdef __FreeBSD__
28654359Sroberto
28754359Sroberto/*
28854359Sroberto * sysctl identifiers underneath kern.ntp_pll
28954359Sroberto */
29054359Sroberto#define NTP_PLL_GETTIME	1	/* used by ntp_gettime() */
29154359Sroberto#define NTP_PLL_MAXID	2	/* number of valid ids */
29254359Sroberto
29354359Sroberto#define NTP_PLL_NAMES { \
29454359Sroberto			  { 0, 0 }, \
29554359Sroberto			  { "gettime", CTLTYPE_STRUCT }, \
29654359Sroberto		      }
29754359Sroberto
29854359Sroberto#ifndef KERNEL
29954359Sroberto#include <sys/cdefs.h>
30054359Sroberto
30154359Sroberto__BEGIN_DECLS
30254359Srobertoextern int ntp_gettime        __P((struct ntptimeval *));
30354359Srobertoextern int ntp_adjtime        __P((struct timex *));
30454359Sroberto__END_DECLS
30554359Sroberto
30654359Sroberto#endif /* not KERNEL */
30754359Sroberto
30854359Sroberto#endif /* __FreeBSD__ */
30954359Sroberto#endif /* _SYS_TIMEX_H_ */
310