/** * @file hwstamp_ctl.c * @brief Utility program to set time stamping policy at the driver level. * @note Copyright (C) 2012 Richard Cochran * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include #include #include #include #include #include "version.h" static void usage(char *progname) { fprintf(stderr, "\n" "usage: %s [options]\n\n" " -h prints this message and exits\n" " -i [device] interface device to use, for example 'eth0'\n" " -r [%d..%d] select receive time stamping:\n" "\t\t%2d time stamp no incoming packet at all\n" "\t\t%2d time stamp any incoming packet\n" "\t\t%2d (reserved value)\n" "\t\t%2d PTP v1, UDP, any kind of event packet\n" "\t\t%2d PTP v1, UDP, Sync packet\n" "\t\t%2d PTP v1, UDP, Delay_req packet\n" "\t\t%2d PTP v2, UDP, any kind of event packet\n" "\t\t%2d PTP v2, UDP, Sync packet\n" "\t\t%2d PTP v2, UDP, Delay_req packet\n" "\t\t%2d 802.AS1, Ethernet, any kind of event packet\n" "\t\t%2d 802.AS1, Ethernet, Sync packet\n" "\t\t%2d 802.AS1, Ethernet, Delay_req packet\n" "\t\t%2d PTP v2/802.AS1, any layer, any kind of event packet\n" "\t\t%2d PTP v2/802.AS1, any layer, Sync packet\n" "\t\t%2d PTP v2/802.AS1, any layer, Delay_req packet\n" " -t [%d|%d] disable or enable transmit time stamping\n" " -v prints the software version and exits\n" "\n", progname, HWTSTAMP_FILTER_NONE, HWTSTAMP_FILTER_PTP_V2_DELAY_REQ, HWTSTAMP_FILTER_NONE, HWTSTAMP_FILTER_ALL, HWTSTAMP_FILTER_SOME, HWTSTAMP_FILTER_PTP_V1_L4_EVENT, HWTSTAMP_FILTER_PTP_V1_L4_SYNC, HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ, HWTSTAMP_FILTER_PTP_V2_L4_EVENT, HWTSTAMP_FILTER_PTP_V2_L4_SYNC, HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ, HWTSTAMP_FILTER_PTP_V2_L2_EVENT, HWTSTAMP_FILTER_PTP_V2_L2_SYNC, HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ, HWTSTAMP_FILTER_PTP_V2_EVENT, HWTSTAMP_FILTER_PTP_V2_SYNC, HWTSTAMP_FILTER_PTP_V2_DELAY_REQ, HWTSTAMP_TX_OFF, HWTSTAMP_TX_ON); } int main(int argc, char *argv[]) { struct ifreq ifreq; struct hwtstamp_config cfg; char *device = NULL, *progname; int c, err, fd, rxopt = HWTSTAMP_FILTER_NONE, txopt = HWTSTAMP_TX_OFF; /* Process the command line arguments. */ progname = strrchr(argv[0], '/'); progname = progname ? 1+progname : argv[0]; while (EOF != (c = getopt(argc, argv, "hi:r:t:v"))) { switch (c) { case 'i': device = optarg; break; case 'r': rxopt = atoi(optarg); break; case 't': txopt = atoi(optarg); break; case 'v': version_show(stdout); return 0; case 'h': usage(progname); return 0; case '?': default: usage(progname); return -1; } } if (!device) { usage(progname); return -1; } if (rxopt < HWTSTAMP_FILTER_NONE || rxopt > HWTSTAMP_FILTER_PTP_V2_DELAY_REQ || txopt < HWTSTAMP_TX_OFF || txopt > HWTSTAMP_TX_ON) { usage(progname); return -1; } memset(&ifreq, 0, sizeof(ifreq)); memset(&cfg, 0, sizeof(cfg)); strncpy(ifreq.ifr_name, device, sizeof(ifreq.ifr_name)); ifreq.ifr_data = (void *) &cfg; cfg.tx_type = txopt; cfg.rx_filter = rxopt; fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (fd < 0) { perror("socket"); return -1; } err = ioctl(fd, SIOCSHWTSTAMP, &ifreq); if (err < 0) { err = errno; perror("SIOCSHWTSTAMP failed"); if (err == ERANGE) fprintf(stderr, "The requested time stamping mode is not supported by the hardware.\n"); } printf("tx_type %d\n" "rx_filter %d\n", cfg.tx_type, cfg.rx_filter); return err; }