hwtstamp_ctl: use SIOCGHWTSTAMP ioctl before destructively setting policy
This patch modifies the hwtstamp_ctl program, so that it will (attempt to) use the SIOCGHWTSTAMP ioctl to non-destructively read the current hardware timestamping policy, prior to setting it with SIOCSHWTSTAMP. This change has 3 primary advantages: 1) It allows reading the current settings of the device, which was previously not possible since SIOCSHWTSTAMP is destructive. 2) The default behavior without rx-filter or tx-type selected on the command line is no longer destructive, since it does not attempt to set the values to 0. The user must explicitly request to disable the settings, by using the provided options. 3) It allows only modifying tx-type or rx-filter separately, without destroying the other setting. This patch supersedes a previous submission which added a -g flag. This new method of getting first is more advantageous and doesn't require adding an additional option flag. - v4 * only display results if command succeeds, as the contents are otherwise expected to be identical to what we passed in. Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>master
parent
5e8a34f0b4
commit
2462f675c3
|
@ -15,7 +15,7 @@ hwstamp_ctl \- set time stamping policy at the driver level
|
|||
|
||||
.SH DESCRIPTION
|
||||
.B hwstamp_ctl
|
||||
is a program used to set the hardware time stamping policy at the network
|
||||
is a program used to set and get the hardware time stamping policy at the network
|
||||
driver level with the
|
||||
.B SIOCSHWTSTAMP
|
||||
.BR ioctl (2).
|
||||
|
@ -27,6 +27,15 @@ values are hints to the driver what it is expected to do. If the requested
|
|||
fine-grained filtering for incoming packets is not supported, the driver may
|
||||
time stamp more than just the requested types of packets.
|
||||
|
||||
If neither
|
||||
.I tx-type
|
||||
nor
|
||||
.I rx-filter
|
||||
values are passed to the program, it will use the
|
||||
.B SIOCGHWTSTAMP
|
||||
.BR ioctl(2)
|
||||
to non-destructively read the current hardware time stamping policy.
|
||||
|
||||
This program is a debugging tool. The
|
||||
.BR ptp4l (8)
|
||||
program does not need this program to function, it will set the policy
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <net/if.h>
|
||||
|
||||
#include "version.h"
|
||||
#include "missing.h"
|
||||
|
||||
static void usage(char *progname)
|
||||
{
|
||||
|
@ -84,6 +85,7 @@ int main(int argc, char *argv[])
|
|||
struct hwtstamp_config cfg;
|
||||
char *device = NULL, *progname;
|
||||
int c, err, fd, rxopt = HWTSTAMP_FILTER_NONE, txopt = HWTSTAMP_TX_OFF;
|
||||
int setrx = 0, settx = 0;
|
||||
|
||||
/* Process the command line arguments. */
|
||||
progname = strrchr(argv[0], '/');
|
||||
|
@ -94,9 +96,11 @@ int main(int argc, char *argv[])
|
|||
device = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
setrx = 1;
|
||||
rxopt = atoi(optarg);
|
||||
break;
|
||||
case 't':
|
||||
settx = 1;
|
||||
txopt = atoi(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
|
@ -116,6 +120,7 @@ int main(int argc, char *argv[])
|
|||
usage(progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rxopt < HWTSTAMP_FILTER_NONE ||
|
||||
rxopt > HWTSTAMP_FILTER_PTP_V2_DELAY_REQ ||
|
||||
txopt < HWTSTAMP_TX_OFF || txopt > HWTSTAMP_TX_ON) {
|
||||
|
@ -129,8 +134,6 @@ int main(int argc, char *argv[])
|
|||
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) {
|
||||
|
@ -138,15 +141,53 @@ int main(int argc, char *argv[])
|
|||
return -1;
|
||||
}
|
||||
|
||||
err = ioctl(fd, SIOCSHWTSTAMP, &ifreq);
|
||||
/* First, attempt to get the current settings. */
|
||||
err = ioctl(fd, SIOCGHWTSTAMP, &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");
|
||||
if (err == ENOTTY)
|
||||
fprintf(stderr,
|
||||
"Kernel does not have support "
|
||||
"for non-destructive SIOCGHWTSTAMP.\n");
|
||||
else if (err == EOPNOTSUPP)
|
||||
fprintf(stderr,
|
||||
"Device driver does not have support "
|
||||
"for non-destructive SIOCGHWTSTAMP.\n");
|
||||
else
|
||||
perror("SIOCGHWTSTAMP failed");
|
||||
} else {
|
||||
printf("current settings:\n"
|
||||
"tx_type %d\n"
|
||||
"rx_filter %d\n",
|
||||
cfg.tx_type, cfg.rx_filter);
|
||||
}
|
||||
|
||||
printf("tx_type %d\n" "rx_filter %d\n", cfg.tx_type, cfg.rx_filter);
|
||||
/* Now, attempt to set values. Only change the values actually
|
||||
* requested by user, rather than blindly resetting th zero if
|
||||
* unrequested. */
|
||||
if (settx || setrx) {
|
||||
|
||||
if (settx)
|
||||
cfg.tx_type = txopt;
|
||||
|
||||
if (setrx)
|
||||
cfg.rx_filter = rxopt;
|
||||
|
||||
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");
|
||||
} else {
|
||||
printf("new settings:\n"
|
||||
"tx_type %d\n"
|
||||
"rx_filter %d\n",
|
||||
cfg.tx_type, cfg.rx_filter);
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue