aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-12-05 19:45:14 -0500
committerDavid S. Miller <davem@davemloft.net>2013-12-05 19:45:14 -0500
commit426e1fa31e0d8e982891e801c80b84b74f209f10 (patch)
treebc53409418ffa918fb3f175639bc5c9245c4219f /Documentation
parente1ca87bb1b64b044163e686ff3bb71405156c561 (diff)
parenta4bcc795e9cc84902b86edbfbb755ecb38d11f91 (diff)
Merge branch 'siocghwtstamp' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc-next
Ben Hutchings says: ==================== SIOCGHWTSTAMP ioctl 1. Add the SIOCGHWTSTAMP ioctl and update the timestamping documentation. 2. Implement SIOCGHWTSTAMP in most drivers that support SIOCSHWTSTAMP. 3. Add a test program to exercise SIOC{G,S}HWTSTAMP. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/networking/timestamping.txt9
-rw-r--r--Documentation/networking/timestamping/.gitignore1
-rw-r--r--Documentation/networking/timestamping/Makefile5
-rw-r--r--Documentation/networking/timestamping/hwtstamp_config.c134
4 files changed, 145 insertions, 4 deletions
diff --git a/Documentation/networking/timestamping.txt b/Documentation/networking/timestamping.txt
index 98097d8cb910..661d3c316a17 100644
--- a/Documentation/networking/timestamping.txt
+++ b/Documentation/networking/timestamping.txt
@@ -85,7 +85,7 @@ Filled in if SOF_TIMESTAMPING_SYS_HARDWARE is set. Requires support
85by the network device and will be empty without that support. 85by the network device and will be empty without that support.
86 86
87 87
88SIOCSHWTSTAMP: 88SIOCSHWTSTAMP, SIOCGHWTSTAMP:
89 89
90Hardware time stamping must also be initialized for each device driver 90Hardware time stamping must also be initialized for each device driver
91that is expected to do hardware time stamping. The parameter is defined in 91that is expected to do hardware time stamping. The parameter is defined in
@@ -115,6 +115,10 @@ Only a processes with admin rights may change the configuration. User
115space is responsible to ensure that multiple processes don't interfere 115space is responsible to ensure that multiple processes don't interfere
116with each other and that the settings are reset. 116with each other and that the settings are reset.
117 117
118Any process can read the actual configuration by passing this
119structure to ioctl(SIOCGHWTSTAMP) in the same way. However, this has
120not been implemented in all drivers.
121
118/* possible values for hwtstamp_config->tx_type */ 122/* possible values for hwtstamp_config->tx_type */
119enum { 123enum {
120 /* 124 /*
@@ -157,7 +161,8 @@ DEVICE IMPLEMENTATION
157 161
158A driver which supports hardware time stamping must support the 162A driver which supports hardware time stamping must support the
159SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with 163SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with
160the actual values as described in the section on SIOCSHWTSTAMP. 164the actual values as described in the section on SIOCSHWTSTAMP. It
165should also support SIOCGHWTSTAMP.
161 166
162Time stamps for received packets must be stored in the skb. To get a pointer 167Time stamps for received packets must be stored in the skb. To get a pointer
163to the shared time stamp structure of the skb call skb_hwtstamps(). Then 168to the shared time stamp structure of the skb call skb_hwtstamps(). Then
diff --git a/Documentation/networking/timestamping/.gitignore b/Documentation/networking/timestamping/.gitignore
index 71e81eb2e22f..a380159765ce 100644
--- a/Documentation/networking/timestamping/.gitignore
+++ b/Documentation/networking/timestamping/.gitignore
@@ -1 +1,2 @@
1timestamping 1timestamping
2hwtstamp_config
diff --git a/Documentation/networking/timestamping/Makefile b/Documentation/networking/timestamping/Makefile
index e79973443e9f..d934afc8306a 100644
--- a/Documentation/networking/timestamping/Makefile
+++ b/Documentation/networking/timestamping/Makefile
@@ -2,12 +2,13 @@
2obj- := dummy.o 2obj- := dummy.o
3 3
4# List of programs to build 4# List of programs to build
5hostprogs-y := timestamping 5hostprogs-y := timestamping hwtstamp_config
6 6
7# Tell kbuild to always build the programs 7# Tell kbuild to always build the programs
8always := $(hostprogs-y) 8always := $(hostprogs-y)
9 9
10HOSTCFLAGS_timestamping.o += -I$(objtree)/usr/include 10HOSTCFLAGS_timestamping.o += -I$(objtree)/usr/include
11HOSTCFLAGS_hwtstamp_config.o += -I$(objtree)/usr/include
11 12
12clean: 13clean:
13 rm -f timestamping 14 rm -f timestamping hwtstamp_config
diff --git a/Documentation/networking/timestamping/hwtstamp_config.c b/Documentation/networking/timestamping/hwtstamp_config.c
new file mode 100644
index 000000000000..e8b685a7f15f
--- /dev/null
+++ b/Documentation/networking/timestamping/hwtstamp_config.c
@@ -0,0 +1,134 @@
1/* Test program for SIOC{G,S}HWTSTAMP
2 * Copyright 2013 Solarflare Communications
3 * Author: Ben Hutchings
4 */
5
6#include <errno.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10
11#include <sys/socket.h>
12#include <sys/ioctl.h>
13
14#include <linux/if.h>
15#include <linux/net_tstamp.h>
16#include <linux/sockios.h>
17
18static int
19lookup_value(const char **names, int size, const char *name)
20{
21 int value;
22
23 for (value = 0; value < size; value++)
24 if (names[value] && strcasecmp(names[value], name) == 0)
25 return value;
26
27 return -1;
28}
29
30static const char *
31lookup_name(const char **names, int size, int value)
32{
33 return (value >= 0 && value < size) ? names[value] : NULL;
34}
35
36static void list_names(FILE *f, const char **names, int size)
37{
38 int value;
39
40 for (value = 0; value < size; value++)
41 if (names[value])
42 fprintf(f, " %s\n", names[value]);
43}
44
45static const char *tx_types[] = {
46#define TX_TYPE(name) [HWTSTAMP_TX_ ## name] = #name
47 TX_TYPE(OFF),
48 TX_TYPE(ON),
49 TX_TYPE(ONESTEP_SYNC)
50#undef TX_TYPE
51};
52#define N_TX_TYPES ((int)(sizeof(tx_types) / sizeof(tx_types[0])))
53
54static const char *rx_filters[] = {
55#define RX_FILTER(name) [HWTSTAMP_FILTER_ ## name] = #name
56 RX_FILTER(NONE),
57 RX_FILTER(ALL),
58 RX_FILTER(SOME),
59 RX_FILTER(PTP_V1_L4_EVENT),
60 RX_FILTER(PTP_V1_L4_SYNC),
61 RX_FILTER(PTP_V1_L4_DELAY_REQ),
62 RX_FILTER(PTP_V2_L4_EVENT),
63 RX_FILTER(PTP_V2_L4_SYNC),
64 RX_FILTER(PTP_V2_L4_DELAY_REQ),
65 RX_FILTER(PTP_V2_L2_EVENT),
66 RX_FILTER(PTP_V2_L2_SYNC),
67 RX_FILTER(PTP_V2_L2_DELAY_REQ),
68 RX_FILTER(PTP_V2_EVENT),
69 RX_FILTER(PTP_V2_SYNC),
70 RX_FILTER(PTP_V2_DELAY_REQ),
71#undef RX_FILTER
72};
73#define N_RX_FILTERS ((int)(sizeof(rx_filters) / sizeof(rx_filters[0])))
74
75static void usage(void)
76{
77 fputs("Usage: hwtstamp_config if_name [tx_type rx_filter]\n"
78 "tx_type is any of (case-insensitive):\n",
79 stderr);
80 list_names(stderr, tx_types, N_TX_TYPES);
81 fputs("rx_filter is any of (case-insensitive):\n", stderr);
82 list_names(stderr, rx_filters, N_RX_FILTERS);
83}
84
85int main(int argc, char **argv)
86{
87 struct ifreq ifr;
88 struct hwtstamp_config config;
89 const char *name;
90 int sock;
91
92 if ((argc != 2 && argc != 4) || (strlen(argv[1]) >= IFNAMSIZ)) {
93 usage();
94 return 2;
95 }
96
97 if (argc == 4) {
98 config.flags = 0;
99 config.tx_type = lookup_value(tx_types, N_TX_TYPES, argv[2]);
100 config.rx_filter = lookup_value(rx_filters, N_RX_FILTERS, argv[3]);
101 if (config.tx_type < 0 || config.rx_filter < 0) {
102 usage();
103 return 2;
104 }
105 }
106
107 sock = socket(AF_INET, SOCK_DGRAM, 0);
108 if (sock < 0) {
109 perror("socket");
110 return 1;
111 }
112
113 strcpy(ifr.ifr_name, argv[1]);
114 ifr.ifr_data = (caddr_t)&config;
115
116 if (ioctl(sock, (argc == 2) ? SIOCGHWTSTAMP : SIOCSHWTSTAMP, &ifr)) {
117 perror("ioctl");
118 return 1;
119 }
120
121 printf("flags = %#x\n", config.flags);
122 name = lookup_name(tx_types, N_TX_TYPES, config.tx_type);
123 if (name)
124 printf("tx_type = %s\n", name);
125 else
126 printf("tx_type = %d\n", config.tx_type);
127 name = lookup_name(rx_filters, N_RX_FILTERS, config.rx_filter);
128 if (name)
129 printf("rx_filter = %s\n", name);
130 else
131 printf("rx_filter = %d\n", config.rx_filter);
132
133 return 0;
134}