Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Simple PCIe FMC carrier SPEC - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
3
Issues
3
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
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
Simple PCIe FMC carrier SPEC - Software
Commits
95b2b969
Commit
95b2b969
authored
Sep 24, 2012
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
tools: add wr-dio-agent
Signed-off-by:
Alessandro Rubini
<
rubini@gnudd.com
>
parent
64739dd8
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
146 additions
and
1 deletion
+146
-1
Makefile
tools/Makefile
+1
-1
wr-dio-agent.c
tools/wr-dio-agent.c
+145
-0
No files found.
tools/Makefile
View file @
95b2b969
...
...
@@ -6,7 +6,7 @@ LIB = libspec.a
LIBOBJ
=
speclib.o loader-ll.o
PROGS
=
spec-cl spec-fwloader spec-vuart specmem
PROGS
+=
wr-dio-cmd wr-dio-pps wr-dio-ruler
PROGS
+=
wr-dio-cmd wr-dio-pps wr-dio-
agent wr-dio-
ruler
all
:
$(LIB) $(PROGS)
...
...
tools/wr-dio-agent.c
0 → 100644
View file @
95b2b969
/*
* Copyright (C) 2012 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* Released to the public domain as sample code to be customized.
*
* This work is part of the White Rabbit project, a research effort led
* by CERN, the European Institute for Nuclear Research.
*/
/* Typical use: "wr-dio-agent wr1" */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
#include <net/if.h>
#include <netpacket/packet.h>
#include "wr_nic/wr-nic.h"
#include "wr-dio.h"
#define RULER_PROTO 0x5752
/* WR */
/*
* Lazily, use global variables, so the code has less parameter passing.
* Everything in this file is using "agent_" as a prefix, to ease the
* reader -- and remember that <TAB> aligns at 8 spaces, not 4.
*/
char
*
agent_prgname
;
int
agent_sock
;
char
*
agent_ifname
;
struct
ifreq
agent_ifr
;
/* Boring network stuff extracted from main function */
static
int
agent_open_wr_sock
(
char
*
name
)
{
struct
sockaddr_ll
addr
;
int
sock
,
ifindex
;
sock
=
socket
(
PF_PACKET
,
SOCK_RAW
,
htons
(
ETH_P_ALL
));
if
(
sock
<
0
)
{
fprintf
(
stderr
,
"%s: socket(): %s
\n
"
,
agent_prgname
,
strerror
(
errno
));
return
-
1
;
}
memset
(
&
agent_ifr
,
0
,
sizeof
(
agent_ifr
));
strncpy
(
agent_ifr
.
ifr_name
,
name
,
sizeof
(
agent_ifr
.
ifr_name
));
if
(
ioctl
(
sock
,
PRIV_MEZZANINE_ID
,
&
agent_ifr
)
<
0
/* EAGAIN is special: it means we have no ID to check yet */
&&
errno
!=
EAGAIN
)
{
fprintf
(
stderr
,
"%s: ioctl(PRIV_MEZZANINE_ID(%s)): %s
\n
"
,
agent_prgname
,
name
,
strerror
(
errno
));
close
(
sock
);
return
-
1
;
}
/* Retieve the interfaceindex */
if
(
ioctl
(
sock
,
SIOCGIFINDEX
,
&
agent_ifr
)
<
0
)
{
fprintf
(
stderr
,
"%s: SIOCGIFINDEX(%s): %s
\n
"
,
agent_prgname
,
name
,
strerror
(
errno
));
close
(
sock
);
return
-
1
;
}
ifindex
=
agent_ifr
.
ifr_ifindex
;
/* Bind to the interface, so to be able to receive */
memset
(
&
addr
,
0
,
sizeof
(
addr
));
addr
.
sll_family
=
AF_PACKET
;
addr
.
sll_protocol
=
htons
(
RULER_PROTO
);
addr
.
sll_ifindex
=
ifindex
;
addr
.
sll_pkttype
=
PACKET_BROADCAST
;
/* that's what ruler sends */
if
(
bind
(
sock
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
))
<
0
)
{
fprintf
(
stderr
,
"%s: bind(%s): %s
\n
"
,
agent_prgname
,
name
,
strerror
(
errno
));
close
(
sock
);
return
-
1
;
}
/* save in globals for later */
agent_sock
=
sock
;
return
0
;
}
/* And a simple main with the loop inside */
int
main
(
int
argc
,
char
**
argv
)
{
int
len
;
/* We are receiving stuff in this frame */
static
struct
frame
{
struct
ether_header
h
;
unsigned
char
pad
[
2
];
struct
wr_dio_cmd
cmd
;
}
f
;
if
(
argc
!=
2
)
{
fprintf
(
stderr
,
"%s: Use
\"
%s <wr-if>
\"\n
"
,
argv
[
0
],
argv
[
0
]);
exit
(
1
);
}
agent_prgname
=
argv
[
0
];
/* All functions print error messages by themselves, so just exit */
if
(
agent_open_wr_sock
(
argv
[
1
])
<
0
)
exit
(
1
);
while
(
1
)
{
len
=
recv
(
agent_sock
,
&
f
,
sizeof
(
f
),
MSG_TRUNC
);
if
(
len
!=
sizeof
(
f
))
{
fprintf
(
stderr
,
"%s: recevied unexpected frame length"
" (%i instead of %i)
\n
"
,
agent_prgname
,
len
,
sizeof
(
f
));
continue
;
}
if
(
ntohs
(
f
.
h
.
ether_type
)
!=
RULER_PROTO
)
{
fprintf
(
stderr
,
"%s: received unexpected eth type"
" (%04x instead of %04x)
\n
"
,
agent_prgname
,
ntohs
(
f
.
h
.
ether_type
),
RULER_PROTO
);
continue
;
}
if
(
0
)
printf
(
"command %i, ch %i, t %li.%09li
\n
"
,
f
.
cmd
.
command
,
f
.
cmd
.
channel
,
f
.
cmd
.
t
[
0
].
tv_sec
,
f
.
cmd
.
t
[
0
].
tv_nsec
);
/* Then simply pass it to the hardware */
agent_ifr
.
ifr_data
=
(
void
*
)
&
f
.
cmd
;
if
(
ioctl
(
agent_sock
,
PRIV_MEZZANINE_CMD
,
&
agent_ifr
)
<
0
)
{
fprintf
(
stderr
,
"%s: ioctl(PRIV_MEZZANINE_CMD(%s)): "
"%s
\n
"
,
agent_prgname
,
agent_ifname
,
strerror
(
errno
));
return
-
1
;
}
}
exit
(
0
);
}
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