Commit 0c72e452 authored by Alessandro Rubini's avatar Alessandro Rubini

Merge branch 'network cleanup'

parents 7bab5d84 03285ba4
......@@ -83,6 +83,14 @@ config CMD_CONFIG
reports the current configuration. This adds half a kilobyte
to the binary size (100b for the code plus the .config file).
config SYSLOG
depends on IP
boolean "Include syslog client support"
help
This enable a UDP syslog client, configured by a shell command.
The user (or init script) must use "syslog <ipaddr> <macaddr>"
to enable it. The special "off" ipaddr disables syslog.
#
# This is a set of configuration options that should not be changed by
# normal users. If the "developer" menu is used, the binary is tainted.
......
......@@ -13,8 +13,9 @@ CONFIG_STACKSIZE=2048
CONFIG_PPSI=y
CONFIG_UART=y
CONFIG_W1=y
# CONFIG_IP is not set
# CONFIG_CMD_CONFIG is not set
CONFIG_IP=y
CONFIG_CMD_CONFIG=y
CONFIG_SYSLOG=y
#
# wrpc-sw is tainted if you change the following options
......
......@@ -194,7 +194,7 @@ int minic_poll_rx()
int minic_rx_frame(uint8_t * hdr, uint8_t * payload, uint32_t buf_size,
struct hw_timestamp *hwts)
{
uint32_t payload_size, num_words;
uint32_t frame_size, payload_size, num_words;
uint32_t desc_hdr;
uint32_t raw_ts;
uint32_t cur_avail;
......@@ -217,8 +217,8 @@ int minic_rx_frame(uint8_t * hdr, uint8_t * payload, uint32_t buf_size,
}
return 0;
}
payload_size = RX_DESC_SIZE(desc_hdr);
num_words = ((payload_size + 3) >> 2) + 1;
frame_size = RX_DESC_SIZE(desc_hdr);
num_words = ((frame_size + 3) >> 2) + 1;
/* valid packet */
if (!RX_DESC_ERROR(desc_hdr)) {
......@@ -229,15 +229,15 @@ int minic_rx_frame(uint8_t * hdr, uint8_t * payload, uint32_t buf_size,
int cntr_diff;
uint16_t dhdr;
payload_size -= RX_OOB_SIZE;
frame_size -= RX_OOB_SIZE;
/* fixme: ugly way of doing unaligned read */
minic_rx_memcpy((uint8_t *) & raw_ts,
(uint8_t *) minic.rx_head
+ payload_size + 6, 4);
+ frame_size + 6, 4);
minic_rx_memcpy((uint8_t *) & dhdr,
(uint8_t *) minic.rx_head +
payload_size + 4, 2);
frame_size + 4, 2);
EXPLODE_WR_TIMESTAMP(raw_ts, counter_r, counter_f);
shw_pps_gen_get_time(&sec, &counter_ppsg);
......@@ -258,14 +258,14 @@ int minic_rx_frame(uint8_t * hdr, uint8_t * payload, uint32_t buf_size,
hwts->nsec = counter_r * (REF_CLOCK_PERIOD_PS / 1000);
hwts->valid = (dhdr & RXOOB_TS_INCORRECT) ? 0 : 1;
}
payload_size = frame_size - ETH_HEADER_SIZE;
n_recvd = (buf_size < payload_size ? buf_size : payload_size);
minic.rx_count++;
minic_rx_memcpy(hdr, (void *)minic.rx_head + 4,
ETH_HEADER_SIZE);
minic_rx_memcpy(payload, (void *)minic.rx_head + 4
+ ETH_HEADER_SIZE, n_recvd - ETH_HEADER_SIZE);
+ ETH_HEADER_SIZE, n_recvd);
} else {
n_recvd = -1;
}
......@@ -299,9 +299,9 @@ int minic_tx_frame(uint8_t * hdr, uint8_t * payload, uint32_t size,
memset((void *)minic.tx_head, 0x0, size + 16);
memset((void *)minic.tx_head + 4, 0, size < 60 ? 60 : size);
memcpy((void *)minic.tx_head + 4, hdr, ETH_HEADER_SIZE);
memcpy((void *)minic.tx_head + 4 + ETH_HEADER_SIZE, payload,
size - ETH_HEADER_SIZE);
memcpy((void *)minic.tx_head + 4 + ETH_HEADER_SIZE, payload, size);
size += ETH_HEADER_SIZE;
if (size < 60)
size = 60;
......
......@@ -31,10 +31,10 @@
#define UART_BAUDRATE 115200ULL
/* Maximum number of simultaneously created sockets */
#define NET_MAX_SOCKETS 4
#define NET_MAX_SOCKETS 8
/* Socket buffer size, determines the max. RX packet size */
#define NET_SKBUF_SIZE 512
#define NET_MAX_SKBUF_SIZE 512
/* Number of auxillary clock channels - usually equal to the number of FMCs */
#define NUM_AUX_CLOCKS 1
......
......@@ -15,17 +15,13 @@
#include <board.h>
//#include <inttypes.h>
#define PTPD_SOCK_RAW_ETHERNET 1 /* used in ppsi to no aim: remove this */
#define PTPD_SOCK_UDP 0 /* wrong name, it should be "WRPC" */
#define PTPD_SOCK_RAW_ETHERNET 1 /* but used in ppsi, which I won't change */
#define PTPD_FLAGS_MULTICAST 0x1
// error codes (to be extended)
#define PTPD_NETIF_READY 1
#define PTPD_NETIF_OK 0
#define PTPD_NETIF_ERROR -1
#define PTPD_NETIF_NOT_READY -2
#define PTPD_NETIF_NOT_FOUND -3
#define LINK_WENT_UP 1
#define LINK_WENT_DOWN 2
#define LINK_UP 3
#define LINK_DOWN 4
// GCC-specific
#ifndef PACKED
......@@ -34,35 +30,36 @@
#define PHYS_PORT_ANY (0xffff)
#define PTPD_NETIF_TX 1
#define PTPD_NETIF_RX 2
#define IFACE_NAME_LEN 16
#define SLAVE_PRIORITY_0 0
#define SLAVE_PRIORITY_1 1
#define SLAVE_PRIORITY_2 2
#define SLAVE_PRIORITY_3 3
#define SLAVE_PRIORITY_4 4
// Some system-independent definitions
typedef uint8_t mac_addr_t[6];
typedef uint32_t ipv4_addr_t;
// WhiteRabbit socket - it's void pointer as the real socket structure is private and probably platform-specific.
typedef void *wr_socket_t;
// Socket address for ptp_netif_ functions
typedef struct {
// MAC address
struct wr_sockaddr {
// MAC address
mac_addr_t mac;
// Destination MASC address, filled by recvfrom() function on interfaces bound to multiple addresses
// Destination MAC address, filled by recvfrom()
mac_addr_t mac_dest;
// RAW ethertype
// RAW ethertype
uint16_t ethertype;
} wr_sockaddr_t;
uint16_t udpport;
};
struct sockq {
uint16_t head, tail, avail, size;
uint16_t n;
uint8_t *buff;
};
PACKED struct _wr_timestamp {
struct wrpc_socket {
struct wr_sockaddr bind_addr;
mac_addr_t local_mac;
uint32_t phase_transition;
uint32_t dmtd_phase;
struct sockq queue;
};
PACKED struct wr_timestamp {
// Seconds
int64_t sec;
......@@ -70,7 +67,7 @@ PACKED struct _wr_timestamp {
// Nanoseconds
int32_t nsec;
// Phase (in picoseconds), linearized for receive timestamps, zero for send timestamps
// Phase (in picoseconds), linearized for rx, zero for send timestamps
int32_t phase; // phase(picoseconds)
/* Raw time (non-linearized) for debugging purposes */
......@@ -78,54 +75,48 @@ PACKED struct _wr_timestamp {
int32_t raw_nsec;
int32_t raw_ahead;
// correctness flag: when 0, the timestamp MAY be incorrect (e.g. generated during timebase adjustment)
// when 0, tstamp MAY be incorrect (e.g. during timebase adjustment)
int correct;
//int cntr_ahead;
};
typedef struct _wr_timestamp wr_timestamp_t;
/* OK. These functions we'll develop along with network card driver. You can write your own UDP-based stubs for testing purposes. */
// Initialization of network interface:
// - opens devices
// - does necessary ioctls()
// - initializes connection with the mighty HAL daemon
int ptpd_netif_init(void);
// Creates UDP or Ethernet RAW socket (determined by sock_type) bound to bind_addr. If PTPD_FLAG_MULTICAST is set, the socket is
// automatically added to multicast group. User can specify physical_port field to bind the socket to specific switch port only.
wr_socket_t *ptpd_netif_create_socket(int unused, int unused2,
wr_sockaddr_t * bind_addr);
// Creates UDP or Ethernet RAW socket (determined by sock_type) bound
// to bind_addr. If PTPD_FLAG_MULTICAST is set, the socket is
// automatically added to multicast group. User can specify
// physical_port field to bind the socket to specific switch port only.
struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *s,
struct wr_sockaddr * bind_addr,
int udp_or_raw, int udpport);
// Sends a UDP/RAW packet (data, data_length) to address provided in wr_sockaddr_t.
// Sends a UDP/RAW packet (data, data_length) to addr in wr_sockaddr.
// For raw frames, mac/ethertype needs to be provided, for UDP - ip/port.
// Every transmitted frame has assigned a tag value, stored at tag parameter. This value is later used
// for recovering the precise transmit timestamp. If user doesn't need it, tag parameter can be left NULL.
int ptpd_netif_sendto(wr_socket_t * sock, wr_sockaddr_t * to, void *data,
size_t data_length, wr_timestamp_t * tx_ts);
// Receives an UDP/RAW packet. Data is written to (data) and length is returned. Maximum buffer length can be specified
// by data_length parameter. Sender information is stored in structure specified in 'from'. All RXed packets are timestamped and the timestamp
// Every transmitted frame has assigned a tag value, stored at tag parameter.
// This value is later used for recovering the precise transmit timestamp.
// If user doesn't need it, tag parameter can be left NULL.
int ptpd_netif_sendto(struct wrpc_socket *sock, struct wr_sockaddr *to, void *data,
size_t data_length, struct wr_timestamp *tx_ts);
// Receives an UDP/RAW packet. Data is written to (data) and len is returned.
// Maximum buffer length can be specified by data_length parameter.
// Sender information is stored in structure specified in 'from'.
// All RXed packets are timestamped and the timestamp
// is stored in rx_timestamp (unless it's NULL).
int ptpd_netif_recvfrom(wr_socket_t * sock, wr_sockaddr_t * from, void *data,
size_t data_length, wr_timestamp_t * rx_timestamp);
int ptpd_netif_recvfrom(struct wrpc_socket *sock, struct wr_sockaddr *from, void *data,
size_t data_length, struct wr_timestamp *rx_timestamp);
// Closes the socket.
int ptpd_netif_close_socket(wr_socket_t * sock);
int ptpd_netif_get_hw_addr(wr_socket_t * sock, mac_addr_t * mac);
int ptpd_netif_close_socket(struct wrpc_socket * sock);
int ptpd_netif_get_hw_addr(wr_socket_t * sock, mac_addr_t * mac);
int ptpd_netif_get_hw_addr(struct wrpc_socket * sock, mac_addr_t * mac);
void ptpd_netif_linearize_rx_timestamp(wr_timestamp_t * ts, int32_t dmtd_phase,
void ptpd_netif_linearize_rx_timestamp(struct wr_timestamp *ts,
int32_t dmtd_phase,
int cntr_ahead, int transition_point,
int clock_period);
void ptpd_netif_set_phase_transition(uint32_t phase);
struct hal_port_state;
int wrpc_get_port_state(struct hal_port_state *port, const char *port_name /* unused */);
int wrpc_get_port_state(struct hal_port_state *port,
const char *port_name /* unused */);
#endif /* __PTPD_NETIF_H */
......@@ -14,6 +14,10 @@ extern int wrc_stat_running;
const char *fromhex(const char *hex, int *v);
const char *fromdec(const char *dec, int *v);
void decode_mac(const char *str, unsigned char *mac);
char *format_mac(char *s, const unsigned char *mac);
void decode_ip(const char *str, unsigned char *ip);
char *format_ip(char *s, const unsigned char *ip);
struct wrc_shell_cmd {
char *name;
......
......@@ -16,7 +16,10 @@
#define C_BLUE 4
/* Return TAI date/time in human-readable form. Non-reentrant. */
char *format_time(uint64_t sec);
char *format_time(uint64_t sec, int format);
#define TIME_FORMAT_LEGACY 0
#define TIME_FORMAT_SYSLOG 1
#define TIME_FORMAT_SORTED 2
/* Color printf() variant. */
void cprintf(int color, const char *fmt, ...);
......
......@@ -16,7 +16,12 @@
#define htons(x) x
#endif
static wr_socket_t *arp_socket;
static uint8_t __arp_queue[128];
static struct wrpc_socket __static_arp_socket = {
.queue.buff = __arp_queue,
.queue.size = sizeof(__arp_queue),
};
static struct wrpc_socket *arp_socket;
#define ARP_HTYPE 0
#define ARP_PTYPE (ARP_HTYPE+2)
......@@ -31,14 +36,15 @@ static wr_socket_t *arp_socket;
void arp_init(void)
{
wr_sockaddr_t saddr;
struct wr_sockaddr saddr;
/* Configure socket filter */
memset(&saddr, 0, sizeof(saddr));
memset(&saddr.mac, 0xFF, 6); /* Broadcast */
saddr.ethertype = htons(0x0806); /* ARP */
arp_socket = ptpd_netif_create_socket(0, 0 /* both unused */, &saddr);
arp_socket = ptpd_netif_create_socket(&__static_arp_socket, &saddr,
PTPD_SOCK_RAW_ETHERNET, 0);
}
static int process_arp(uint8_t * buf, int len)
......@@ -85,7 +91,7 @@ static int process_arp(uint8_t * buf, int len)
void arp_poll(void)
{
uint8_t buf[ARP_END + 100];
wr_sockaddr_t addr;
struct wr_sockaddr addr;
int len;
if (needIP)
......
......@@ -12,30 +12,6 @@
#include "ipv4.h"
#define IP_VERSION 0
#define IP_TOS (IP_VERSION+1)
#define IP_LEN (IP_TOS+1)
#define IP_ID (IP_LEN+2)
#define IP_FLAGS (IP_ID+2)
#define IP_TTL (IP_FLAGS+2)
#define IP_PROTOCOL (IP_TTL+1)
#define IP_CHECKSUM (IP_PROTOCOL+1)
#define IP_SOURCE (IP_CHECKSUM+2)
#define IP_DEST (IP_SOURCE+4)
#define IP_END (IP_DEST+4)
#define UDP_VIRT_SADDR (IP_END-12)
#define UDP_VIRT_DADDR (UDP_VIRT_SADDR+4)
#define UDP_VIRT_ZEROS (UDP_VIRT_DADDR+4)
#define UDP_VIRT_PROTO (UDP_VIRT_ZEROS+1)
#define UDP_VIRT_LENGTH (UDP_VIRT_PROTO+1)
#define UDP_SPORT (IP_END)
#define UDP_DPORT (UDP_SPORT+2)
#define UDP_LENGTH (UDP_DPORT+2)
#define UDP_CHECKSUM (UDP_LENGTH+2)
#define UDP_END (UDP_CHECKSUM+2)
#define BOOTP_OP (UDP_END)
#define BOOTP_HTYPE (BOOTP_OP+1)
#define BOOTP_HLEN (BOOTP_HTYPE+1)
......@@ -53,9 +29,9 @@
#define BOOTP_VEND (BOOTP_FILE+128)
#define BOOTP_END (BOOTP_VEND+64)
int send_bootp(uint8_t * buf, int retry)
int prepare_bootp(struct wr_sockaddr *addr, uint8_t * buf, int retry)
{
unsigned short sum;
struct wr_udp_addr uaddr;
// ----------- BOOTP ------------
buf[BOOTP_OP] = 1; /* bootrequest */
......@@ -86,54 +62,16 @@ int send_bootp(uint8_t * buf, int retry)
memset(buf + BOOTP_FILE, 0, 128); /* desired BOOTP file */
memset(buf + BOOTP_VEND, 0, 64); /* vendor extensions */
// ------------ UDP -------------
memset(buf + UDP_VIRT_SADDR, 0, 4);
memset(buf + UDP_VIRT_DADDR, 0xFF, 4);
buf[UDP_VIRT_ZEROS] = 0;
buf[UDP_VIRT_PROTO] = 0x11; /* UDP */
buf[UDP_VIRT_LENGTH] = (BOOTP_END - IP_END) >> 8;
buf[UDP_VIRT_LENGTH + 1] = (BOOTP_END - IP_END) & 0xff;
buf[UDP_SPORT] = 0;
buf[UDP_SPORT + 1] = 68; /* BOOTP client */
buf[UDP_DPORT] = 0;
buf[UDP_DPORT + 1] = 67; /* BOOTP server */
buf[UDP_LENGTH] = (BOOTP_END - IP_END) >> 8;
buf[UDP_LENGTH + 1] = (BOOTP_END - IP_END) & 0xff;
buf[UDP_CHECKSUM] = 0;
buf[UDP_CHECKSUM + 1] = 0;
sum =
ipv4_checksum((unsigned short *)(buf + UDP_VIRT_SADDR),
(BOOTP_END - UDP_VIRT_SADDR) / 2);
if (sum == 0)
sum = 0xFFFF;
buf[UDP_CHECKSUM + 0] = (sum >> 8);
buf[UDP_CHECKSUM + 1] = sum & 0xff;
// ------------ IP --------------
buf[IP_VERSION] = 0x45;
buf[IP_TOS] = 0;
buf[IP_LEN + 0] = (BOOTP_END) >> 8;
buf[IP_LEN + 1] = (BOOTP_END) & 0xff;
buf[IP_ID + 0] = 0;
buf[IP_ID + 1] = 0;
buf[IP_FLAGS + 0] = 0;
buf[IP_FLAGS + 1] = 0;
buf[IP_TTL] = 63;
buf[IP_PROTOCOL] = 17; /* UDP */
buf[IP_CHECKSUM + 0] = 0;
buf[IP_CHECKSUM + 1] = 0;
memset(buf + IP_SOURCE, 0, 4);
memset(buf + IP_DEST, 0xFF, 4);
sum =
ipv4_checksum((unsigned short *)(buf + IP_VERSION),
(IP_END - IP_VERSION) / 2);
buf[IP_CHECKSUM + 0] = sum >> 8;
buf[IP_CHECKSUM + 1] = sum & 0xff;
/* complete with udp helper */
memset(&uaddr.saddr, 0, 4);
memset(&uaddr.daddr, 0xff, 4);
uaddr.sport = ntohs(68);
uaddr.dport = ntohs(67);
fill_udp(buf, BOOTP_END, &uaddr);
/* and fix destination before sending it */
memset(addr->mac, 0xFF, 6);
// pp_printf("Sending BOOTP request...\n");
return BOOTP_END;
}
......@@ -148,12 +86,7 @@ int process_bootp(uint8_t * buf, int len)
if (len != BOOTP_END)
return 0;
if (buf[IP_VERSION] != 0x45)
return 0;
if (buf[IP_PROTOCOL] != 17 ||
buf[UDP_DPORT] != 0 || buf[UDP_DPORT + 1] != 68 ||
buf[UDP_SPORT] != 0 || buf[UDP_SPORT + 1] != 67)
if (buf[UDP_SPORT] != 0 || buf[UDP_SPORT + 1] != 67)
return 0;
if (memcmp(buf + BOOTP_CHADDR, mac, 6))
......
......@@ -7,10 +7,12 @@
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <string.h>
#include <wrpc.h>
#include "endpoint.h"
#include "ipv4.h"
#include "ptpd_netif.h"
#include "pps_gen.h"
#include "hw/memlayout.h"
#include "hw/etherbone-config.h"
......@@ -20,7 +22,37 @@
int needIP = 1;
static uint8_t myIP[4];
static wr_socket_t *ipv4_socket;
/* bootp: bigger buffer, UDP based */
static uint8_t __bootp_queue[512];
static struct wrpc_socket __static_bootp_socket = {
.queue.buff = __bootp_queue,
.queue.size = sizeof(__bootp_queue),
};
static struct wrpc_socket *bootp_socket;
/* ICMP: smaller buffer */
static uint8_t __icmp_queue[128];
static struct wrpc_socket __static_icmp_socket = {
.queue.buff = __icmp_queue,
.queue.size = sizeof(__icmp_queue),
};
static struct wrpc_socket *icmp_socket;
/* RDATE: even smaller buffer -- but we require 86. 96 is "even". */
static uint8_t __rdate_queue[96];
static struct wrpc_socket __static_rdate_socket = {
.queue.buff = __rdate_queue,
.queue.size = sizeof(__rdate_queue),
};
static struct wrpc_socket *rdate_socket;
/* syslog is selected by Kconfig, so we have weak aliases here */
void __attribute__((weak)) syslog_init(void)
{ }
void __attribute__((weak)) syslog_poll(int l_status)
{ }
unsigned int ipv4_checksum(unsigned short *buf, int shorts)
{
......@@ -29,7 +61,7 @@ unsigned int ipv4_checksum(unsigned short *buf, int shorts)
sum = 0;
for (i = 0; i < shorts; ++i)
sum += buf[i];
sum += ntohs(buf[i]);
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
......@@ -39,47 +71,106 @@ unsigned int ipv4_checksum(unsigned short *buf, int shorts)
void ipv4_init(void)
{
wr_sockaddr_t saddr;
struct wr_sockaddr saddr;
/* Bootp: use UDP engine activated but function arguments */
bootp_socket = ptpd_netif_create_socket(&__static_bootp_socket, NULL,
PTPD_SOCK_UDP, 68 /* bootpc */);
/* Reset => need a fresh IP */
needIP = 1;
/* time (rdate): UDP */
rdate_socket = ptpd_netif_create_socket(&__static_rdate_socket, NULL,
PTPD_SOCK_UDP, 37 /* time */);
/* Configure socket filter */
/* ICMP: specify raw (not UDP), with IPV4 ethtype */
memset(&saddr, 0, sizeof(saddr));
get_mac_addr(&saddr.mac[0]); /* Unicast */
saddr.ethertype = htons(0x0800); /* IPv4 */
saddr.ethertype = htons(0x0800);
icmp_socket = ptpd_netif_create_socket(&__static_icmp_socket, &saddr,
PTPD_SOCK_RAW_ETHERNET, 0);
ipv4_socket = ptpd_netif_create_socket(0, 0 /* both unused */, &saddr);
syslog_init();
}
static int bootp_retry = 0;
static int bootp_timer = 0;
static uint32_t bootp_tics;
void ipv4_poll(void)
/* receive bootp through the UDP mechanism */
static void bootp_poll(void)
{
struct wr_sockaddr addr;
uint8_t buf[400];
wr_sockaddr_t addr;
int len;
if ((len = ptpd_netif_recvfrom(ipv4_socket, &addr,
buf, sizeof(buf), 0)) > 0) {
if (needIP)
process_bootp(buf, len);
if (!bootp_tics) /* first time ever */
bootp_tics = timer_get_tics() - 1;
len = ptpd_netif_recvfrom(bootp_socket, &addr,
buf, sizeof(buf), NULL);
if (len > 0 && needIP)
process_bootp(buf, len);
if (!needIP)
return;
if (time_before(timer_get_tics(), bootp_tics))
return;
len = prepare_bootp(&addr, buf, ++bootp_retry);
ptpd_netif_sendto(bootp_socket, &addr, buf, len, 0);
bootp_tics = timer_get_tics() + TICS_PER_SECOND;
}
static void icmp_poll(void)
{
struct wr_sockaddr addr;
uint8_t buf[128];
int len;
len = ptpd_netif_recvfrom(icmp_socket, &addr,
buf, sizeof(buf), NULL);
if (len <= 0)
return;
if (needIP)
return;
if ((len = process_icmp(buf, len)) > 0)
ptpd_netif_sendto(icmp_socket, &addr, buf, len, 0);
}
static void rdate_poll(void)
{
struct wr_sockaddr addr;
uint64_t secs;
uint32_t result;
uint8_t buf[32];
int len;
len = ptpd_netif_recvfrom(rdate_socket, &addr,
buf, sizeof(buf), NULL);
if (len <= 0)
return;
shw_pps_gen_get_time(&secs, NULL);
result = htonl((uint32_t)(secs + 2208988800LL));
/* Magic above: $(date +%s --date="Jan 1 1900 00:00:00 UTC)" */
if (!needIP && (len = process_icmp(buf, len)) > 0)
ptpd_netif_sendto(ipv4_socket, &addr, buf, len, 0);
}
len = UDP_END + sizeof(result);
memcpy(buf + UDP_END, &result, sizeof(result));
fill_udp(buf, len, NULL);
ptpd_netif_sendto(rdate_socket, &addr, buf, len, 0);
}
void ipv4_poll(int l_status)
{
if (l_status == LINK_WENT_UP)
needIP = 1;
bootp_poll();
if (needIP && bootp_timer == 0) {
len = send_bootp(buf, ++bootp_retry);
icmp_poll();
memset(addr.mac, 0xFF, 6);
addr.ethertype = htons(0x0800); /* IPv4 */
ptpd_netif_sendto(ipv4_socket, &addr, buf, len, 0);
}
rdate_poll();
if (needIP && ++bootp_timer == 100000)
bootp_timer = 0;
syslog_poll(l_status);
}
void getIP(unsigned char *IP)
......@@ -100,8 +191,6 @@ void setIP(unsigned char *IP)
*eb_ip = ip;
needIP = (ip == 0);
if (!needIP) {
if (!needIP)
bootp_retry = 0;
bootp_timer = 0;
}
}
......@@ -7,9 +7,34 @@
#define IPV4_H
#include <inttypes.h>
#include "ptpd_netif.h" /* for sockaddr in prototype */
#define IP_VERSION 0
#define IP_TOS (IP_VERSION+1)
#define IP_LEN (IP_TOS+1)
#define IP_ID (IP_LEN+2)
#define IP_FLAGS (IP_ID+2)
#define IP_TTL (IP_FLAGS+2)
#define IP_PROTOCOL (IP_TTL+1)
#define IP_CHECKSUM (IP_PROTOCOL+1)
#define IP_SOURCE (IP_CHECKSUM+2)
#define IP_DEST (IP_SOURCE+4)
#define IP_END (IP_DEST+4)
#define UDP_VIRT_SADDR (IP_END-12)
#define UDP_VIRT_DADDR (UDP_VIRT_SADDR+4)
#define UDP_VIRT_ZEROS (UDP_VIRT_DADDR+4)
#define UDP_VIRT_PROTO (UDP_VIRT_ZEROS+1)
#define UDP_VIRT_LENGTH (UDP_VIRT_PROTO+1)
#define UDP_SPORT (IP_END)
#define UDP_DPORT (UDP_SPORT+2)
#define UDP_LENGTH (UDP_DPORT+2)
#define UDP_CHECKSUM (UDP_LENGTH+2)
#define UDP_END (UDP_CHECKSUM+2)
void ipv4_init(void);
void ipv4_poll(void);
void ipv4_poll(int l_status);
/* Internal to IP stack: */
unsigned int ipv4_checksum(unsigned short *buf, int shorts);
......@@ -23,6 +48,19 @@ void getIP(unsigned char *IP);
int process_icmp(uint8_t * buf, int len);
int process_bootp(uint8_t * buf, int len); /* non-zero if IP was set */
int send_bootp(uint8_t * buf, int retry);
int prepare_bootp(struct wr_sockaddr *addr, uint8_t * buf, int retry);
/* The UDP helper needs some information, if not replying to a frame */
struct wr_udp_addr {
uint32_t saddr; /* all fields in network order, for memcpy */
uint32_t daddr;
uint16_t sport;
uint16_t dport;
};
void fill_udp(uint8_t * buf, int len, struct wr_udp_addr *uaddr);
void syslog_init(void);
void syslog_poll(int l_status);
#endif
obj-y += lib/util.o lib/atoi.o
obj-y += lib/usleep.o
obj-$(CONFIG_WR_NODE) += lib/net.o
obj-$(CONFIG_WR_NODE) += lib/net.o lib/udp.o
obj-$(CONFIG_WR_NODE) += lib/arp.o lib/icmp.o lib/ipv4.o lib/bootp.o
obj-$(CONFIG_SYSLOG) += lib/syslog.o
......@@ -22,47 +22,20 @@
#include "minic.h"
#include "endpoint.h"
#include "softpll_ng.h"
#include "ipv4.h"
#define min(x,y) ((x) < (y) ? (x) : (y))
__attribute__ ((packed))
struct ethhdr {
uint8_t dstmac[6];
uint8_t srcmac[6];
uint16_t ethtype;
};
struct timeout {
uint64_t start_tics;
uint64_t timeout;
};
struct sockq {
uint8_t buf[NET_SKBUF_SIZE];
uint16_t head, tail, avail;
uint16_t n;
};
struct my_socket {
int in_use;
wr_sockaddr_t bind_addr;
mac_addr_t local_mac;
uint32_t phase_transition;
uint32_t dmtd_phase;
struct sockq queue;
};
static struct my_socket socks[NET_MAX_SOCKETS];
int ptpd_netif_init()
{
memset(socks, 0, sizeof(socks));
return PTPD_NETIF_OK;
}
static struct wrpc_socket *socks[NET_MAX_SOCKETS];
//#define net_verbose pp_printf
int ptpd_netif_get_hw_addr(wr_socket_t * sock, mac_addr_t * mac)
int ptpd_netif_get_hw_addr(struct wrpc_socket *sock, mac_addr_t *mac)
{
get_mac_addr((uint8_t *) mac);
......@@ -73,35 +46,45 @@ void ptpd_netif_set_phase_transition(uint32_t phase)
{
int i;
for (i=0; i< NET_MAX_SOCKETS; ++i) {
socks[i].phase_transition = phase;
for (i=0; i< ARRAY_SIZE(socks); ++i) {
socks[i]->phase_transition = phase;
}
}
wr_socket_t *ptpd_netif_create_socket(int unused, int unusd2,
wr_sockaddr_t * bind_addr)
struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *sock,
struct wr_sockaddr * bind_addr,
int udp_or_raw, int udpport)
{
int i;
struct hal_port_state pstate;
struct my_socket *sock;
static mac_addr_t zero_mac;
/* Look for the first available socket. */
for (sock = NULL, i = 0; i < NET_MAX_SOCKETS; i++)
if (!socks[i].in_use) {
sock = &socks[i];
for (i = 0; i < ARRAY_SIZE(socks); i++)
if (!socks[i]) {
socks[i] = sock;
break;
}
if (!sock) {
net_verbose("No sockets left.\n");
if (i == ARRAY_SIZE(socks)) {
pp_printf("%s: no socket slots left\n", __func__);
return NULL;
}
if (wrpc_get_port_state(&pstate, "wr0" /* unused */) < 0)
return NULL;
memcpy(&sock->bind_addr, bind_addr, sizeof(wr_sockaddr_t));
/* copy and complete the bind information. If MAC is 0 use unicast */
memset(&sock->bind_addr, 0, sizeof(struct wr_sockaddr));
if (bind_addr)
memcpy(&sock->bind_addr, bind_addr, sizeof(struct wr_sockaddr));
if (!memcmp(sock->bind_addr.mac, zero_mac, ETH_ALEN))
get_mac_addr(sock->bind_addr.mac);
sock->bind_addr.udpport = 0;
if (udp_or_raw == PTPD_SOCK_UDP) {
sock->bind_addr.ethertype = htons(0x0800); /* IPv4 */
sock->bind_addr.udpport = udpport;
}
/*get mac from endpoint */
get_mac_addr(sock->local_mac);
......@@ -111,19 +94,18 @@ wr_socket_t *ptpd_netif_create_socket(int unused, int unusd2,
/*packet queue */
sock->queue.head = sock->queue.tail = 0;
sock->queue.avail = NET_SKBUF_SIZE;
sock->queue.avail = sock->queue.size;
sock->queue.n = 0;
sock->in_use = 1;
return (wr_socket_t *) (sock);
return sock;
}
int ptpd_netif_close_socket(wr_socket_t * sock)
int ptpd_netif_close_socket(struct wrpc_socket *s)
{
struct my_socket *s = (struct my_socket *)sock;
if (s)
s->in_use = 0;
int i;
for (i = 0; i < ARRAY_SIZE(socks); i++)
if (socks[i] == s)
socks[i] = NULL;
return 0;
}
......@@ -136,7 +118,8 @@ int ptpd_netif_close_socket(wr_socket_t * sock)
*
* Have a look at the note at http://ohwr.org/documents/xxx for details.
*/
void ptpd_netif_linearize_rx_timestamp(wr_timestamp_t * ts, int32_t dmtd_phase,
void ptpd_netif_linearize_rx_timestamp(struct wr_timestamp *ts,
int32_t dmtd_phase,
int cntr_ahead, int transition_point,
int clock_period)
{
......@@ -202,20 +185,27 @@ void ptpd_netif_linearize_rx_timestamp(wr_timestamp_t * ts, int32_t dmtd_phase,
}
/* Slow, but we don't care much... */
static int wrap_copy_in(void *dst, struct sockq *q, size_t len)
static int wrap_copy_in(void *dst, struct sockq *q, size_t len, size_t buflen)
{
char *dptr = dst;
int i = len;
net_verbose("copy_in: tail %d avail %d len %d\n", q->tail, q->avail,
len);
int i;
if (!buflen)
buflen = len;
net_verbose("copy_in: tail %d avail %d len %d (buf %d)\n",
q->tail, q->avail, len, buflen);
i = min(len, buflen);
while (i--) {
*dptr++ = q->buf[q->tail];
*dptr++ = q->buff[q->tail];
q->tail++;
if (q->tail == NET_SKBUF_SIZE)
if (q->tail == q->size)
q->tail = 0;
}
if (len > buflen) {
q->tail += len - buflen;
while (q->tail > q->size)
q->tail -= q->size;
}
return len;
}
......@@ -228,17 +218,16 @@ static int wrap_copy_out(struct sockq *q, void *src, size_t len)
len);
while (i--) {
q->buf[q->head++] = *sptr++;
if (q->head == NET_SKBUF_SIZE)
q->buff[q->head++] = *sptr++;
if (q->head == q->size)
q->head = 0;
}
return len;
}
int ptpd_netif_recvfrom(wr_socket_t * sock, wr_sockaddr_t * from, void *data,
size_t data_length, wr_timestamp_t * rx_timestamp)
int ptpd_netif_recvfrom(struct wrpc_socket *s, struct wr_sockaddr *from, void *data,
size_t data_length, struct wr_timestamp *rx_timestamp)
{
struct my_socket *s = (struct my_socket *)sock;
struct sockq *q = &s->queue;
uint16_t size;
......@@ -252,10 +241,10 @@ int ptpd_netif_recvfrom(wr_socket_t * sock, wr_sockaddr_t * from, void *data,
q->n--;
q->avail += wrap_copy_in(&size, q, 2);
q->avail += wrap_copy_in(&hdr, q, sizeof(struct ethhdr));
q->avail += wrap_copy_in(&hwts, q, sizeof(struct hw_timestamp));
q->avail += wrap_copy_in(data, q, min(size, data_length));
q->avail += wrap_copy_in(&size, q, 2, 0);
q->avail += wrap_copy_in(&hwts, q, sizeof(struct hw_timestamp), 0);
q->avail += wrap_copy_in(&hdr, q, sizeof(struct ethhdr), 0);
q->avail += wrap_copy_in(data, q, size, data_length);
from->ethertype = ntohs(hdr.ethtype);
memcpy(from->mac, hdr.srcmac, 6);
......@@ -279,28 +268,34 @@ int ptpd_netif_recvfrom(wr_socket_t * sock, wr_sockaddr_t * from, void *data,
REF_CLOCK_PERIOD_PS);
}
net_verbose("%s: called from %p\n",
__func__, __builtin_return_address(0));
net_verbose("RX: Size %d tail %d Smac %x:%x:%x:%x:%x:%x\n", size,
q->tail, hdr.srcmac[0], hdr.srcmac[1], hdr.srcmac[2],
hdr.srcmac[3], hdr.srcmac[4], hdr.srcmac[5]);
return min(size - sizeof(struct ethhdr), data_length);
return min(size, data_length);
}
int ptpd_netif_sendto(wr_socket_t * sock, wr_sockaddr_t * to, void *data,
size_t data_length, wr_timestamp_t * tx_timestamp)
int ptpd_netif_sendto(struct wrpc_socket * sock, struct wr_sockaddr *to, void *data,
size_t data_length, struct wr_timestamp *tx_timestamp)
{
struct my_socket *s = (struct my_socket *)sock;
struct wrpc_socket *s = (struct wrpc_socket *)sock;
struct hw_timestamp hwts;
struct ethhdr hdr;
int rval;
memcpy(hdr.dstmac, to->mac, 6);
memcpy(hdr.srcmac, s->local_mac, 6);
hdr.ethtype = to->ethertype;
hdr.ethtype = sock->bind_addr.ethertype;
net_verbose("TX: socket %04x:%04x, len %i\n",
ntohs(s->bind_addr.ethertype),
s->bind_addr.udpport,
data_length);
rval =
minic_tx_frame((uint8_t *) & hdr, (uint8_t *) data,
data_length + ETH_HEADER_SIZE, &hwts);
data_length, &hwts);
if (tx_timestamp) {
......@@ -315,30 +310,46 @@ int ptpd_netif_sendto(wr_socket_t * sock, wr_sockaddr_t * to, void *data,
void update_rx_queues()
{
struct my_socket *s = NULL;
struct wrpc_socket *s = NULL;
struct sockq *q;
struct hw_timestamp hwts;
static struct ethhdr hdr;
int recvd, i, q_required;
static uint8_t payload[NET_SKBUF_SIZE - 32];
uint16_t size;
static uint8_t payload[NET_MAX_SKBUF_SIZE - 32];
uint16_t size, port;
recvd =
minic_rx_frame((uint8_t *) & hdr, payload, NET_SKBUF_SIZE - 32,
minic_rx_frame((uint8_t *) & hdr, payload, sizeof(payload),
&hwts);
if (recvd <= 0) /* No data received? */
return;
for (i = 0; i < NET_MAX_SOCKETS; i++) {
s = &socks[i];
if (s->in_use && !memcmp(hdr.dstmac, s->bind_addr.mac, 6)
&& hdr.ethtype == s->bind_addr.ethertype)
break; /*they match */
s = NULL;
for (i = 0; i < ARRAY_SIZE(socks); i++) {
s = socks[i];
if (!s)
continue;
if (memcmp(hdr.dstmac, s->bind_addr.mac, 6))
continue;
if (hdr.ethtype != s->bind_addr.ethertype)
continue;
if (s->bind_addr.udpport == 0)
break; /* raw socket: match */
/* Now make IP/UDP checks */
if (payload[IP_VERSION] != 0x45)
continue;
if (payload[IP_PROTOCOL] != 17)
continue;
port = payload[UDP_DPORT] << 8 | payload[UDP_DPORT + 1];
if (port != s->bind_addr.udpport)
continue;
break; /* udp match */
}
if (!s) {
if (i == ARRAY_SIZE(socks)) {
net_verbose("%s: could not find socket for packet\n",
__FUNCTION__);
return;
......@@ -358,8 +369,8 @@ void update_rx_queues()
size = recvd;
q->avail -= wrap_copy_out(q, &size, 2);
q->avail -= wrap_copy_out(q, &hdr, sizeof(struct ethhdr));
q->avail -= wrap_copy_out(q, &hwts, sizeof(struct hw_timestamp));
q->avail -= wrap_copy_out(q, &hdr, sizeof(struct ethhdr));
q->avail -= wrap_copy_out(q, payload, size);
q->n++;
......@@ -367,6 +378,9 @@ void update_rx_queues()
q->head, hdr.srcmac[0], hdr.srcmac[1], hdr.srcmac[2],
hdr.srcmac[3], hdr.srcmac[4], hdr.srcmac[5]);
net_verbose("%s: saved packet to queue [avail %d n %d size %d]\n",
__FUNCTION__, q->avail, q->n, q_required);
net_verbose("%s: saved packet to socket %04x:%04x "
"[avail %d n %d size %d]\n", __FUNCTION__,
ntohs(s->bind_addr.ethertype),
s->bind_addr.udpport,
q->avail, q->n, q_required);
}
#include <string.h>
#include <wrc.h>
#include <wrpc.h>
#include "endpoint.h"
#include "minic.h"
#include "shell.h"
#include "pps_gen.h"
#include "ipv4.h"
/* syslog: a tx-only socket: no queue is there */
static struct wrpc_socket __static_syslog_socket = {
.queue.buff = NULL,
.queue.size = 0,
};
static struct wrpc_socket *syslog_socket;
static struct wr_udp_addr syslog_addr;
unsigned char syslog_mac[6];
static uint32_t tics, tics_zero;
void syslog_init(void)
{
syslog_socket = ptpd_netif_create_socket(&__static_syslog_socket, NULL,
PTPD_SOCK_UDP, 514 /* time */);
syslog_addr.sport = syslog_addr.dport = htons(514);
tics_zero = timer_get_tics();
}
static int cmd_syslog(const char *args[])
{
char b1[32], b2[32];
if (args[0] && !strcmp(args[0], "off")) {
syslog_addr.daddr = 0;
return 0;
}
if (!args[1]) {
pp_printf("use: syslog <ipaddr> <macaddr> (or just \"off\"\n");
return -1;
}
decode_ip(args[0], (void *)&syslog_addr.daddr);
decode_mac(args[1], syslog_mac);
pp_printf("Syslog parameters: %s, %s\n",
format_ip(b1, (void *)&syslog_addr.daddr),
format_mac(b2, syslog_mac));
tics = 0; /* send the first frame immediately to the new host */
return 0;
}
DEFINE_WRC_COMMAND(mac) = {
.name = "syslog",
.exec = cmd_syslog,
};
void syslog_poll(int l_status)
{
struct wr_sockaddr addr;
char buf[256];
char b1[32], b2[32];
unsigned char mac[6];
unsigned char ip[4];
uint64_t secs;
static uint32_t down_tics;
int len = 0;
if (needIP)
return;
if (!syslog_addr.daddr)
return;
if (!tics) {
/* first time ever, or new syslog server */
tics = timer_get_tics() - 1;
shw_pps_gen_get_time(&secs, NULL);
get_mac_addr(mac);
getIP(ip);
len = pp_sprintf(buf + UDP_END, /* 8 == user + 6 == info */
"<14> %s %s (%s) Node up "
"since %i seconds\n",
format_time(secs, TIME_FORMAT_SYSLOG),
format_ip(b1, ip), format_mac(b2, mac),
(tics - tics_zero) / 1000);
goto send;
}
if (l_status == LINK_WENT_DOWN)
down_tics = timer_get_tics();
if (l_status == LINK_UP && down_tics) {
down_tics = timer_get_tics() - down_tics;
shw_pps_gen_get_time(&secs, NULL);
getIP(ip);
len = pp_sprintf(buf + UDP_END, /* 8 == user + 6 == info */
"<14> %s %s Link up after %i.%03i s\n",
format_time(secs, TIME_FORMAT_SYSLOG),
format_ip(b1, ip),
down_tics / 1000, down_tics % 1000);
down_tics = 0;
goto send;
}
return;
send:
len += UDP_END;
memcpy(&syslog_addr.saddr, ip, 4);
fill_udp((void *)buf, len, &syslog_addr);
memcpy(&addr.mac, syslog_mac, 6);
ptpd_netif_sendto(syslog_socket, &addr, buf, len, 0);
}
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2016 GSI (www.gsi.de)
* Author: Alessandro Rubini <a.rubini@gsi.de>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <string.h>
#include "ipv4.h"
#include "ptpd_netif.h"
void fill_udp(uint8_t * buf, int len, struct wr_udp_addr *uaddr)
{
unsigned short sum;
struct wr_udp_addr addr;
/* if there is no user-provided uaddr, we are replying */
if (!uaddr) {
memcpy(&addr.daddr, buf + IP_SOURCE, 4);
memcpy(&addr.saddr, buf + IP_DEST, 4);
memcpy(&addr.dport, buf + UDP_SPORT, 2);
memcpy(&addr.sport, buf + UDP_DPORT, 2);
uaddr = &addr;
}
// ------------ UDP -------------
memcpy(buf + UDP_VIRT_SADDR, &uaddr->saddr, 4);
memcpy(buf + UDP_VIRT_DADDR, &uaddr->daddr, 4);
buf[UDP_VIRT_ZEROS] = 0;
buf[UDP_VIRT_PROTO] = 0x11; /* UDP */
buf[UDP_VIRT_LENGTH] = (len - IP_END) >> 8;
buf[UDP_VIRT_LENGTH + 1] = (len - IP_END) & 0xff;
memcpy(buf + UDP_SPORT, &uaddr->sport, 2);
memcpy(buf + UDP_DPORT, &uaddr->dport, 2);
buf[UDP_LENGTH] = (len - IP_END) >> 8;
buf[UDP_LENGTH + 1] = (len - IP_END) & 0xff;
buf[UDP_CHECKSUM] = 0;
buf[UDP_CHECKSUM + 1] = 0;
sum =
ipv4_checksum((unsigned short *)(buf + UDP_VIRT_SADDR),
(len - UDP_VIRT_SADDR) / 2);
if (sum == 0)
sum = 0xFFFF;
buf[UDP_CHECKSUM + 0] = (sum >> 8);
buf[UDP_CHECKSUM + 1] = sum & 0xff;
// ------------ IP --------------
buf[IP_VERSION] = 0x45;
buf[IP_TOS] = 0;
buf[IP_LEN + 0] = len >> 8;
buf[IP_LEN + 1] = len & 0xff;
buf[IP_ID + 0] = 0;
buf[IP_ID + 1] = 0;
buf[IP_FLAGS + 0] = 0;
buf[IP_FLAGS + 1] = 0;
buf[IP_TTL] = 63;
buf[IP_PROTOCOL] = 17; /* UDP */
buf[IP_CHECKSUM + 0] = 0;
buf[IP_CHECKSUM + 1] = 0;
memcpy(buf + IP_SOURCE, &uaddr->saddr, 4);
memcpy(buf + IP_DEST, &uaddr->daddr, 4);
sum =
ipv4_checksum((unsigned short *)(buf + IP_VERSION),
(IP_END - IP_VERSION) / 2);
buf[IP_CHECKSUM + 0] = sum >> 8;
buf[IP_CHECKSUM + 1] = sum & 0xff;
return;
}
......@@ -41,7 +41,7 @@ static const int _ytab[2][12] = {
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
char *format_time(uint64_t sec)
char *format_time(uint64_t sec, int format)
{
struct tm t;
static char buf[64];
......@@ -69,9 +69,23 @@ char *format_time(uint64_t sec)
t.tm_mday = dayno + 1;
t.tm_isdst = 0;
sprintf(buf, "%s, %s %d, %d, %02d:%02d:%02d", _days[t.tm_wday],
_months[t.tm_mon], t.tm_mday, t.tm_year + YEAR0, t.tm_hour,
t.tm_min, t.tm_sec);
switch(format) {
case TIME_FORMAT_LEGACY:
default:
sprintf(buf, "%s, %s %d, %d, %02d:%02d:%02d", _days[t.tm_wday],
_months[t.tm_mon], t.tm_mday, t.tm_year + YEAR0,
t.tm_hour, t.tm_min, t.tm_sec);
break;
case TIME_FORMAT_SYSLOG:
sprintf(buf, "%s %2d %02d:%02d:%02d", _months[t.tm_mon],
t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
break;
case TIME_FORMAT_SORTED:
sprintf(buf, "%4d-%02d-%02d-%02d:%02d:%02d",
t.tm_year + YEAR0, t.tm_mon + 1, t.tm_mday,
t.tm_hour, t.tm_min, t.tm_sec);
break;
}
return buf;
}
......
......@@ -110,7 +110,7 @@ void wrc_mon_gui(void)
shw_pps_gen_get_time(&sec, &nsec);
cprintf(C_BLUE, "\n\nTAI Time: ");
cprintf(C_WHITE, "%s", format_time(sec));
cprintf(C_WHITE, "%s", format_time(sec, TIME_FORMAT_LEGACY));
/*show_ports */
wrpc_get_port_state(&state, NULL);
......
ppsi @ 43635331
Subproject commit b203cc96df8d4008fe311deaf7baab8e555d5c96
Subproject commit 43635331c54fa906bf54ad75e3087e336bdc7799
......@@ -15,7 +15,7 @@
#include "shell.h"
#include "../lib/ipv4.h"
static void decode_ip(const char *str, unsigned char *ip)
void decode_ip(const char *str, unsigned char *ip)
{
int i, x;
......@@ -28,9 +28,17 @@ static void decode_ip(const char *str, unsigned char *ip)
}
}
char *format_ip(char *s, const unsigned char *ip)
{
pp_sprintf(s, "%d.%d.%d.%d",
ip[0], ip[1], ip[2], ip[3]);
return s;
}
static int cmd_ip(const char *args[])
{
unsigned char ip[4];
char buf[20];
if (!args[0] || !strcasecmp(args[0], "get")) {
getIP(ip);
......@@ -44,8 +52,7 @@ static int cmd_ip(const char *args[])
if (needIP) {
pp_printf("IP-address: in training\n");
} else {
pp_printf("IP-address: %d.%d.%d.%d\n",
ip[0], ip[1], ip[2], ip[3]);
pp_printf("IP-address: %s\n", format_ip(buf, ip));
}
return 0;
}
......
......@@ -17,7 +17,7 @@
#include "endpoint.h"
#include "../lib/ipv4.h"
static void decode_mac(const char *str, unsigned char *mac)
void decode_mac(const char *str, unsigned char *mac)
{
int i, x;
......@@ -30,9 +30,18 @@ static void decode_mac(const char *str, unsigned char *mac)
}
}
char *format_mac(char *s, const unsigned char *mac)
{
pp_sprintf(s, "%02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return s;
}
static int cmd_mac(const char *args[])
{
unsigned char mac[6];
char buf[32];
if (!args[0] || !strcasecmp(args[0], "get")) {
/* get current MAC */
......@@ -52,8 +61,7 @@ static int cmd_mac(const char *args[])
return -EINVAL;
}
pp_printf("MAC-address: %02x:%02x:%02x:%02x:%02x:%02x\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
pp_printf("MAC-address: %s\n", format_mac(buf, mac));
return 0;
}
......
......@@ -53,7 +53,9 @@ static int cmd_time(const char *args[])
return 0;
}
pp_printf("%s +%d nanoseconds.\n", format_time(sec), nsec); /* fixme: clock freq is not always 125 MHz */
pp_printf("%s +%d nanoseconds.\n",
format_time(sec, TIME_FORMAT_LEGACY), nsec);
/* fixme: clock freq is not always 125 MHz */
return 0;
}
......
......@@ -409,6 +409,7 @@ void pfilter_init(int mode, char *fname)
pfilter_cmp(18, 0x0044, 0xffff, MOV, PORT_UDP_HOST); /* bootpc */
pfilter_cmp(18, 0x013f, 0xffff, OR, PORT_UDP_HOST); /* ptp event */
pfilter_cmp(18, 0x0140, 0xffff, OR, PORT_UDP_HOST); /* ptp general */
pfilter_cmp(18, 0x0025, 0xffff, OR, PORT_UDP_HOST); /* rdate */
/* The CPU gets those ports in a proper UDP frame, plus the previous selections */
pfilter_logic3(FRAME_FOR_CPU, FRAME_UDP, AND, PORT_UDP_HOST, OR, FRAME_FOR_CPU);
......
......@@ -96,11 +96,6 @@ static void wrc_initialize(void)
}
}
#define LINK_WENT_UP 1
#define LINK_WENT_DOWN 2
#define LINK_UP 3
#define LINK_DOWN 4
static int wrc_check_link(void)
{
static int prev_link_state = -1;
......@@ -184,24 +179,20 @@ int main(void)
}
switch (l_status) {
case LINK_WENT_DOWN:
if (wrc_ptp_get_mode() == WRC_MODE_SLAVE) {
spll_init(SPLL_MODE_FREE_RUNNING_MASTER, 0, 1);
shw_pps_gen_enable_output(0);
}
/* fall through */
case LINK_WENT_UP:
needIP = 1;
break;
case LINK_UP:
update_rx_queues();
if (HAS_IP) {
ipv4_poll();
ipv4_poll(l_status);
arp_poll();
}
break;
case LINK_WENT_DOWN:
if (wrc_ptp_get_mode() == WRC_MODE_SLAVE) {
spll_init(SPLL_MODE_FREE_RUNNING_MASTER, 0, 1);
shw_pps_gen_enable_output(0);
}
break;
}
ui_update();
......
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