Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
White Rabbit Switch - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
86
Issues
86
List
Board
Labels
Milestones
Merge Requests
4
Merge Requests
4
CI / CD
CI / CD
Pipelines
Schedules
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
White Rabbit Switch - Software
Commits
ca626c92
Commit
ca626c92
authored
Nov 25, 2013
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
userspace: copy libptpnetif from ptp-noposix
Signed-off-by:
Alessandro Rubini
<
rubini@gnudd.com
>
parent
a5b624eb
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
1152 additions
and
6 deletions
+1152
-6
Makefile
userspace/Makefile
+1
-1
Makefile
userspace/libptpnetif/Makefile
+24
-0
hal_client.c
userspace/libptpnetif/hal_client.c
+109
-0
hal_client.h
userspace/libptpnetif/hal_client.h
+11
-0
ptpd_netif.c
userspace/libptpnetif/ptpd_netif.c
+760
-0
ptpd_netif.h
userspace/libptpnetif/ptpd_netif.h
+242
-0
Makefile
userspace/tools/Makefile
+2
-2
Makefile
userspace/wrsw_rtud/Makefile
+3
-3
No files found.
userspace/Makefile
View file @
ca626c92
...
...
@@ -12,7 +12,7 @@ WR_INSTALL_ROOT ?= $(WRS_OUTPUT_DIR)/images/wr
WRDEV_DIR
?=
$(WRS_BASE_DIR)
/..
# subdirectories we want to compile
SUBDIRS
=
mini-rpc libswitchhw wrsw_hal wrsw_rtud tools
SUBDIRS
=
libptpnetif
mini-rpc libswitchhw wrsw_hal wrsw_rtud tools
# all variables are exported
export
...
...
userspace/libptpnetif/Makefile
0 → 100644
View file @
ca626c92
AS
=
$(CROSS_COMPILE)
as
LD
=
$(CROSS_COMPILE)
ld
CC
=
$(CROSS_COMPILE)
gcc
CPP
=
$(CC)
-E
AR
=
$(CROSS_COMPILE)
ar
NM
=
$(CROSS_COMPILE)
nm
STRIP
=
$(CROSS_COMPILE)
strip
OBJCOPY
=
$(CROSS_COMPILE)
objcopy
OBJDUMP
=
$(CROSS_COMPILE)
objdump
CFLAGS
=
-Wall
-ggdb
-O2
-I
../wrsw_hal
-I
../mini-rpc
all
:
libptpnetif.a
libptpnetif.a
:
ptpd_netif.o hal_client.o
$(AR)
r
$@
$^
clean
:
rm
-f
*
.a
*
.o
*
~
install
:
@
echo
"We have no install rule by now"
userspace/libptpnetif/hal_client.c
0 → 100644
View file @
ca626c92
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <minipc.h>
#define HAL_EXPORT_STRUCTURES
#include "hal_exports.h"
#define DEFAULT_TO 200000
/* ms */
static
struct
minipc_ch
*
hal_ch
;
int
halexp_check_running
()
{
//int res_int;
//return wripc_call(hal_ipc, "halexp_check_running", ;
return
0
;
}
int
halexp_reset_port
(
const
char
*
port_name
)
{
// TRACE(TRACE_INFO, "resetting port %s\n", port_name);
return
0
;
}
int
halexp_calibration_cmd
(
const
char
*
port_name
,
int
command
,
int
on_off
)
{
int
ret
,
rval
;
ret
=
minipc_call
(
hal_ch
,
DEFAULT_TO
,
&
__rpcdef_calibration_cmd
,
&
rval
,
port_name
,
command
,
on_off
);
if
(
ret
<
0
)
return
ret
;
return
rval
;
}
int
halexp_lock_cmd
(
const
char
*
port_name
,
int
command
,
int
priority
)
{
int
ret
,
rval
;
ret
=
minipc_call
(
hal_ch
,
DEFAULT_TO
,
&
__rpcdef_lock_cmd
,
&
rval
,
port_name
,
command
,
priority
);
if
(
ret
<
0
)
return
ret
;
return
rval
;
}
int
halexp_query_ports
(
hexp_port_list_t
*
list
)
{
int
ret
;
ret
=
minipc_call
(
hal_ch
,
DEFAULT_TO
,
&
__rpcdef_query_ports
,
list
/* return val */
);
return
ret
;
}
int
halexp_get_port_state
(
hexp_port_state_t
*
state
,
const
char
*
port_name
)
{
int
ret
;
ret
=
minipc_call
(
hal_ch
,
DEFAULT_TO
,
&
__rpcdef_get_port_state
,
state
/* retval */
,
port_name
);
return
ret
;
}
int
halexp_pps_cmd
(
int
cmd
,
hexp_pps_params_t
*
params
)
{
int
ret
,
rval
;
ret
=
minipc_call
(
hal_ch
,
DEFAULT_TO
,
&
__rpcdef_pps_cmd
,
&
rval
,
cmd
,
params
);
if
(
ret
<
0
)
return
ret
;
return
rval
;
}
int
halexp_get_timing_state
(
hexp_timing_state_t
*
tstate
)
{
int
ret
;
ret
=
minipc_call
(
hal_ch
,
DEFAULT_TO
,
&
__rpcdef_get_timing_state
,
tstate
);
if
(
ret
<
0
)
return
ret
;
return
0
;
}
int
halexp_client_try_connect
(
int
retries
,
int
timeout
)
{
for
(;;)
{
hal_ch
=
minipc_client_create
(
WRSW_HAL_SERVER_ADDR
,
MINIPC_FLAG_VERBOSE
);
if
(
hal_ch
==
0
)
retries
--
;
else
return
0
;
if
(
!
retries
)
return
-
1
;
usleep
(
timeout
);
}
return
-
1
;
}
int
halexp_client_init
()
{
return
halexp_client_try_connect
(
0
,
0
);
}
\ No newline at end of file
userspace/libptpnetif/hal_client.h
0 → 100644
View file @
ca626c92
#ifndef __HAL_CLIENT_H
#define __HAL_CLIENT_H
#include "hal_exports.h"
int
halexp_client_init
();
int
halexp_client_try_connect
(
int
retries
,
int
timeout
);
#endif
userspace/libptpnetif/ptpd_netif.c
0 → 100644
View file @
ca626c92
// Wrapper functions for network/timestamping/adjustment operations
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <linux/net_tstamp.h>
#include <linux/errqueue.h>
#include <linux/sockios.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <asm/types.h>
#include <fcntl.h>
#include <errno.h>
#include <asm/socket.h>
#include "ptpd_netif.h"
#include "hal_client.h"
#ifdef NETIF_VERBOSE
#define netif_dbg(...) printf(__VA_ARGS__)
#else
#define netif_dbg(...)
#endif
#define ETHER_MTU 1518
#define DMTD_UPDATE_INTERVAL 500
struct
scm_timestamping
{
struct
timespec
systime
;
struct
timespec
hwtimetrans
;
struct
timespec
hwtimeraw
;
};
PACKED
struct
etherpacket
{
struct
ethhdr
ether
;
char
data
[
ETHER_MTU
];
};
typedef
struct
{
uint64_t
start_tics
;
uint64_t
timeout
;
}
timeout_t
;
struct
my_socket
{
int
fd
;
wr_sockaddr_t
bind_addr
;
mac_addr_t
local_mac
;
int
if_index
;
// parameters for linearization of RX timestamps
uint32_t
clock_period
;
uint32_t
phase_transition
;
uint32_t
dmtd_phase
;
int
dmtd_phase_valid
;
timeout_t
dmtd_update_tmo
;
};
static
uint64_t
get_tics
()
{
struct
timezone
tz
=
{
0
,
0
};
struct
timeval
tv
;
gettimeofday
(
&
tv
,
&
tz
);
return
(
uint64_t
)
tv
.
tv_sec
*
1000000ULL
+
(
uint64_t
)
tv
.
tv_usec
;
}
static
inline
int
tmo_init
(
timeout_t
*
tmo
,
uint32_t
milliseconds
)
{
tmo
->
start_tics
=
get_tics
();
tmo
->
timeout
=
(
uint64_t
)
milliseconds
*
1000ULL
;
return
0
;
}
static
inline
int
tmo_restart
(
timeout_t
*
tmo
)
{
tmo
->
start_tics
=
get_tics
();
return
0
;
}
static
inline
int
tmo_expired
(
timeout_t
*
tmo
)
{
return
(
get_tics
()
-
tmo
->
start_tics
>
tmo
->
timeout
);
}
// cheks if x is inside range <min, max>
static
inline
int
inside_range
(
int
min
,
int
max
,
int
x
)
{
if
(
min
<
max
)
return
(
x
>=
min
&&
x
<=
max
);
else
return
(
x
<=
max
||
x
>=
min
);
}
/* For debugging/testing purposes */
int
ptpd_netif_get_dmtd_phase
(
wr_socket_t
*
sock
,
int32_t
*
phase
)
{
struct
my_socket
*
s
=
(
struct
my_socket
*
)
sock
;
hexp_port_state_t
pstate
;
halexp_get_port_state
(
&
pstate
,
s
->
bind_addr
.
if_name
);
if
(
phase
)
*
phase
=
pstate
.
phase_val
;
return
pstate
.
phase_val_valid
;
}
static
void
update_dmtd
(
wr_socket_t
*
sock
)
{
struct
my_socket
*
s
=
(
struct
my_socket
*
)
sock
;
hexp_port_state_t
pstate
;
if
(
tmo_expired
(
&
s
->
dmtd_update_tmo
))
{
halexp_get_port_state
(
&
pstate
,
s
->
bind_addr
.
if_name
);
// FIXME: ccheck if phase value is ready
s
->
dmtd_phase
=
pstate
.
phase_val
;
s
->
dmtd_phase_valid
=
pstate
.
phase_val_valid
;
tmo_restart
(
&
s
->
dmtd_update_tmo
);
}
}
void
ptpd_netif_linearize_rx_timestamp
(
wr_timestamp_t
*
ts
,
int32_t
dmtd_phase
,
int
cntr_ahead
,
int
transition_point
,
int
clock_period
)
{
int
trip_lo
,
trip_hi
;
int
phase
;
// "phase" transition: DMTD output value (in picoseconds)
// at which the transition of rising edge
// TS counter will appear
ts
->
raw_phase
=
dmtd_phase
;
phase
=
clock_period
-
1
-
dmtd_phase
;
// calculate the range within which falling edge timestamp is stable
// (no possible transitions)
trip_lo
=
transition_point
-
clock_period
/
4
;
if
(
trip_lo
<
0
)
trip_lo
+=
clock_period
;
trip_hi
=
transition_point
+
clock_period
/
4
;
if
(
trip_hi
>=
clock_period
)
trip_hi
-=
clock_period
;
if
(
inside_range
(
trip_lo
,
trip_hi
,
phase
))
{
// We are within +- 25% range of transition area of
// rising counter. Take the falling edge counter value as the
// "reliable" one. cntr_ahead will be 1 when the rising edge
//counter is 1 tick ahead of the falling edge counter
ts
->
nsec
-=
cntr_ahead
?
(
clock_period
/
1000
)
:
0
;
// check if the phase is before the counter transition value
// and eventually increase the counter by 1 to simulate a
// timestamp transition exactly at s->phase_transition
//DMTD phase value
if
(
inside_range
(
trip_lo
,
transition_point
,
phase
))
ts
->
nsec
+=
clock_period
/
1000
;
}
ts
->
phase
=
phase
-
transition_point
-
1
;
if
(
ts
->
phase
<
0
)
ts
->
phase
+=
clock_period
;
ts
->
phase
=
clock_period
-
1
-
ts
->
phase
;
}
#define HAL_CONNECT_RETRIES 1000
#define HAL_CONNECT_TIMEOUT 2000000
/* us */
int
ptpd_netif_init
()
{
if
(
halexp_client_try_connect
(
HAL_CONNECT_RETRIES
,
HAL_CONNECT_TIMEOUT
)
<
0
)
return
PTPD_NETIF_ERROR
;
return
PTPD_NETIF_OK
;
}
wr_socket_t
*
ptpd_netif_create_socket
(
int
sock_type
,
int
flags
,
wr_sockaddr_t
*
bind_addr
)
{
struct
my_socket
*
s
;
struct
sockaddr_ll
sll
;
struct
ifreq
f
;
hexp_port_state_t
pstate
;
int
fd
;
// fprintf(stderr,"CreateSocket!\n");
if
(
sock_type
!=
PTPD_SOCK_RAW_ETHERNET
)
return
NULL
;
if
(
halexp_get_port_state
(
&
pstate
,
bind_addr
->
if_name
)
<
0
)
return
NULL
;
fd
=
socket
(
PF_PACKET
,
SOCK_RAW
,
htons
(
ETH_P_ALL
));
if
(
fd
<
0
)
{
perror
(
"socket()"
);
return
NULL
;
}
fcntl
(
fd
,
F_SETFL
,
O_NONBLOCK
);
// Put the controller in promiscious mode, so it receives everything
strcpy
(
f
.
ifr_name
,
bind_addr
->
if_name
);
if
(
ioctl
(
fd
,
SIOCGIFFLAGS
,
&
f
)
<
0
)
{
perror
(
"ioctl()"
);
return
NULL
;
}
f
.
ifr_flags
|=
IFF_PROMISC
;
if
(
ioctl
(
fd
,
SIOCSIFFLAGS
,
&
f
)
<
0
)
{
perror
(
"ioctl()"
);
return
NULL
;
}
// Find the inteface index
strcpy
(
f
.
ifr_name
,
bind_addr
->
if_name
);
ioctl
(
fd
,
SIOCGIFINDEX
,
&
f
);
sll
.
sll_ifindex
=
f
.
ifr_ifindex
;
sll
.
sll_family
=
AF_PACKET
;
sll
.
sll_protocol
=
htons
(
bind_addr
->
ethertype
);
sll
.
sll_halen
=
6
;
memcpy
(
sll
.
sll_addr
,
bind_addr
->
mac
,
6
);
if
(
bind
(
fd
,
(
struct
sockaddr
*
)
&
sll
,
sizeof
(
struct
sockaddr_ll
))
<
0
)
{
close
(
fd
);
perror
(
"bind()"
);
return
NULL
;
}
// timestamping stuff:
int
so_timestamping_flags
=
SOF_TIMESTAMPING_TX_HARDWARE
|
SOF_TIMESTAMPING_RX_HARDWARE
|
SOF_TIMESTAMPING_RAW_HARDWARE
;
struct
ifreq
ifr
;
struct
hwtstamp_config
hwconfig
;
strncpy
(
ifr
.
ifr_name
,
bind_addr
->
if_name
,
sizeof
(
ifr
.
ifr_name
));
hwconfig
.
tx_type
=
HWTSTAMP_TX_ON
;
hwconfig
.
rx_filter
=
HWTSTAMP_FILTER_PTP_V2_L2_EVENT
;
ifr
.
ifr_data
=
&
hwconfig
;
if
(
ioctl
(
fd
,
SIOCSHWTSTAMP
,
&
ifr
)
<
0
)
{
perror
(
"SIOCSHWTSTAMP"
);
return
NULL
;
}
if
(
setsockopt
(
fd
,
SOL_SOCKET
,
SO_TIMESTAMPING
,
&
so_timestamping_flags
,
sizeof
(
int
))
<
0
)
{
perror
(
"setsockopt(SO_TIMESTAMPING)"
);
return
NULL
;
}
s
=
calloc
(
sizeof
(
struct
my_socket
),
1
);
if
(
!
s
)
return
NULL
;
s
->
if_index
=
f
.
ifr_ifindex
;
// get interface MAC address
if
(
ioctl
(
fd
,
SIOCGIFHWADDR
,
&
f
)
<
0
)
{
perror
(
"ioctl()"
);
return
NULL
;
}
memcpy
(
s
->
local_mac
,
f
.
ifr_hwaddr
.
sa_data
,
6
);
memcpy
(
&
s
->
bind_addr
,
bind_addr
,
sizeof
(
wr_sockaddr_t
));
s
->
fd
=
fd
;
// store the linearization parameters
s
->
clock_period
=
pstate
.
clock_period
;
s
->
phase_transition
=
pstate
.
t2_phase_transition
;
s
->
dmtd_phase_valid
=
0
;
s
->
dmtd_phase
=
pstate
.
phase_val
;
tmo_init
(
&
s
->
dmtd_update_tmo
,
DMTD_UPDATE_INTERVAL
);
return
(
wr_socket_t
*
)
s
;
}
int
ptpd_netif_close_socket
(
wr_socket_t
*
sock
)
{
struct
my_socket
*
s
=
(
struct
my_socket
*
)
sock
;
if
(
!
s
)
return
0
;
close
(
s
->
fd
);
free
(
s
);
return
0
;
}
static
void
poll_tx_timestamp
(
wr_socket_t
*
sock
,
wr_timestamp_t
*
tx_timestamp
);
int
ptpd_netif_sendto
(
wr_socket_t
*
sock
,
wr_sockaddr_t
*
to
,
void
*
data
,
size_t
data_length
,
wr_timestamp_t
*
tx_ts
)
{
struct
etherpacket
pkt
;
struct
my_socket
*
s
=
(
struct
my_socket
*
)
sock
;
struct
sockaddr_ll
sll
;
int
rval
;
if
(
s
->
bind_addr
.
family
!=
PTPD_SOCK_RAW_ETHERNET
)
return
-
ENOTSUP
;
if
(
data_length
>
ETHER_MTU
-
8
)
return
-
EINVAL
;
memset
(
&
pkt
,
0
,
sizeof
(
struct
etherpacket
));
memcpy
(
pkt
.
ether
.
h_dest
,
to
->
mac
,
6
);
memcpy
(
pkt
.
ether
.
h_source
,
s
->
local_mac
,
6
);
pkt
.
ether
.
h_proto
=
htons
(
to
->
ethertype
);
memcpy
(
pkt
.
data
,
data
,
data_length
);
size_t
len
=
data_length
+
sizeof
(
struct
ethhdr
);
if
(
len
<
60
)
/* pad to the minimum allowed packet size */
len
=
60
;
memset
(
&
sll
,
0
,
sizeof
(
struct
sockaddr_ll
));
sll
.
sll_ifindex
=
s
->
if_index
;
sll
.
sll_family
=
AF_PACKET
;
sll
.
sll_protocol
=
htons
(
to
->
ethertype
);
sll
.
sll_halen
=
6
;
rval
=
sendto
(
s
->
fd
,
&
pkt
,
len
,
0
,
(
struct
sockaddr
*
)
&
sll
,
sizeof
(
struct
sockaddr_ll
));
poll_tx_timestamp
(
sock
,
tx_ts
);
return
rval
;
}
#if 0
static void hdump(uint8_t *buf, int size)
{
int i;
netif_dbg("Dump: ");
for(i=0;i<size;i++) netif_dbg("%02x ", buf[i]);
netif_dbg("\n");
}
#endif
/* Waits for the transmission timestamp and stores it in tx_timestamp (if not null). */
static
void
poll_tx_timestamp
(
wr_socket_t
*
sock
,
wr_timestamp_t
*
tx_timestamp
)
{
char
data
[
16384
];
struct
my_socket
*
s
=
(
struct
my_socket
*
)
sock
;
struct
msghdr
msg
;
struct
iovec
entry
;
struct
sockaddr_ll
from_addr
;
struct
{
struct
cmsghdr
cm
;
char
control
[
1024
];
}
control
;
struct
cmsghdr
*
cmsg
;
int
res
;
uint32_t
rtag
;
struct
sock_extended_err
*
serr
=
NULL
;
struct
scm_timestamping
*
sts
=
NULL
;
memset
(
&
msg
,
0
,
sizeof
(
msg
));
msg
.
msg_iov
=
&
entry
;
msg
.
msg_iovlen
=
1
;
entry
.
iov_base
=
data
;
entry
.
iov_len
=
sizeof
(
data
);
msg
.
msg_name
=
(
caddr_t
)
&
from_addr
;
msg
.
msg_namelen
=
sizeof
(
from_addr
);
msg
.
msg_control
=
&
control
;
msg
.
msg_controllen
=
sizeof
(
control
);
res
=
recvmsg
(
s
->
fd
,
&
msg
,
MSG_ERRQUEUE
);
//|MSG_DONTWAIT);
if
(
tx_timestamp
)
tx_timestamp
->
correct
=
0
;
if
(
res
<=
0
)
return
;
memcpy
(
&
rtag
,
data
+
res
-
4
,
4
);
for
(
cmsg
=
CMSG_FIRSTHDR
(
&
msg
);
cmsg
;
cmsg
=
CMSG_NXTHDR
(
&
msg
,
cmsg
))
{
void
*
dp
=
CMSG_DATA
(
cmsg
);
if
(
cmsg
->
cmsg_level
==
SOL_PACKET
&&
cmsg
->
cmsg_type
==
PACKET_TX_TIMESTAMP
)
serr
=
(
struct
sock_extended_err
*
)
dp
;
if
(
cmsg
->
cmsg_level
==
SOL_SOCKET
&&
cmsg
->
cmsg_type
==
SO_TIMESTAMPING
)
sts
=
(
struct
scm_timestamping
*
)
dp
;
//fprintf(stderr, "Serr %x sts %x\n", serr, sts);
if
(
serr
&&
sts
&&
tx_timestamp
)
{
tx_timestamp
->
correct
=
1
;
tx_timestamp
->
phase
=
0
;
tx_timestamp
->
nsec
=
sts
->
hwtimeraw
.
tv_nsec
;
tx_timestamp
->
sec
=
(
uint64_t
)
sts
->
hwtimeraw
.
tv_sec
&
0x7fffffff
;
}
}
}
int
ptpd_netif_recvfrom
(
wr_socket_t
*
sock
,
wr_sockaddr_t
*
from
,
void
*
data
,
size_t
data_length
,
wr_timestamp_t
*
rx_timestamp
)
{
struct
my_socket
*
s
=
(
struct
my_socket
*
)
sock
;
struct
etherpacket
pkt
;
struct
msghdr
msg
;
struct
iovec
entry
;
struct
sockaddr_ll
from_addr
;
struct
{
struct
cmsghdr
cm
;
char
control
[
1024
];
}
control
;
struct
cmsghdr
*
cmsg
;
struct
scm_timestamping
*
sts
=
NULL
;
size_t
len
=
data_length
+
sizeof
(
struct
ethhdr
);
memset
(
&
msg
,
0
,
sizeof
(
msg
));
msg
.
msg_iov
=
&
entry
;
msg
.
msg_iovlen
=
1
;
entry
.
iov_base
=
&
pkt
;
entry
.
iov_len
=
len
;
msg
.
msg_name
=
(
caddr_t
)
&
from_addr
;
msg
.
msg_namelen
=
sizeof
(
from_addr
);
msg
.
msg_control
=
&
control
;
msg
.
msg_controllen
=
sizeof
(
control
);
int
ret
=
recvmsg
(
s
->
fd
,
&
msg
,
MSG_DONTWAIT
);
if
(
ret
<
0
&&
errno
==
EAGAIN
)
return
0
;
// would be blocking
if
(
ret
==
-
EAGAIN
)
return
0
;
if
(
ret
<=
0
)
return
ret
;
memcpy
(
data
,
pkt
.
data
,
ret
-
sizeof
(
struct
ethhdr
));
from
->
ethertype
=
ntohs
(
pkt
.
ether
.
h_proto
);
memcpy
(
from
->
mac
,
pkt
.
ether
.
h_source
,
6
);
memcpy
(
from
->
mac_dest
,
pkt
.
ether
.
h_dest
,
6
);
if
(
rx_timestamp
)
rx_timestamp
->
correct
=
0
;
for
(
cmsg
=
CMSG_FIRSTHDR
(
&
msg
);
cmsg
;
cmsg
=
CMSG_NXTHDR
(
&
msg
,
cmsg
))
{
void
*
dp
=
CMSG_DATA
(
cmsg
);
if
(
cmsg
->
cmsg_level
==
SOL_SOCKET
&&
cmsg
->
cmsg_type
==
SO_TIMESTAMPING
)
sts
=
(
struct
scm_timestamping
*
)
dp
;
}
if
(
sts
&&
rx_timestamp
)
{
int
cntr_ahead
=
sts
->
hwtimeraw
.
tv_sec
&
0x80000000
?
1
:
0
;
rx_timestamp
->
nsec
=
sts
->
hwtimeraw
.
tv_nsec
;
rx_timestamp
->
sec
=
(
uint64_t
)
sts
->
hwtimeraw
.
tv_sec
&
0x7fffffff
;
rx_timestamp
->
raw_nsec
=
sts
->
hwtimeraw
.
tv_nsec
;
rx_timestamp
->
raw_ahead
=
cntr_ahead
;
update_dmtd
(
sock
);
if
(
s
->
dmtd_phase_valid
)
{
ptpd_netif_linearize_rx_timestamp
(
rx_timestamp
,
s
->
dmtd_phase
,
cntr_ahead
,
s
->
phase_transition
,
s
->
clock_period
);
rx_timestamp
->
correct
=
1
;
}
}
return
ret
-
sizeof
(
struct
ethhdr
);
}
/*
* Turns on locking
*/
int
ptpd_netif_locking_enable
(
int
txrx
,
const
char
*
ifaceName
,
int
priority
)
{
netif_dbg
(
"(PTPD_NETIF): start locking
\n
"
);
int
ret
=
halexp_lock_cmd
(
ifaceName
,
HEXP_LOCK_CMD_START
,
0
);
return
(
ret
<
0
?
PTPD_NETIF_ERROR
:
PTPD_NETIF_OK
);
}
int
ptpd_netif_locking_disable
(
int
txrx
,
const
char
*
ifaceName
,
int
priority
)
{
return
PTPD_NETIF_OK
;
}
int
ptpd_netif_locking_poll
(
int
txrx
,
const
char
*
ifaceName
,
int
priority
)
{
if
(
halexp_lock_cmd
(
ifaceName
,
HEXP_LOCK_CMD_CHECK
,
0
)
==
HEXP_LOCK_STATUS_LOCKED
)
return
PTPD_NETIF_READY
;
else
return
PTPD_NETIF_NOT_READY
;
}
/* We don't need these functions in V3/spec anymore - the transceivers are deterministic! */
int
ptpd_netif_calibration_pattern_enable
(
const
char
*
ifaceName
,
unsigned
int
calibrationPeriod
,
unsigned
int
calibrationPattern
,
unsigned
int
calibrationPatternLen
)
{
return
PTPD_NETIF_OK
;
}
int
ptpd_netif_calibrating_disable
(
int
txrx
,
const
char
*
ifaceName
)
{
return
PTPD_NETIF_OK
;
}
int
ptpd_netif_calibrating_enable
(
int
txrx
,
const
char
*
ifaceName
)
{
return
PTPD_NETIF_OK
;
}
int
ptpd_netif_calibrating_poll
(
int
txrx
,
const
char
*
ifaceName
,
uint64_t
*
delta
)
{
uint64_t
delta_rx
,
delta_tx
;
ptpd_netif_read_calibration_data
(
ifaceName
,
&
delta_tx
,
&
delta_rx
,
NULL
,
NULL
);
if
(
txrx
==
PTPD_NETIF_TX
)
*
delta
=
delta_tx
;
else
*
delta
=
delta_rx
;
return
PTPD_NETIF_READY
;
}
int
ptpd_netif_calibration_pattern_disable
(
const
char
*
ifaceName
)
{
return
PTPD_NETIF_OK
;
}
int
ptpd_netif_read_calibration_data
(
const
char
*
ifaceName
,
uint64_t
*
deltaTx
,
uint64_t
*
deltaRx
,
int32_t
*
fix_alpha
,
int32_t
*
clock_period
)
{
hexp_port_state_t
state
;
//read the port state
halexp_get_port_state
(
&
state
,
ifaceName
);
// check if the data is available
if
(
state
.
valid
&&
state
.
tx_calibrated
&&
state
.
rx_calibrated
)
{
fprintf
(
stderr
,
"servo:ifaceName: %s (%d / %d)
\n
"
,
ifaceName
,
state
.
delta_tx
,
state
.
delta_rx
);
if
(
deltaTx
)
*
deltaTx
=
state
.
delta_tx
;
if
(
deltaRx
)
*
deltaRx
=
state
.
delta_rx
;
if
(
fix_alpha
)
*
fix_alpha
=
state
.
fiber_fix_alpha
;
if
(
clock_period
)
*
clock_period
=
state
.
clock_period
;
return
PTPD_NETIF_OK
;
}
return
PTPD_NETIF_NOT_FOUND
;
}
int
ptpd_netif_select
(
wr_socket_t
*
wrSock
)
{
struct
my_socket
*
s
=
(
struct
my_socket
*
)
wrSock
;
int
ret
;
fd_set
readfds
;
FD_ZERO
(
&
readfds
);
FD_SET
(
s
->
fd
,
&
readfds
);
ret
=
select
(
s
->
fd
+
1
,
&
readfds
,
0
,
0
,
0
)
>
0
;
if
(
ret
<
0
)
{
if
(
errno
==
EAGAIN
||
errno
==
EINTR
)
return
0
;
}
return
1
;
}
int
ptpd_netif_get_hw_addr
(
wr_socket_t
*
sock
,
mac_addr_t
*
mac
)
{
struct
my_socket
*
s
=
(
struct
my_socket
*
)
sock
;
memcpy
(
mac
,
s
->
local_mac
,
6
);
return
0
;
}
int
ptpd_netif_get_port_state
(
const
char
*
ifaceName
)
{
hexp_port_state_t
state
;
//read the port state
halexp_get_port_state
(
&
state
,
ifaceName
);
// check if the data is available
if
(
state
.
valid
)
{
//check if link is UP
if
(
state
.
up
>
0
)
return
PTPD_NETIF_OK
;
else
{
// if(!strcmp(ifaceName,"wru1") || !strcmp(ifaceName,"wru0"))
// printf("(ptpd_netif) linkdown detected on port: %s\n",ifaceName);
return
PTPD_NETIF_ERROR
;
}
}
/* printf("(ptpd_netif) linkdown detected on port: %s "
"[no valid port state data)\n",ifaceName);*/
//should not get here
return
PTPD_NETIF_ERROR
;
}
int
ptpd_netif_extsrc_detection
()
{
return
0
;
}
int
ptpd_netif_get_ifName
(
char
*
ifname
,
int
number
)
{
int
i
;
int
j
=
0
;
hexp_port_list_t
list
;
halexp_query_ports
(
&
list
);
for
(
i
=
0
;
i
<
list
.
num_ports
;
i
++
)
{
if
(
j
==
number
)
{
strcpy
(
ifname
,
list
.
port_names
[
i
]);
return
PTPD_NETIF_OK
;
}
else
j
++
;
}
return
PTPD_NETIF_ERROR
;
}
uint64_t
ptpd_netif_get_msec_tics
()
{
// printf("getmsec: %lld\n", get_tics() / 1000ULL);
return
get_tics
()
/
1000ULL
;
}
int
ptpd_netif_adjust_counters
(
int64_t
adjust_sec
,
int32_t
adjust_nsec
)
{
hexp_pps_params_t
p
;
int
cmd
;
if
(
!
adjust_nsec
&&
!
adjust_sec
)
return
PTPD_NETIF_OK
;
if
(
adjust_sec
&&
adjust_nsec
)
{
fprintf
(
stderr
,
" FATAL : trying to adjust both the SEC and the NS counters simultaneously.
\n
"
);
exit
(
-
1
);
}
if
(
adjust_sec
)
{
cmd
=
HEXP_PPSG_CMD_ADJUST_SEC
;
p
.
adjust_sec
=
adjust_sec
;
}
else
{
cmd
=
HEXP_PPSG_CMD_ADJUST_NSEC
;
p
.
adjust_nsec
=
adjust_nsec
;
}
if
(
!
halexp_pps_cmd
(
cmd
,
&
p
))
return
PTPD_NETIF_OK
;
return
PTPD_NETIF_ERROR
;
}
int
ptpd_netif_adjust_phase
(
int32_t
phase_ps
)
{
hexp_pps_params_t
p
;
p
.
adjust_phase_shift
=
phase_ps
;
if
(
!
halexp_pps_cmd
(
HEXP_PPSG_CMD_ADJUST_PHASE
,
&
p
))
return
PTPD_NETIF_OK
;
return
PTPD_NETIF_ERROR
;
}
int
ptpd_netif_adjust_in_progress
()
{
hexp_pps_params_t
p
;
if
(
halexp_pps_cmd
(
HEXP_PPSG_CMD_POLL
,
&
p
))
return
PTPD_NETIF_OK
;
else
return
PTPD_NETIF_NOT_READY
;
}
int
ptpd_netif_enable_timing_output
(
int
enable
)
{
hexp_pps_params_t
p
;
p
.
pps_valid
=
enable
;
if
(
halexp_pps_cmd
(
HEXP_PPSG_CMD_SET_VALID
,
&
p
))
return
PTPD_NETIF_OK
;
else
return
PTPD_NETIF_NOT_READY
;
}
int
ptpd_netif_enable_phase_tracking
(
const
char
*
if_name
)
{
int
ret
=
halexp_lock_cmd
(
if_name
,
HEXP_LOCK_CMD_ENABLE_TRACKING
,
0
);
return
(
ret
<
0
?
PTPD_NETIF_ERROR
:
PTPD_NETIF_OK
);
}
userspace/libptpnetif/ptpd_netif.h
0 → 100644
View file @
ca626c92
// Network API for WR-PTPd
#ifndef __PTPD_NETIF_H
#define __PTPD_NETIF_H
#include <stdio.h>
//#include <inttypes.h>
#define PTPD_SOCK_RAW_ETHERNET 1
#define PTPD_SOCK_UDP 2
#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
// GCC-specific
#define PACKED __attribute__((packed))
#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
{
// Network interface name (eth0, ...)
char
if_name
[
IFACE_NAME_LEN
];
// Socket family (RAW ethernet/UDP)
int
family
;
// MAC address
mac_addr_t
mac
;
// Destination MASC address, filled by recvfrom() function on interfaces bound to multiple addresses
mac_addr_t
mac_dest
;
// IP address
ipv4_addr_t
ip
;
// UDP port
uint16_t
port
;
// RAW ethertype
uint16_t
ethertype
;
// physical port to bind socket to
uint16_t
physical_port
;
}
wr_sockaddr_t
;
PACKED
struct
_wr_timestamp
{
// Seconds
int64_t
sec
;
// Nanoseconds
int32_t
nsec
;
// Phase (in picoseconds), linearized for receive timestamps, zero for send timestamps
int32_t
phase
;
// phase(picoseconds)
/* Raw time (non-linearized) for debugging purposes */
int32_t
raw_phase
;
int32_t
raw_nsec
;
int32_t
raw_ahead
;
// correctness flag: when 0, the timestamp MAY be incorrect (e.g. generated 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
();
// 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
sock_type
,
int
flags
,
wr_sockaddr_t
*
bind_addr
);
// Sends a UDP/RAW packet (data, data_length) to address provided in wr_sockaddr_t.
// 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
// 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
);
// Closes the socket.
int
ptpd_netif_close_socket
(
wr_socket_t
*
sock
);
int
ptpd_netif_poll
(
wr_socket_t
*
);
int
ptpd_netif_get_hw_addr
(
wr_socket_t
*
sock
,
mac_addr_t
*
mac
);
/*
* Function start HW locking of freq on WR Slave
* return:
* PTPD_NETIF_ERROR - locking not started
* PTPD_NETIF_OK - locking started
*/
int
ptpd_netif_locking_enable
(
int
txrx
,
const
char
*
ifaceName
,
int
priority
);
/*
*
* return:
*
* PTPD_NETIF_OK - locking started
*/
int
ptpd_netif_locking_disable
(
int
txrx
,
const
char
*
ifaceName
,
int
priority
);
int
ptpd_netif_locking_poll
(
int
txrx
,
const
char
*
ifaceName
,
int
priority
);
/*
* Function turns on calibration (measurement of delay)
* Tx or Rx depending on the txrx param
* return:
* PTPD_NETIF_NOT_READY - if there is calibratin going on on another port
* PTPD_NETIF_OK - calibration started
*/
int
ptpd_netif_calibrating_enable
(
int
txrx
,
const
char
*
ifaceName
);
/*
* Function turns off calibration (measurement of delay)
* Tx or Rx depending on the txrx param
* return:
* PTPD_NETIF_ERROR - if there is calibratin going on on another port
* PTPD_NETIF_OK - calibration started
*/
int
ptpd_netif_calibrating_disable
(
int
txrx
,
const
char
*
ifaceName
);
/*
* Function checks if Rx/Tx (depending on the param) calibration is finished
* if finished, returns measured delay in delta
* return:
*
* PTPD_NETIF_OK - locking started
*/
int
ptpd_netif_calibrating_poll
(
int
txrx
,
const
char
*
ifaceName
,
uint64_t
*
delta
);
/*
* Function turns on calibration pattern.
* return:
* PTPD_NETIF_NOT_READY - if WRSW is busy with calibration on other switch or error occured
* PTPD_NETIF_OK - calibration started
*/
int
ptpd_netif_calibration_pattern_enable
(
const
char
*
ifaceName
,
unsigned
int
calibrationPeriod
,
unsigned
int
calibrationPattern
,
unsigned
int
calibrationPatternLen
);
/*
* Function turns off calibration pattern
* return:
* PTPD_NETIF_ERROR - turning off not successful
* PTPD_NETIF_OK - turning off successful
*/
int
ptpd_netif_calibration_pattern_disable
(
const
char
*
ifaceName
);
/*
* Function reads calibration data if it's available, used at the beginning of PTPWRd to check if
* HW knows already the interface's deltax, and therefore no need for calibration
* return:
* PTPD_NETIF_NOT_FOUND - if deltas are not known
* PTPD_NETIF_OK - if deltas are known, in such case, deltaTx and deltaRx have valid data
*/
int
ptpd_netif_read_calibration_data
(
const
char
*
ifaceName
,
uint64_t
*
deltaTx
,
uint64_t
*
deltaRx
,
int32_t
*
fix_alpha
,
int32_t
*
clock_period
);
int
ptpd_netif_select
(
wr_socket_t
*
);
int
ptpd_netif_get_hw_addr
(
wr_socket_t
*
sock
,
mac_addr_t
*
mac
);
/*
* Function reads state of the given port (interface in our case), if the port is up, everything is OK, otherwise ERROR
* return:
* PTPD_NETIF_ERROR - if the port is down
* PTPD_NETIF_OK - if the port is up
*/
int
ptpd_netif_get_port_state
(
const
char
*
ifaceName
);
/*
* Function looks for a port (interface) for the port number 'number'
* it will return in the argument ifname the port name
* return:
* PTPD_NETIF_ERROR - port not found
* PTPD_NETIF_OK - if the port found
*/
int
ptpd_netif_get_ifName
(
char
*
ifname
,
int
number
);
/* Returns the millisecond "tics" counter value */
uint64_t
ptpd_netif_get_msec_tics
();
/*
* Function detects external source lock,
*
* return:
* HEXP_EXTSRC_STATUS_LOCKED 0
* HEXP_LOCK_STATUS_BUSY 1
* HEXP_EXTSRC_STATUS_NOSRC 2
*/
int
ptpd_netif_extsrc_detection
();
/* Timebase adjustment functions - the servo should not call the HAL directly */
int
ptpd_netif_adjust_counters
(
int64_t
adjust_sec
,
int32_t
adjust_nsec
);
int
ptpd_netif_adjust_phase
(
int32_t
phase_ps
);
int
ptpd_netif_adjust_in_progress
();
int
ptpd_netif_get_dmtd_phase
(
wr_socket_t
*
sock
,
int32_t
*
phase
);
void
ptpd_netif_linearize_rx_timestamp
(
wr_timestamp_t
*
ts
,
int32_t
dmtd_phase
,
int
cntr_ahead
,
int
transition_point
,
int
clock_period
);
int
ptpd_netif_enable_timing_output
(
int
enable
);
int
ptpd_netif_enable_phase_tracking
(
const
char
*
if_name
);
#endif
userspace/tools/Makefile
View file @
ca626c92
...
...
@@ -21,7 +21,7 @@ GIT_USR = $(shell git config --get-all user.name)
CFLAGS
=
-O2
-DDEBUG
-g
-Wall
\
-I
$(LINUX)
/include
\
-I
$(LINUX)
/arch/arm/mach-at91/include
\
-I
../
ptp-noposix/
libptpnetif
\
-I
../libptpnetif
\
-I
../wrsw_hal
\
-I
../wrsw_rtud
\
-I
../mini-rpc
\
...
...
@@ -29,7 +29,7 @@ CFLAGS = -O2 -DDEBUG -g -Wall \
-I
../include
LDFLAGS
=
-L
../mini-rpc
\
-L
../
ptp-noposix
\
-L
../
libptpnetif
\
-L
../libswitchhw
\
-lminipc
-lptpnetif
-lswitchhw
...
...
userspace/wrsw_rtud/Makefile
View file @
ca626c92
PROGRAM
=
wrsw_rtud
SRCFILES
=
mac.c rtu_drv.c rtu_hash.c rtu_fd.c rtud.c
\
rtud_exports.c utils.c
../ptp-noposix/libptpnetif/hal_client.c
rtud_exports.c utils.c
OBJFILES
=
$
(
patsubst %.c,%.o,
$(SRCFILES)
)
CC
=
$(CROSS_COMPILE)
gcc
...
...
@@ -13,12 +13,12 @@ WR_INCLUDE = $(WR_INSTALL_ROOT)/include
WR_LIB
=
$(WR_INSTALL_ROOT)
/lib
CFLAGS
=
-O2
-DDEBUG
-Wall
-ggdb
\
-I
../
ptp-noposix/
libptpnetif
-I
../wrsw_hal
\
-I
../libptpnetif
-I
../wrsw_hal
\
-I
../mini-rpc
-I
../include
-I
$(WR_INCLUDE)
-I
$(LINUX)
/include
# -I$(CROSS_COMPILE_ARM_PATH)/../include
LDFLAGS
:=
-L
../libptpnetif
-L
../libswitchhw
-L
../mini-rpc
\
-lswitchhw
-lpthread
-lminipc
-lswitchhw
-lpt
pnetif
-lpt
hread
-lminipc
RM
:=
rm
-f
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment