Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net_tstamp,doc: Add test program for SIOC{G,S}HWTSTAMP

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>

+138 -2
+1
Documentation/networking/timestamping/.gitignore
··· 1 1 timestamping 2 + hwtstamp_config
+3 -2
Documentation/networking/timestamping/Makefile
··· 2 2 obj- := dummy.o 3 3 4 4 # List of programs to build 5 - hostprogs-y := timestamping 5 + hostprogs-y := timestamping hwtstamp_config 6 6 7 7 # Tell kbuild to always build the programs 8 8 always := $(hostprogs-y) 9 9 10 10 HOSTCFLAGS_timestamping.o += -I$(objtree)/usr/include 11 + HOSTCFLAGS_hwtstamp_config.o += -I$(objtree)/usr/include 11 12 12 13 clean: 13 - rm -f timestamping 14 + rm -f timestamping hwtstamp_config
+134
Documentation/networking/timestamping/hwtstamp_config.c
··· 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 + 18 + static int 19 + lookup_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 + 30 + static const char * 31 + lookup_name(const char **names, int size, int value) 32 + { 33 + return (value >= 0 && value < size) ? names[value] : NULL; 34 + } 35 + 36 + static 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 + 45 + static 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 + 54 + static 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 + 75 + static 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 + 85 + int 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 + }