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
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
Software for White Rabbit PTP Core
Commits
0f4fb1ca
Commit
0f4fb1ca
authored
Oct 28, 2011
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
improved LM32 loader
parent
e3f4734f
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
770 additions
and
191 deletions
+770
-191
lm32-loader.c
tools/lm32-loader.c
+100
-191
Makefile
tools/mini_bone/Makefile
+4
-0
minibone_lib.c
tools/mini_bone/minibone_lib.c
+172
-0
minibone_lib.h
tools/mini_bone/minibone_lib.h
+14
-0
ptpd_netif.c
tools/mini_bone/ptpd_netif.c
+241
-0
ptpd_netif.h
tools/mini_bone/ptpd_netif.h
+239
-0
No files found.
tools/lm32-loader.c
View file @
0f4fb1ca
...
...
@@ -19,224 +19,133 @@
* zpu-loader uses rawrabbit kernel driver written by Alessandro Rubini.
*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/ioctl.h>
#include"rawrabbit.h"
#define DEVNAME "/dev/rawrabbit"
#define RST_ADDR 0xE2000
int
rst_zpu
(
int
spec
,
int
rst
);
int
copy
(
int
spec
,
int
srcbin
,
unsigned
int
baseaddr
);
int
verify
(
int
spec
,
int
srcbin
,
unsigned
int
baseaddr
);
int
conv_endian
(
int
x
);
int
dump_to_file
(
int
spec
,
char
*
filename
,
unsigned
int
baseaddr
);
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int
main
(
int
argc
,
char
**
argv
)
{
unsigned
int
addr
=
0x80000
;
int
spec
,
srcbin
;
unsigned
int
bytes
;
char
*
dumpfile
=
NULL
;
if
(
argc
<
2
)
{
fprintf
(
stderr
,
"No parameters specified !
\n
"
);
fprintf
(
stderr
,
"Usage:
\n\t
./%s [-r] <binary file> [base address]
\n
"
,
argv
[
0
]);
fprintf
(
stderr
,
"-r options dumps the memory contents to a given file.
\n\n
"
);
return
-
1
;
}
#define BASE_PCIE 0x80000
#define BASE_MBONE 0x00000
if
(
!
strcmp
(
argv
[
1
],
"-r"
))
dumpfile
=
argv
[
2
];
else
if
(
argc
==
3
)
addr
=
atoi
(
argv
[
2
]);
#define RST_ADDR 0x62000
#define MEM_ADDR 0x0
#include "rr_io.h"
#include "minibone_lib.h"
static
void
*
mb_handle
=
NULL
;
spec
=
open
(
DEVNAME
,
O_RDWR
);
if
(
spec
<
0
)
{
perror
(
"Could not open device"
);
return
-
1
;
}
if
(
dumpfile
)
{
dump_to_file
(
spec
,
dumpfile
,
addr
);
return
0
;
}
static
void
spec_writel
(
uint32_t
value
,
uint32_t
addr
)
{
if
(
mb_handle
)
mbn_writel
(
mb_handle
,
value
,
BASE_MBONE
+
addr
);
else
rr_writel
(
value
,
BASE_PCIE
+
addr
);
}
srcbin
=
open
(
argv
[
1
],
O_RDONLY
);
if
(
srcbin
<
0
)
{
perror
(
"Could not open binary file"
);
close
(
spec
);
return
-
1
;
}
static
uint32_t
spec_readl
(
uint32_t
addr
)
{
uint32_t
rval
;
if
(
mb_handle
)
rval
=
mbn_readl
(
mb_handle
,
BASE_MBONE
+
addr
);
else
rval
=
rr_readl
(
BASE_PCIE
+
addr
);
rst_zpu
(
spec
,
1
);
bytes
=
copy
(
spec
,
srcbin
,
addr
);
if
(
bytes
<
0
)
{
close
(
srcbin
);
close
(
spec
);
return
-
1
;
}
printf
(
"Wrote %u bytes
\n
"
,
bytes
);
verify
(
spec
,
srcbin
,
addr
);
// printf("readl: value %x addr %x\n", addr, rval);
rst_zpu
(
spec
,
0
)
;
return
rval
;
close
(
srcbin
);
close
(
spec
);
}
return
0
;
int
conv_endian
(
int
x
)
{
return
((
x
&
0xff000000
)
>>
24
)
+
((
x
&
0x00ff0000
)
>>
8
)
+
((
x
&
0x0000ff00
)
<<
8
)
+
((
x
&
0x000000ff
)
<<
24
);
}
int
copy
(
int
spec
,
int
srcbin
,
unsigned
int
baseaddr
)
void
rst_lm32
(
int
rst
)
{
unsigned
int
bytes
,
word
;
struct
rr_iocmd
iocmd
;
int
ret
;
spec_writel
(
rst
?
1
:
0
,
RST_ADDR
);
}
void
copy_lm32
(
uint32_t
*
buf
,
int
buf_nwords
,
uint32_t
base_addr
)
{
int
i
;
printf
(
"Writing memory: "
);
bytes
=
0
;
while
(
1
)
{
ret
=
read
(
srcbin
,
&
word
,
4
);
/*read 32-bit word*/
if
(
ret
<
0
)
{
perror
(
"Error while reading binary file"
);
return
-
1
;
}
else
if
(
ret
==
0
)
{
printf
(
"Done
\n
"
);
break
;
}
iocmd
.
address
=
baseaddr
+
bytes
;
bytes
+=
ret
;
//address shift for next write
iocmd
.
address
|=
__RR_SET_BAR
(
0
);
//bar0
iocmd
.
datasize
=
4
;
iocmd
.
data32
=
conv_endian
(
word
);
ret
=
ioctl
(
spec
,
RR_WRITE
,
&
iocmd
);
if
(
ret
<
0
)
for
(
i
=
0
;
i
<
buf_nwords
;
i
++
)
{
perror
(
"Error while writing to SPEC"
);
return
-
1
;
}
printf
(
"."
);
spec_writel
(
conv_endian
(
buf
[
i
]),
base_addr
+
i
*
4
);
if
(
!
(
i
&
0xfff
))
{
printf
(
"."
);
fflush
(
stdout
);
}
}
return
bytes
;
}
printf
(
"
\n
Verifing memory: "
);
int
dump_to_file
(
int
spec
,
char
*
filename
,
unsigned
int
baseaddr
)
{
unsigned
int
bytes
,
word
;
struct
rr_iocmd
iocmd
;
int
ret
;
FILE
*
f
=
fopen
(
filename
,
"wb"
);
if
(
!
f
)
return
-
1
;
bytes
=
0
;
while
(
bytes
<
0x10000
)
for
(
i
=
0
;
i
<
buf_nwords
;
i
++
)
{
uint32_t
x
=
spec_readl
(
base_addr
+
i
*
4
);
if
(
conv_endian
(
buf
[
i
])
!=
x
)
{
printf
(
"Verify failed (%x vs %x)
\n
"
,
conv_endian
(
buf
[
i
]),
x
);
return
;
}
iocmd
.
address
=
baseaddr
+
bytes
;
// bytes += ret; //address shift for next write
iocmd
.
address
|=
__RR_SET_BAR
(
0
);
//bar0
iocmd
.
datasize
=
4
;
iocmd
.
data32
=
0
;
ret
=
ioctl
(
spec
,
RR_READ
,
&
iocmd
);
word
=
conv_endian
(
iocmd
.
data32
);
fwrite
(
&
word
,
4
,
1
,
f
);
bytes
+=
4
;
if
(
!
(
i
&
0xfff
))
{
printf
(
"."
);
fflush
(
stdout
);
}
}
fclose
(
f
);
printf
(
"OK.
\n
"
);
}
int
verify
(
int
spec
,
int
srcbin
,
unsigned
int
baseaddr
)
int
main
(
int
argc
,
char
**
argv
)
{
unsigned
int
wbin
;
struct
rr_iocmd
iocmd
;
unsigned
int
bytes
;
int
ret
;
int
num_words
;
uint32_t
*
buf
;
uint8_t
target_mac
[
6
];
FILE
*
f
;
char
if_name
[
16
];
printf
(
"Verifing: "
);
bytes
=
0
;
while
(
1
)
{
ret
=
read
(
srcbin
,
&
wbin
,
4
);
/*read 32-bit word*/
if
(
ret
<
0
)
if
(
argc
<
2
)
{
perror
(
"Error while reading binary file"
);
fprintf
(
stderr
,
"No parameters specified !
\n
"
);
fprintf
(
stderr
,
"Usage:
\n\t
%s <binary file> [-m network_if mac_addr]
\n
"
,
argv
[
0
]);
fprintf
(
stderr
,
"By default the loader assumes that the card is in a PCIe slot.
\n
"
);
fprintf
(
stderr
,
"-m option enables remove programming via ethernet.
\n
"
);
return
-
1
;
}
else
if
(
ret
==
0
)
{
printf
(
"OK !
\n
"
);
break
;
}
iocmd
.
address
=
baseaddr
+
bytes
;
bytes
+=
ret
;
iocmd
.
address
|=
__RR_SET_BAR
(
0
);
//bar0
iocmd
.
datasize
=
4
;
ret
=
ioctl
(
spec
,
RR_READ
,
&
iocmd
);
if
(
ret
<
0
)
if
(
argc
>=
4
&&
!
strcmp
(
argv
[
2
],
"-m"
))
{
sscanf
(
argv
[
3
],
"%s"
,
if_name
);
sscanf
(
argv
[
4
],
"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"
,
&
target_mac
[
0
],
&
target_mac
[
1
],
&
target_mac
[
2
],
&
target_mac
[
3
],
&
target_mac
[
4
],
&
target_mac
[
5
])
;
mb_handle
=
mbn_open
(
if_name
,
target_mac
);
if
(
!
mb_handle
)
{
perror
(
"Error while reading SPEC memory
"
);
fprintf
(
stderr
,
"Connection failed....
\n
"
);
return
-
1
;
}
if
(
iocmd
.
data32
!=
conv_endian
(
wbin
))
}
else
if
(
rr_init
()
<
0
)
{
printf
(
"Error (@word %u)
\n
"
,
bytes
/
4
);
fprintf
(
stderr
,
"Can't initialize rawrabbit :(
\n
"
);
return
-
1
;
}
printf
(
"."
);
return
0
;
}
return
0
;
}
int
rst_zpu
(
int
spec
,
int
rst
)
{
struct
rr_iocmd
iocmd
;
iocmd
.
address
=
RST_ADDR
;
iocmd
.
address
|=
__RR_SET_BAR
(
0
);
//bar0
iocmd
.
datasize
=
4
;
iocmd
.
data32
=
rst
;
if
(
ioctl
(
spec
,
RR_WRITE
,
&
iocmd
)
<
0
)
f
=
fopen
(
argv
[
1
],
"rb"
);
if
(
!
f
)
{
perror
(
"Could not reset ZPU
"
);
fprintf
(
stderr
,
"Input file not found.
\n
"
);
return
-
1
;
}
return
0
;
}
fseek
(
f
,
0
,
SEEK_END
);
int
size
=
ftell
(
f
);
rewind
(
f
);
int
conv_endian
(
int
x
)
{
return
((
x
&
0xff000000
)
>>
24
)
+
((
x
&
0x00ff0000
)
>>
8
)
+
((
x
&
0x0000ff00
)
<<
8
)
+
((
x
&
0x000000ff
)
<<
24
);
buf
=
malloc
(
size
+
4
);
fread
(
buf
,
1
,
size
,
f
);
fclose
(
f
);
rst_lm32
(
1
);
copy_lm32
(
buf
,
(
size
+
3
)
/
4
,
0
);
rst_lm32
(
0
);
return
0
;
}
tools/mini_bone/Makefile
0 → 100644
View file @
0f4fb1ca
OBJS
=
minibone_lib.o ptpd_netif.o
all
:
$(OBJS)
gcc
-o
m
$(OBJS)
\ No newline at end of file
tools/mini_bone/minibone_lib.c
0 → 100644
View file @
0f4fb1ca
/* MiniBone library. BUGGY CRAP CODE INTENDED FOR TESTING ONLY! */
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <sys/socket.h>
#include <sys/time.h>
#include "ptpd_netif.h"
#define F_SEL(x) (x & 0xf)
#define F_ERROR (1<<1)
#define F_READBACK (1<<0)
#define F_WRITE (1<<4)
#define RX_TIMEOUT 100
#define MBN_ETHERTYPE 0xa0a0
struct
mbn_packet
{
uint16_t
flags
;
uint32_t
a_d
;
uint32_t
d
;
}
__attribute__
((
packed
));
struct
mb_device
{
mac_addr_t
dest
;
uint16_t
ethertype
;
wr_socket_t
*
sock
;
};
typedef
struct
{
uint64_t
start_tics
;
uint64_t
timeout
;
}
timeout_t
;
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
);
}
void
*
mbn_open
(
const
char
*
if_name
,
mac_addr_t
target
)
{
struct
mb_device
*
dev
=
malloc
(
sizeof
(
struct
mb_device
));
wr_sockaddr_t
saddr
;
if
(
!
dev
)
return
NULL
;
memcpy
(
dev
->
dest
,
target
,
6
);
strcpy
(
saddr
.
if_name
,
if_name
);
memcpy
(
saddr
.
mac
,
target
,
6
);
saddr
.
ethertype
=
htons
(
MBN_ETHERTYPE
);
saddr
.
family
=
PTPD_SOCK_RAW_ETHERNET
;
dev
->
sock
=
ptpd_netif_create_socket
(
PTPD_SOCK_RAW_ETHERNET
,
0
,
&
saddr
);
if
(
!
dev
->
sock
)
{
free
(
dev
);
return
NULL
;
}
return
(
void
*
)
dev
;
}
static
int
mbn_send
(
void
*
priv
,
uint8_t
*
data
,
int
size
)
{
struct
mb_device
*
dev
=
(
struct
mb_device
*
)
priv
;
wr_sockaddr_t
to
;
memcpy
(
to
.
mac
,
dev
->
dest
,
6
);
to
.
ethertype
=
MBN_ETHERTYPE
;
return
ptpd_netif_sendto
(
dev
->
sock
,
&
to
,
(
void
*
)
data
,
size
,
NULL
);
}
static
int
mbn_recv
(
void
*
handle
,
uint8_t
*
data
,
int
size
,
int
timeout
)
{
struct
mb_device
*
dev
=
(
struct
mb_device
*
)
handle
;
wr_sockaddr_t
from
;
timeout_t
rx_tmo
;
tmo_init
(
&
rx_tmo
,
timeout
);
do
{
int
n
=
ptpd_netif_recvfrom
(
dev
->
sock
,
&
from
,
(
void
*
)
data
,
size
,
NULL
);
if
(
n
>
0
&&
from
.
ethertype
==
MBN_ETHERTYPE
&&
!
memcmp
(
from
.
mac
,
dev
->
dest
,
6
))
{
return
n
;
}
}
while
(
!
tmo_expired
(
&
rx_tmo
));
return
0
;
}
void
mbn_writel
(
void
*
handle
,
uint32_t
d
,
uint32_t
a
)
{
int
n_retries
=
3
;
struct
mbn_packet
pkt
;
pkt
.
flags
=
htons
(
F_SEL
(
0xf
)
|
F_WRITE
);
pkt
.
a_d
=
htonl
(
a
);
pkt
.
d
=
htonl
(
d
);
while
(
n_retries
--
)
{
mbn_send
(
handle
,
(
uint8_t
*
)
&
pkt
,
sizeof
(
pkt
));
int
n
=
mbn_recv
(
handle
,
(
uint8_t
*
)
&
pkt
,
sizeof
(
pkt
),
RX_TIMEOUT
);
pkt
.
flags
=
ntohs
(
pkt
.
flags
);
if
(
n
==
sizeof
(
pkt
)
&&
!
(
pkt
.
flags
&&
F_READBACK
)
&&
!
(
pkt
.
flags
&
F_ERROR
))
{
return
;
}
}
fprintf
(
stderr
,
"No ack.
\n
"
);
}
uint32_t
mbn_readl
(
void
*
handle
,
uint32_t
a
)
{
int
n_retries
=
3
;
struct
mbn_packet
pkt
;
pkt
.
flags
=
htons
(
F_SEL
(
0xf
));
pkt
.
a_d
=
htonl
(
a
);
while
(
n_retries
--
)
{
mbn_send
(
handle
,
(
uint8_t
*
)
&
pkt
,
sizeof
(
pkt
));
int
n
=
mbn_recv
(
handle
,
(
uint8_t
*
)
&
pkt
,
sizeof
(
pkt
),
RX_TIMEOUT
);
pkt
.
flags
=
ntohs
(
pkt
.
flags
);
if
(
n
==
sizeof
(
pkt
)
&&
(
pkt
.
flags
&
F_READBACK
)
&&
!
(
pkt
.
flags
&
F_ERROR
))
{
return
ntohl
(
pkt
.
a_d
);
}
}
fprintf
(
stderr
,
"No ack.
\n
"
);
}
void
mbn_close
(
void
*
handle
)
{
struct
mb_device
*
dev
=
(
struct
mb_device
*
)
handle
;
ptpd_netif_close_socket
(
dev
->
sock
);
}
\ No newline at end of file
tools/mini_bone/minibone_lib.h
0 → 100644
View file @
0f4fb1ca
/* MiniBone library. BUGGY CRAP CODE INTENDED FOR TESTING ONLY! */
#ifndef __MINIBONE_LIB_H
#define __MINIBONE_LIB_H
#include <stdint.h>
void
*
mbn_open
(
const
char
*
if_name
,
uint8_t
target_mac
[]);
void
mbn_writel
(
void
*
handle
,
uint32_t
d
,
uint32_t
a
);
uint32_t
mbn_readl
(
void
*
handle
,
uint32_t
a
);
void
mbn_close
(
void
*
handle
);
#endif
tools/mini_bone/ptpd_netif.c
0 → 100644
View file @
0f4fb1ca
// Supports only raw ethernet now.
#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/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"
#ifdef NETIF_VERBOSE
#define netif_dbg(...) printf(__VA_ARGS__)
#else
#define netif_dbg(...)
#endif
#define ETHER_MTU 1518
#define DMTD_UPDATE_INTERVAL 100
struct
scm_timestamping
{
struct
timespec
systime
;
struct
timespec
hwtimetrans
;
struct
timespec
hwtimeraw
;
};
PACKED
struct
etherpacket
{
struct
ethhdr
ether
;
char
data
[
ETHER_MTU
];
};
struct
tx_timestamp
{
int
valid
;
wr_timestamp_t
ts
;
uint32_t
tag
;
uint64_t
t_acq
;
};
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
;
};
struct
nasty_hack
{
char
if_name
[
20
];
int
clockedAsPrimary
;
};
#ifdef MACIEK_HACKs
struct
nasty_hack
locking_hack
;
#endif
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
;
int
fd
;
// fprintf(stderr,"CreateSocket!\n");
if
(
sock_type
!=
PTPD_SOCK_RAW_ETHERNET
)
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
;
}
s
=
calloc
(
sizeof
(
struct
my_socket
),
1
);
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
;
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
);
return
0
;
}
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
;
wr_timestamp_t
ts
;
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
<
64
)
len
=
64
;
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
;
// fprintf(stderr,"fd %d ifi %d ethertype %d\n", s->fd,
// s->if_index, to->ethertype);
rval
=
sendto
(
s
->
fd
,
&
pkt
,
len
,
0
,
(
struct
sockaddr
*
)
&
sll
,
sizeof
(
struct
sockaddr_ll
));
return
rval
;
}
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
);
return
ret
-
sizeof
(
struct
ethhdr
);
}
tools/mini_bone/ptpd_netif.h
0 → 100644
View file @
0f4fb1ca
// 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
;
typedef
struct
{
uint32_t
v
[
4
];
}
wr_picoseconds_t
;
// Precise WhiteRabbit timestamp
// TS[picoseconds] = utc * 1e12 + nsec * 1e3 + phase;
PACKED
struct
_wr_timestamp
{
// UTC time value (seconds)
int64_t
utc
;
// Nanoseconds
int32_t
nsec
;
// Phase (in picoseconds), linearized for receive timestamps, zero for send timestamps
int32_t
phase
;
// phase(picoseconds)
int32_t
raw_phase
;
int32_t
raw_nsec
;
int32_t
raw_ahead
;
//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 read 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
);
#define MACIEK_TMP
#ifdef MACIEK_TMP
int
ptpd_netif_select
(
wr_socket_t
*
);
int
ptpd_netif_get_hw_addr
(
wr_socket_t
*
sock
,
mac_addr_t
*
mac
);
#endif
/*
* 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
();
#endif
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