Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Software for White Rabbit PTP Core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
32
Issues
32
List
Board
Labels
Milestones
Merge Requests
7
Merge Requests
7
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
Software for White Rabbit PTP Core
Commits
2723ad02
Commit
2723ad02
authored
May 20, 2016
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'latency-test'
parents
1a4665dd
965efd02
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
264 additions
and
5 deletions
+264
-5
Kconfig
Kconfig
+19
-0
devel_build_test_defconfig
configs/devel_build_test_defconfig
+10
-1
ep_pfilter.c
dev/ep_pfilter.c
+17
-0
ptpd_netif.h
include/ptpd_netif.h
+1
-0
latency.c
lib/latency.c
+209
-0
lib.mk
lib/lib.mk
+1
-0
net.c
lib/net.c
+1
-1
pfilter-builder.c
tools/pfilter-builder.c
+6
-3
No files found.
Kconfig
View file @
2723ad02
...
...
@@ -106,6 +106,10 @@ config W1
boolean
default y
config LATENCY_ETHTYPE
int
default 0
# The other ones can be set by non-developers
config IP
...
...
@@ -396,6 +400,21 @@ config LEGACY_EEPROM
boolean
default !SDB_STORAGE
config LATENCY_PROBE
depends on DEVELOPER
bool "Build the latency probe mechanism (send/recv)"
help
The latency prober sends two frames to broadcast and
then the timestamp of their departure time. The receiver
measures the network latency and reports it.
If this option is set, the receiver is always running. The
sender is built but must be activated by the latency shell cmd.
config LATENCY_ETHTYPE
depends on LATENCY_PROBE
int "Ethtype to use for latency probing"
# This is needed to size the pp_instance data strucuture. Instead of
# including the ppsi autoconf.h, with duplicate definitions, define it
# here, as we know what the value is
...
...
configs/devel_build_test_defconfig
View file @
2723ad02
...
...
@@ -6,6 +6,7 @@ CONFIG_WR_NODE=y
CONFIG_PRINT_BUFSIZE=128
# CONFIG_PRINTF_XINT is not set
CONFIG_RAMSIZE=131072
CONFIG_TEMP_POLL_INTERVAL=15
CONFIG_PLL_VERBOSE=y
CONFIG_PFILTER_VERBOSE=y
CONFIG_WRC_VERBOSE=y
...
...
@@ -14,11 +15,15 @@ CONFIG_VLAN_NR=10
CONFIG_VLAN_1_FOR_CLASS7=20
CONFIG_VLAN_2_FOR_CLASS7=30
CONFIG_VLAN_FOR_CLASS6=100
# CONFIG_HOST_PROCESS is not set
CONFIG_LM32=y
CONFIG_EMBEDDED_NODE=y
# CONFIG_WR_NODE_PCS16 is not set
CONFIG_STACKSIZE=2048
CONFIG_PPSI=y
CONFIG_UART=y
CONFIG_W1=y
CONFIG_LATENCY_ETHTYPE=4455
CONFIG_IP=y
CONFIG_CMD_CONFIG=y
CONFIG_SYSLOG=y
...
...
@@ -26,13 +31,15 @@ CONFIG_BUILD_INIT=y
CONFIG_INIT_COMMAND="help"
CONFIG_HAS_BUILD_INIT=1
CONFIG_HAS_FLASH_INIT=1
CONFIG_FLASH_INIT=y
#
# wrpc-sw is tainted if you change the following options
#
CONFIG_DEVELOPER=y
CONFIG_TEMP_HIGH_THRESHOLD=70
CONFIG_TEMP_HIGH_RAPPEL=60
CONFIG_CMD_LL=y
CONFIG_FLASH_INIT=y
CONFIG_CHECK_RESET=y
CONFIG_SPLL_FIFO_LOG=y
CONFIG_PRINTF_FULL=y
...
...
@@ -41,6 +48,8 @@ CONFIG_PRINTF_FULL=y
CONFIG_DETERMINISTIC_BINARY=y
CONFIG_UART_SW=y
CONFIG_NET_VERBOSE=y
CONFIG_FAKE_TEMPERATURES=y
CONFIG_SDB_STORAGE=y
# CONFIG_LEGACY_EEPROM is not set
CONFIG_LATENCY_PROBE=y
CONFIG_VLAN_ARRAY_SIZE=1
dev/ep_pfilter.c
View file @
2723ad02
...
...
@@ -61,6 +61,7 @@ void pfilter_init_default(void)
uint64_t
cmd_word
;
int
i
;
static
int
inited
;
uint32_t
latency_ethtype
=
CONFIG_LATENCY_ETHTYPE
;
/* If vlan, use rule-set 1, else rule-set 0 */
s
=
rule_sets
+
(
wrc_vlan_number
!=
0
);
...
...
@@ -114,6 +115,22 @@ void pfilter_init_default(void)
pfilter_verbose
(
"fixing MAC adress in rule: use %s
\n
"
,
format_mac
(
buf
,
mac
));
/*
* Patch in the "latency" ethtype too. This is set at build time
* so there's not need to remember the place or the value.
*/
if
(
latency_ethtype
==
0
)
latency_ethtype
=
0x88f7
;
/* reuse PTPv2 type: turn into NOP */
for
(
v
=
vini
+
1
;
v
<
vend
;
v
+=
2
)
{
if
(((
*
v
>>
13
)
&
0xffff
)
==
0xcafe
&&
(
*
v
&
0x7
)
==
OR
)
{
pfilter_verbose
(
"fixing latency eth_type: use 0x%x
\n
"
,
latency_ethtype
);
*
v
&=
~
(
0xffff
<<
13
);
*
v
|=
latency_ethtype
<<
13
;
}
}
/* If this is the VLAN rule-set, patch the vlan number too */
for
(
v
=
vini
+
1
;
v
<
vend
;
v
+=
2
)
{
if
(((
*
v
>>
13
)
&
0xffff
)
==
0x0aaa
...
...
include/ptpd_netif.h
View file @
2723ad02
...
...
@@ -55,6 +55,7 @@ struct sockq {
struct
wrpc_socket
{
struct
wr_sockaddr
bind_addr
;
mac_addr_t
local_mac
;
uint16_t
prio
;
uint32_t
phase_transition
;
uint32_t
dmtd_phase
;
...
...
lib/latency.c
0 → 100644
View file @
2723ad02
/*
* 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 <wrc.h>
#include <wrpc.h>
#include <ptpd_netif.h>
#include <shell.h>
#include "ipv4.h"
/* latency probe: we need to enqueue 3 short frames: 64*3+overhead = 256 */
static
uint8_t
__latency_queue
[
256
];
static
struct
wrpc_socket
*
latency_socket
,
__static_latency_socket
=
{
.
queue
.
buff
=
__latency_queue
,
.
queue
.
size
=
sizeof
(
__latency_queue
),
};
static
struct
wr_sockaddr
latency_addr
=
{
.
mac
=
{
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
},
/* for binding */
.
mac_dest
=
{
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
},
/* for sending */
.
ethertype
=
0
,
/* htons(CONFIG_LATENCY_ETHTYPE) -- not constant! */
};
static
void
latency_init
(
void
)
{
latency_addr
.
ethertype
=
htons
(
CONFIG_LATENCY_ETHTYPE
);
latency_socket
=
ptpd_netif_create_socket
(
&
__static_latency_socket
,
&
latency_addr
,
PTPD_SOCK_RAW_ETHERNET
,
0
);
}
static
struct
latency_frame
{
uint32_t
type
;
/* 1, 2, 3 */
uint32_t
sequence
;
struct
wr_timestamp
ts1
,
ts2
;
}
frame
;
static
uint16_t
prev_sequence
,
prev_type
;
static
void
ts_sub
(
struct
wr_timestamp
*
t2
,
struct
wr_timestamp
*
t1
,
struct
wr_timestamp
*
res
)
{
int64_t
resll
;
/* every field is signed: good */
resll
=
t2
->
sec
-
t1
->
sec
;
resll
*=
1000
*
1000
*
1000
;
resll
+=
t2
->
nsec
-
t1
->
nsec
;
resll
*=
1000
;
resll
+=
t2
->
phase
-
t1
->
phase
;
/* seconds must be 0 and result must be positive */
res
->
sec
=
0
;
res
->
phase
=
__div64_32
((
uint64_t
*
)
&
resll
,
1000
);
res
->
nsec
=
resll
;
}
static
void
latency_warning
(
void
)
{
pp_printf
(
"lat: unexpected %i.%i after %i.%i
\n
"
,
frame
.
sequence
,
frame
.
type
,
prev_sequence
,
prev_type
);
}
static
int
latency_poll_rx
(
void
)
{
static
struct
wr_timestamp
ts
[
2
];
static
int
nframes
;
struct
wr_timestamp
ts_tmp
,
lat
[
2
];
struct
wr_sockaddr
addr
;
int
len
;
len
=
ptpd_netif_recvfrom
(
latency_socket
,
&
addr
,
&
frame
,
sizeof
(
frame
),
&
ts_tmp
);
if
(
len
<
sizeof
(
frame
))
return
0
;
/* check sequence and type is ok */
switch
(
frame
.
type
)
{
case
1
:
if
(
frame
.
sequence
!=
prev_sequence
+
1
||
prev_type
!=
3
)
latency_warning
();
ts
[
0
]
=
ts_tmp
;
/* 0 is always valid, it's a new set */
nframes
=
1
;
ts
[
1
].
sec
=
0
;
/* but still incomplete info */
break
;
case
2
:
if
(
frame
.
sequence
!=
prev_sequence
||
prev_type
!=
1
)
{
latency_warning
();
}
else
{
ts
[
1
]
=
ts_tmp
;
nframes
++
;
}
break
;
case
3
:
if
(
frame
.
sequence
!=
prev_sequence
||
prev_type
!=
2
)
{
latency_warning
();
}
else
{
nframes
++
;
}
break
;
}
prev_sequence
=
frame
.
sequence
;
prev_type
=
frame
.
type
;
if
(
frame
.
type
!=
3
||
nframes
!=
3
)
return
1
;
net_verbose
(
"ts_rx 1: %9li.%09i.%03i
\n
"
,
(
long
)
ts
[
0
].
sec
,
ts
[
0
].
nsec
,
ts
[
0
].
phase
);
net_verbose
(
"ts_tx 1: %9li.%09i.%03i
\n
"
,
(
long
)
frame
.
ts1
.
sec
,
frame
.
ts1
.
nsec
,
frame
.
ts1
.
phase
);
net_verbose
(
"ts_rx 2: %9li.%09i.%03i
\n
"
,
(
long
)
ts
[
1
].
sec
,
ts
[
1
].
nsec
,
ts
[
1
].
phase
);
net_verbose
(
"ts_tx 2: %9li.%09i.%03i
\n
"
,
(
long
)
frame
.
ts2
.
sec
,
frame
.
ts2
.
nsec
,
frame
.
ts2
.
phase
);
ts_sub
(
ts
+
0
,
&
frame
.
ts1
,
lat
+
0
);
ts_sub
(
ts
+
1
,
&
frame
.
ts2
,
lat
+
1
);
pp_printf
(
"lat: %9i %6i.%03i %6i.%03i
\n
"
,
frame
.
sequence
,
lat
[
0
].
nsec
,
lat
[
0
].
phase
,
lat
[
1
].
nsec
,
lat
[
1
].
phase
);
return
1
;
}
static
int
latency_poll_tx
(
void
)
{
static
uint32_t
sequence
;
static
uint32_t
lasts
;
/* Send three frames -- lazily in native byte order */
memset
(
&
frame
,
0
,
sizeof
(
frame
));
frame
.
sequence
=
sequence
++
;
frame
.
type
=
1
;
latency_socket
->
prio
=
7
;
ptpd_netif_sendto
(
latency_socket
,
&
latency_addr
,
&
frame
,
sizeof
(
frame
),
&
frame
.
ts1
);
frame
.
type
=
2
;
latency_socket
->
prio
=
6
;
ptpd_netif_sendto
(
latency_socket
,
&
latency_addr
,
&
frame
,
sizeof
(
frame
),
&
frame
.
ts2
);
frame
.
type
=
3
;
latency_socket
->
prio
=
0
;
ptpd_netif_sendto
(
latency_socket
,
&
latency_addr
,
&
frame
,
sizeof
(
frame
),
NULL
);
/* Every 10s remind we are sending ltest */
if
(
!
lasts
)
{
lasts
=
frame
.
ts2
.
sec
;
}
else
if
(
frame
.
ts2
.
sec
-
lasts
>=
10
)
{
lasts
=
frame
.
ts2
.
sec
;
pp_printf
(
"latency: seq %9i sent @ %9i
\n
"
,
sequence
,
lasts
);
}
return
1
;
}
static
uint32_t
lastt
;
static
uint32_t
latency_period_ms
;
static
int
latency_poll
(
void
)
{
if
(
!
latency_period_ms
)
return
latency_poll_rx
();
/* Periodically send the frames */
if
(
task_not_yet
(
&
lastt
,
latency_period_ms
))
return
0
;
return
latency_poll_tx
();
}
DEFINE_WRC_TASK
(
uptime
)
=
{
.
name
=
"latency-probe"
,
.
init
=
latency_init
,
.
job
=
latency_poll
,
};
static
int
cmd_ltest
(
const
char
*
args
[])
{
int
v
=
0
,
v1
=
0
;
if
(
args
[
1
])
{
fromdec
(
args
[
1
],
&
v1
);
/* ms */
}
if
(
args
[
0
])
{
fromdec
(
args
[
0
],
&
v
);
latency_period_ms
=
v
*
1000
+
v1
;
lastt
=
0
;
/* reset, so it fires immediately */
}
pp_printf
(
"%i.%03i
\n
"
,
latency_period_ms
/
1000
,
latency_period_ms
%
1000
);
return
0
;
}
DEFINE_WRC_COMMAND
(
ltest
)
=
{
.
name
=
"ltest"
,
.
exec
=
cmd_ltest
,
};
lib/lib.mk
View file @
2723ad02
...
...
@@ -8,3 +8,4 @@ obj-$(CONFIG_WR_NODE) += lib/net.o
obj-$(CONFIG_IP) += lib/ipv4.o lib/arp.o lib/icmp.o lib/udp.o lib/bootp.o
obj-$(CONFIG_SYSLOG) += lib/syslog.o
obj-$(CONFIG_LATENCY_PROBE) += lib/latency.o
lib/net.c
View file @
2723ad02
...
...
@@ -284,7 +284,7 @@ int ptpd_netif_sendto(struct wrpc_socket * sock, struct wr_sockaddr *to, void *d
memcpy
(
hdr
.
srcmac
,
s
->
local_mac
,
6
);
if
(
wrc_vlan_number
)
{
hdr
.
ethtype
=
htons
(
0x8100
);
hdr
.
tag
=
htons
(
wrc_vlan_number
);
hdr
.
tag
=
htons
(
wrc_vlan_number
|
(
sock
->
prio
<<
13
)
);
hdr
.
ethtype_2
=
sock
->
bind_addr
.
ethertype
;
/* net order */
}
else
{
hdr
.
ethtype
=
sock
->
bind_addr
.
ethertype
;
...
...
tools/pfilter-builder.c
View file @
2723ad02
...
...
@@ -216,6 +216,7 @@ enum pf_symbolic_regs {
FRAME_OUR_VLAN
,
FRAME_TYPE_IPV4
,
FRAME_TYPE_PTP2
,
FRAME_TYPE_LATENCY
,
FRAME_TYPE_ARP
,
FRAME_ICMP
,
FRAME_UDP
,
...
...
@@ -398,8 +399,9 @@ void pfilter_init_novlan(char *fname)
pfilter_cmp
(
6
,
0x8100
,
0xffff
,
MOV
,
R_TMP
);
pfilter_logic2
(
R_DROP
,
R_TMP
,
MOV
,
R_ZERO
);
/* Identify some Ethertypes used later
.
*/
/* Identify some Ethertypes used later
-- type latency is 0xcafe
*/
pfilter_cmp
(
6
,
0x88f7
,
0xffff
,
MOV
,
FRAME_TYPE_PTP2
);
pfilter_cmp
(
6
,
0xcafe
,
0xffff
,
OR
,
FRAME_TYPE_PTP2
);
pfilter_cmp
(
6
,
0x0800
,
0xffff
,
MOV
,
FRAME_TYPE_IPV4
);
pfilter_cmp
(
6
,
0x0806
,
0xffff
,
MOV
,
FRAME_TYPE_ARP
);
...
...
@@ -411,7 +413,7 @@ void pfilter_init_novlan(char *fname)
pfilter_cmp
(
11
,
0x0011
,
0x00ff
,
MOV
,
FRAME_UDP
);
pfilter_logic2
(
FRAME_UDP
,
FRAME_UDP
,
AND
,
FRAME_IP_OK
);
/* For CPU: arp broadcast or icmp unicast or ptp */
/* For CPU: arp broadcast or icmp unicast or ptp
(or latency)
*/
pfilter_logic3
(
FRAME_FOR_CPU
,
FRAME_BROADCAST
,
AND
,
FRAME_TYPE_ARP
,
OR
,
FRAME_TYPE_PTP2
);
pfilter_logic3
(
FRAME_FOR_CPU
,
FRAME_IP_OK
,
AND
,
FRAME_ICMP
,
OR
,
FRAME_FOR_CPU
);
...
...
@@ -481,8 +483,9 @@ void pfilter_init_vlan(char *fname)
/* Compare with our vlan (fake number 0xaaa) */
pfilter_cmp
(
7
,
0x0aaa
,
0x0fff
,
MOV
,
FRAME_OUR_VLAN
);
/* Identify some Ethertypes used later
.
*/
/* Identify some Ethertypes used later
-- type latency is 0xcafe
*/
pfilter_cmp
(
8
,
0x88f7
,
0xffff
,
MOV
,
FRAME_TYPE_PTP2
);
pfilter_cmp
(
8
,
0xcafe
,
0xffff
,
OR
,
FRAME_TYPE_PTP2
);
pfilter_cmp
(
8
,
0x0800
,
0xffff
,
MOV
,
FRAME_TYPE_IPV4
);
pfilter_cmp
(
8
,
0x0806
,
0xffff
,
MOV
,
FRAME_TYPE_ARP
);
...
...
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