Commit ea287deb authored by wdenk's avatar wdenk

* Patch by Masami Komiya, 30 Mar 2005:

  add SNTP support and expand time server and time offset fields of
  DHCP support. See doc/README.SNTP

* Patch by Steven Scholz, 13 Dec 2004:
  Fix bug in at91rm920 ethernet driver
parent ef2807c6
......@@ -2,6 +2,13 @@
Changes for U-Boot 1.1.3:
======================================================================
* Patch by Masami Komiya, 30 Mar 2005:
add SNTP support and expand time server and time offset fields of
DHCP support. See doc/README.SNTP
* Patch by Steven Scholz, 13 Dec 2004:
Fix bug in at91rm920 ethernet driver
* Patch by Steven Scholz, 13 Dec 2004:
Remove duplicated code by merging memsetup.S files for
at91rm9200 boards into one cpu/at91rm9200/lowlevel.S
......
......@@ -136,6 +136,19 @@ static void netboot_update_env (void)
#endif
if (NetOurNISDomain[0])
setenv ("domain", NetOurNISDomain);
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_TIMEOFFSET)
if (NetTimeOffset) {
sprintf (tmp, "%d", NetTimeOffset);
setenv ("timeoffset", tmp);
}
#endif
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_NTPSERVER)
if (NetNtpServerIP) {
ip_to_string (NetNtpServerIP, tmp);
setenv ("ntpserverip", tmp);
}
#endif
}
static int
......@@ -279,4 +292,42 @@ U_BOOT_CMD(
);
#endif /* CFG_CMD_CDP */
#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
int do_sntp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
char *toff;
if (argc < 2) {
NetNtpServerIP = getenv_IPaddr ("ntpserverip");
if (NetNtpServerIP == 0) {
printf ("ntpserverip not set\n");
return (1);
}
} else {
NetNtpServerIP = string_to_ip(argv[1]);
if (NetNtpServerIP == 0) {
printf ("Bad NTP server IP address\n");
return (1);
}
}
toff = getenv ("timeoffset");
if (toff == NULL) NetTimeOffset = 0;
else NetTimeOffset = simple_strtol (toff, NULL, 10);
if (NetLoop(SNTP) < 0) {
printf("SNTP failed: host %s not responding\n", argv[1]);
return 1;
}
return 0;
}
U_BOOT_CMD(
sntp, 2, 1, do_sntp,
"sntp\t- synchronize RTC via network\n",
"[NTP server IP]\n"
);
#endif /* CFG_CMD_SNTP */
#endif /* CFG_CMD_NET */
......@@ -169,14 +169,16 @@ int eth_init (bd_t * bd)
AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN |
AT91C_PA7_ETXCK_EREFCK;
#if defined(CONFIG_AT91C_USE_RMII) && !defined(CONFIG_CMC_PU2)
*AT91C_PIOB_PDR = AT91C_PB25_EF100 |
AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV |
#ifdef CONFIG_AT91C_USE_RMII
*AT91C_PIOB_PDR = AT91C_PB19_ERXCK;
*AT91C_PIOB_BSR = AT91C_PB19_ERXCK;
#else
*AT91C_PIOB_PDR = AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV |
AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER |
AT91C_PB13_ETX3 | AT91C_PB12_ETX2;
/* Select B Register */
*AT91C_PIOB_BSR = AT91C_PB25_EF100 | AT91C_PB19_ERXCK | AT91C_PB18_ECOL |
*AT91C_PIOB_BSR = AT91C_PB19_ERXCK | AT91C_PB18_ECOL |
AT91C_PB17_ERXDV | AT91C_PB16_ERX3 | AT91C_PB15_ERX2 |
AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2;
#endif
......
To use SNTP support, add a define CFG_CMD_SNTP to CONFIG_COMMANDS in
the configuration file of the board.
The "sntp" command gets network time from NTP time server and
syncronize RTC of the board. This command needs the command line
parameter of server's IP address or environment variable
"ntpserverip". The network time is sent as UTC. So if you want to
set local time to RTC, set the offset in second from UTC to the
enviroment variable "time offset".
If the DHCP server provides time server's IP or time offset, you
don't need to set the above environment variables yourself.
Current limitations of SNTP support:
1. The roundtrip time is ignored.
2. Only the 1st NTP server IP, in the option ntp-servers of DHCP, will
be used.
......@@ -92,6 +92,7 @@
#define CFG_CMD_XIMG 0x0400000000000000ULL /* Load part of Multi Image */
#define CFG_CMD_UNIVERSE 0x0800000000000000ULL /* Tundra Universe Support */
#define CFG_CMD_EXT2 0x1000000000000000ULL /* EXT2 Support */
#define CFG_CMD_SNTP 0x2000000000000000ULL /* SNTP support */
#define CFG_CMD_ALL 0xFFFFFFFFFFFFFFFFULL /* ALL commands */
......@@ -135,6 +136,7 @@
CFG_CMD_SAVES | \
CFG_CMD_SCSI | \
CFG_CMD_SDRAM | \
CFG_CMD_SNTP | \
CFG_CMD_SPI | \
CFG_CMD_UNIVERSE | \
CFG_CMD_USB | \
......@@ -162,6 +164,8 @@
#define CONFIG_BOOTP_DNS 0x00000040
#define CONFIG_BOOTP_DNS2 0x00000080
#define CONFIG_BOOTP_SEND_HOSTNAME 0x00000100
#define CONFIG_BOOTP_NTPSERVER 0x00000200
#define CONFIG_BOOTP_TIMEOFFSET 0x00000400
#define CONFIG_BOOTP_VENDOREX 0x80000000
......
......@@ -92,10 +92,11 @@
#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
CFG_CMD_ASKENV | \
CFG_CMD_DATE | \
CFG_CMD_DHCP | \
CFG_CMD_ELF | \
CFG_CMD_IDE | \
CFG_CMD_DATE )
CFG_CMD_SNTP )
#define CONFIG_NETCONSOLE
......
......@@ -335,7 +335,7 @@ extern int NetState; /* Network loop state */
extern int NetRestartWrap; /* Tried all network devices */
#endif
typedef enum { BOOTP, RARP, ARP, TFTP, DHCP, PING, DNS, NFS, CDP, NETCONS } proto_t;
typedef enum { BOOTP, RARP, ARP, TFTP, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP } proto_t;
/* from net/net.c */
extern char BootFile[128]; /* Boot File name */
......@@ -350,6 +350,11 @@ extern ushort CDPNativeVLAN;
extern ushort CDPApplianceVLAN;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
extern IPaddr_t NetNtpServerIP; /* the ip address to NTP */
extern int NetTimeOffset; /* offset time from UTC */
#endif
/* Initialize the network adapter */
extern int NetLoop(proto_t);
......
......@@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk
LIB = libnet.a
OBJS = net.o tftp.o bootp.o rarp.o eth.o nfs.o
OBJS = net.o tftp.o bootp.o rarp.o eth.o nfs.o sntp.o
all: $(LIB)
$(LIB): $(START) $(OBJS)
......
......@@ -448,6 +448,10 @@ static int DhcpExtended (u8 * e, int message_type, IPaddr_t ServerID, IPaddr_t R
*e++ = 1; /* Subnet Mask */
*cnt += 1;
#endif
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_TIMEOFFSET)
*e++ = 2;
*cnt += 1;
#endif
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_GATEWAY)
*e++ = 3; /* Router Option */
*cnt += 1;
......@@ -471,6 +475,10 @@ static int DhcpExtended (u8 * e, int message_type, IPaddr_t ServerID, IPaddr_t R
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_NISDOMAIN)
*e++ = 40; /* NIS Domain name request */
*cnt += 1;
#endif
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_NTPSERVER)
*e++ = 42;
*cnt += 1;
#endif
*e++ = 255; /* End of the list */
......@@ -718,6 +726,12 @@ static void DhcpOptionsProcess (uchar * popt)
case 1:
NetCopyIP (&NetOurSubnetMask, (popt + 2));
break;
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_TIMEOFFSET)
case 2: /* Time offset */
NetCopyLong (&NetTimeOffset, (ulong *) (popt + 2));
NetTimeOffset = ntohl (NetTimeOffset);
break;
#endif
case 3:
NetCopyIP (&NetOurGatewayIP, (popt + 2));
break;
......@@ -741,6 +755,11 @@ static void DhcpOptionsProcess (uchar * popt)
memcpy (&NetOurRootPath, popt + 2, size);
NetOurRootPath[size] = 0;
break;
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_NTPSERVER)
case 42: /* NTP server IP */
NetCopyIP (&NetNtpServerIP, (popt + 2));
break;
#endif
case 51:
NetCopyLong (&dhcp_leasetime, (ulong *) (popt + 2));
break;
......
......@@ -64,6 +64,13 @@
* derived from our own IP address)
* We want: - load the boot file
* Next step: none
*
* SNTP:
*
* Prerequisites: - own ethernet address
* - own IP address
* We want: - network time
* Next step: none
*/
......@@ -79,6 +86,9 @@
#include <status_led.h>
#include <miiphy.h>
#endif
#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
#include "sntp.h"
#endif
#if (CONFIG_COMMANDS & CFG_CMD_NET)
......@@ -148,6 +158,11 @@ static void PingStart(void);
static void CDPStart(void);
#endif
#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
IPaddr_t NetNtpServerIP; /* NTP server IP address */
int NetTimeOffset=0; /* offset time from UTC */
#endif
#ifdef CONFIG_NETCONSOLE
void NcStart(void);
int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len);
......@@ -312,6 +327,9 @@ restart:
#endif
#if (CONFIG_COMMANDS & CFG_CMD_PING)
case PING:
#endif
#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
case SNTP:
#endif
case NETCONS:
case TFTP:
......@@ -333,6 +351,11 @@ restart:
case PING:
/* nothing */
break;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
case SNTP:
/* nothing */
break;
#endif
default:
break;
......@@ -416,6 +439,11 @@ restart:
case NETCONS:
NcStart();
break;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
case SNTP:
SntpStart();
break;
#endif
default:
break;
......@@ -1426,6 +1454,14 @@ static int net_check_prereq (proto_t protocol)
}
goto common;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
case SNTP:
if (NetNtpServerIP == 0) {
puts ("*** ERROR: NTP server address not given\n");
return (1);
}
goto common;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
case NFS:
#endif
......@@ -1435,7 +1471,7 @@ static int net_check_prereq (proto_t protocol)
puts ("*** ERROR: `serverip' not set\n");
return (1);
}
#if (CONFIG_COMMANDS & CFG_CMD_PING)
#if (CONFIG_COMMANDS & (CFG_CMD_PING | CFG_CMD_SNTP))
common:
#endif
......
/*
* SNTP support driver
*
* Masami Komiya <mkomiya@sonare.it> 2005
*
*/
#include <common.h>
#include <command.h>
#include <net.h>
#include <rtc.h>
#include "sntp.h"
#if ((CONFIG_COMMANDS & CFG_CMD_NET) && (CONFIG_COMMANDS & CFG_CMD_SNTP))
#define SNTP_TIMEOUT 10
static int SntpOurPort;
static void
SntpSend (void)
{
struct sntp_pkt_t pkt;
int pktlen = SNTP_PACKET_LEN;
int sport;
debug ("%s\n", __FUNCTION__);
memset (&pkt, 0, sizeof(pkt));
pkt.li = NTP_LI_NOLEAP;
pkt.vn = NTP_VERSION;
pkt.mode = NTP_MODE_CLIENT;
memcpy ((char *)NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE, (char *)&pkt, pktlen);
SntpOurPort = 10000 + (get_timer(0) % 4096);
sport = NTP_SERVICE_PORT;
NetSendUDPPacket (NetServerEther, NetNtpServerIP, sport, SntpOurPort, pktlen);
}
static void
SntpTimeout (void)
{
puts ("Timeout\n");
NetState = NETLOOP_FAIL;
return;
}
static void
SntpHandler (uchar *pkt, unsigned dest, unsigned src, unsigned len)
{
struct sntp_pkt_t rpkt;
struct rtc_time tm;
debug ("%s\n", __FUNCTION__);
if (dest != SntpOurPort) return;
memcpy ((unsigned char *)&rpkt, pkt, len);
#if (CONFIG_COMMANDS & CFG_CMD_DATE) || defined(CONFIG_TIMESTAMP)
to_tm(ntohl(rpkt.transmit_timestamp), &tm);
printf ("Date: %4d-%02d-%02d Time: %2d:%02d:%02d\n",
tm.tm_year, tm.tm_mon, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
to_tm(ntohl(rpkt.transmit_timestamp) - 2208988800u + NetTimeOffset, &tm);
#if (CONFIG_COMMANDS & CFG_CMD_DATE)
rtc_set (&tm);
#endif
printf ("Date: %4d-%02d-%02d Time: %2d:%02d:%02d\n",
tm.tm_year, tm.tm_mon, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
#endif
NetState = NETLOOP_SUCCESS;
}
void
SntpStart (void)
{
debug ("%s\n", __FUNCTION__);
NetSetTimeout (SNTP_TIMEOUT * CFG_HZ, SntpTimeout);
NetSetHandler(SntpHandler);
memset (NetServerEther, 0, 6);
SntpSend ();
}
#endif /* CONFIG_COMMANDS & CFG_CMD_SNTP */
/*
* (C) Masami Komiya <mkomiya@sonare.it> 2005
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2, or (at
* your option) any later version.
*/
#ifndef __SNTP_H__
#define __SNTP_H__
#define NTP_SERVICE_PORT 123
#define SNTP_PACKET_LEN 48
/* Leap Indicator */
#define NTP_LI_NOLEAP 0x0
#define NTP_LI_61SECS 0x1
#define NTP_LI_59SECS 0x2
#define NTP_LI_ALARM 0x3
/* Version */
#define NTP_VERSION 4
/* Mode */
#define NTP_MODE_RESERVED 0
#define NTP_MODE_SYMACTIVE 1 /* Symmetric Active */
#define NTP_MODE_SYMPASSIVE 2 /* Symmetric Passive */
#define NTP_MODE_CLIENT 3
#define NTP_MODE_SERVER 4
#define NTP_MODE_BROADCAST 5
#define NTP_MODE_NTPCTRL 6 /* Reserved for NTP control message */
#define NTP_MODE_PRIVATE 7 /* Reserved for private use */
struct sntp_pkt_t {
#if __LITTLE_ENDIAN
uchar mode:3;
uchar vn:3;
uchar li:2;
#else
uchar li:2;
uchar vn:3;
uchar mode:3;
#endif
uchar stratum;
uchar poll;
uchar precision;
uint root_delay;
uint root_dispersion;
uint reference_id;
unsigned long long reference_timestamp;
unsigned long long originate_timestamp;
unsigned long long receive_timestamp;
unsigned long long transmit_timestamp;
};
extern void SntpStart (void); /* Begin SNTP */
#endif /* __SNTP_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment