229 lines
6.9 KiB
Diff
229 lines
6.9 KiB
Diff
commit 399907db7f9dc3f57c3f9831b3b4da705a2c51a3
|
|
Author: Erez Geva <erezgeva2@gmail.com>
|
|
Date: Tue Aug 28 22:05:28 2018 +0200
|
|
|
|
config: Add hardware time stamp filter setting mode
|
|
|
|
Add global option for the hardware time stamp setting.
|
|
The function could:
|
|
Normally set the filters as the PTP daemon require.
|
|
Check that the filters are proper but do not change them.
|
|
Full, set the RX filter to all and the TX filter as the PTP daemon require.
|
|
|
|
[ RC: added missing extern keyword and fixed indentation. ]
|
|
|
|
Signed-off-by: Erez Geva <erez.geva.ext@siemens.com>
|
|
Signed-off-by: Erez Geva <ErezGeva2@gmail.com>
|
|
|
|
diff --git a/config.c b/config.c
|
|
index 7914ba4..3530ce6 100644
|
|
--- a/config.c
|
|
+++ b/config.c
|
|
@@ -164,6 +164,13 @@ static struct config_enum delay_mech_enu[] = {
|
|
{ NULL, 0 },
|
|
};
|
|
|
|
+static struct config_enum hwts_filter_enu[] = {
|
|
+ { "normal", HWTS_FILTER_NORMAL },
|
|
+ { "check", HWTS_FILTER_CHECK },
|
|
+ { "full", HWTS_FILTER_FULL },
|
|
+ { NULL, 0 },
|
|
+};
|
|
+
|
|
static struct config_enum nw_trans_enu[] = {
|
|
{ "L2", TRANS_IEEE_802_3 },
|
|
{ "UDPv4", TRANS_UDP_IPV4 },
|
|
@@ -215,6 +222,7 @@ struct config_item config_tab[] = {
|
|
GLOB_ITEM_INT("G.8275.defaultDS.localPriority", 128, 1, UINT8_MAX),
|
|
PORT_ITEM_INT("G.8275.portDS.localPriority", 128, 1, UINT8_MAX),
|
|
GLOB_ITEM_INT("gmCapable", 1, 0, 1),
|
|
+ GLOB_ITEM_ENU("hwts_filter", HWTS_FILTER_NORMAL, hwts_filter_enu),
|
|
PORT_ITEM_INT("hybrid_e2e", 0, 0, 1),
|
|
PORT_ITEM_INT("ignore_transport_specific", 0, 0, 1),
|
|
PORT_ITEM_INT("ingressLatency", 0, INT_MIN, INT_MAX),
|
|
diff --git a/ptp4l.8 b/ptp4l.8
|
|
index 10c5c2f..39bf36e 100644
|
|
--- a/ptp4l.8
|
|
+++ b/ptp4l.8
|
|
@@ -661,6 +661,15 @@ The time source is a single byte code that gives an idea of the kind
|
|
of local clock in use. The value is purely informational, having no
|
|
effect on the outcome of the Best Master Clock algorithm, and is
|
|
advertised when the clock becomes grand master.
|
|
+.TP
|
|
+.B hwts_filter
|
|
+Select the hardware time stamp filter setting mode.
|
|
+Possible values are normal, check, full.
|
|
+Normal mode set the filters as needed.
|
|
+Check mode only check but do not set.
|
|
+Full mode set the receive filter to mark all packets with hardware time stamp,
|
|
+ so all applications can get them.
|
|
+The default is normal.
|
|
|
|
.SH UNICAST DISCOVERY OPTIONS
|
|
|
|
diff --git a/ptp4l.c b/ptp4l.c
|
|
index 9ef8169..3a9f084 100644
|
|
--- a/ptp4l.c
|
|
+++ b/ptp4l.c
|
|
@@ -191,6 +191,7 @@ int main(int argc, char *argv[])
|
|
assume_two_step = config_get_int(cfg, NULL, "assume_two_step");
|
|
sk_check_fupsync = config_get_int(cfg, NULL, "check_fup_sync");
|
|
sk_tx_timeout = config_get_int(cfg, NULL, "tx_timestamp_timeout");
|
|
+ sk_hwts_filter_mode = config_get_int(cfg, NULL, "hwts_filter");
|
|
|
|
if (config_get_int(cfg, NULL, "clock_servo") == CLOCK_SERVO_NTPSHM) {
|
|
config_set_int(cfg, "kernel_leap", 0);
|
|
diff --git a/sk.c b/sk.c
|
|
index f18b2bf..43f1800 100644
|
|
--- a/sk.c
|
|
+++ b/sk.c
|
|
@@ -40,39 +40,76 @@
|
|
|
|
int sk_tx_timeout = 1;
|
|
int sk_check_fupsync;
|
|
+enum hwts_filter_mode sk_hwts_filter_mode = HWTS_FILTER_NORMAL;
|
|
|
|
/* private methods */
|
|
|
|
-static int hwts_init(int fd, const char *device, int rx_filter, int tx_type)
|
|
+static void init_ifreq(struct ifreq *ifreq, struct hwtstamp_config *cfg,
|
|
+ const char *device)
|
|
{
|
|
- struct ifreq ifreq;
|
|
- struct hwtstamp_config cfg, req;
|
|
- int err;
|
|
+ memset(ifreq, 0, sizeof(*ifreq));
|
|
+ memset(cfg, 0, sizeof(*cfg));
|
|
|
|
- memset(&ifreq, 0, sizeof(ifreq));
|
|
- memset(&cfg, 0, sizeof(cfg));
|
|
+ strncpy(ifreq->ifr_name, device, sizeof(ifreq->ifr_name) - 1);
|
|
|
|
- strncpy(ifreq.ifr_name, device, sizeof(ifreq.ifr_name) - 1);
|
|
+ ifreq->ifr_data = (void *) cfg;
|
|
+}
|
|
|
|
- ifreq.ifr_data = (void *) &cfg;
|
|
- cfg.tx_type = tx_type;
|
|
- cfg.rx_filter = rx_filter;
|
|
- req = cfg;
|
|
- err = ioctl(fd, SIOCSHWTSTAMP, &ifreq);
|
|
- if (err < 0)
|
|
- return err;
|
|
+static int hwts_init(int fd, const char *device, int rx_filter,
|
|
+ int rx_filter2, int tx_type)
|
|
+{
|
|
+ struct ifreq ifreq;
|
|
+ struct hwtstamp_config cfg;
|
|
+ int err;
|
|
|
|
- if (memcmp(&cfg, &req, sizeof(cfg))) {
|
|
+ init_ifreq(&ifreq, &cfg, device);
|
|
|
|
- pr_debug("driver changed our HWTSTAMP options");
|
|
- pr_debug("tx_type %d not %d", cfg.tx_type, req.tx_type);
|
|
- pr_debug("rx_filter %d not %d", cfg.rx_filter, req.rx_filter);
|
|
+ switch (sk_hwts_filter_mode) {
|
|
+ case HWTS_FILTER_CHECK:
|
|
+ err = ioctl(fd, SIOCGHWTSTAMP, &ifreq);
|
|
+ if (err < 0) {
|
|
+ pr_err("ioctl SIOCGHWTSTAMP failed: %m");
|
|
+ return err;
|
|
+ }
|
|
+ break;
|
|
+ case HWTS_FILTER_FULL:
|
|
+ cfg.tx_type = tx_type;
|
|
+ cfg.rx_filter = HWTSTAMP_FILTER_ALL;
|
|
+ err = ioctl(fd, SIOCSHWTSTAMP, &ifreq);
|
|
+ if (err < 0) {
|
|
+ pr_err("ioctl SIOCSHWTSTAMP failed: %m");
|
|
+ return err;
|
|
+ }
|
|
+ break;
|
|
+ case HWTS_FILTER_NORMAL:
|
|
+ cfg.tx_type = tx_type;
|
|
+ cfg.rx_filter = rx_filter;
|
|
+ err = ioctl(fd, SIOCSHWTSTAMP, &ifreq);
|
|
+ if (err < 0) {
|
|
+ pr_info("driver rejected most general HWTSTAMP filter");
|
|
|
|
- if (cfg.tx_type != req.tx_type ||
|
|
- (cfg.rx_filter != HWTSTAMP_FILTER_ALL &&
|
|
- cfg.rx_filter != HWTSTAMP_FILTER_PTP_V2_EVENT)) {
|
|
- return -1;
|
|
+ init_ifreq(&ifreq, &cfg, device);
|
|
+ cfg.tx_type = tx_type;
|
|
+ cfg.rx_filter = rx_filter2;
|
|
+
|
|
+ err = ioctl(fd, SIOCSHWTSTAMP, &ifreq);
|
|
+ if (err < 0) {
|
|
+ pr_err("ioctl SIOCSHWTSTAMP failed: %m");
|
|
+ return err;
|
|
+ }
|
|
}
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (cfg.tx_type != tx_type ||
|
|
+ (cfg.rx_filter != rx_filter &&
|
|
+ cfg.rx_filter != rx_filter2 &&
|
|
+ cfg.rx_filter != HWTSTAMP_FILTER_ALL)) {
|
|
+ pr_debug("tx_type %d not %d", cfg.tx_type, tx_type);
|
|
+ pr_debug("rx_filter %d not %d or %d", cfg.rx_filter, rx_filter,
|
|
+ rx_filter2);
|
|
+ pr_err("The current filter does not match the required");
|
|
+ return -1;
|
|
}
|
|
|
|
return 0;
|
|
@@ -450,15 +487,9 @@ int sk_timestamping_init(int fd, const char *device, enum timestamp_type type,
|
|
case TRANS_UDS:
|
|
return -1;
|
|
}
|
|
- err = hwts_init(fd, device, filter1, tx_type);
|
|
- if (err) {
|
|
- pr_info("driver rejected most general HWTSTAMP filter");
|
|
- err = hwts_init(fd, device, filter2, tx_type);
|
|
- if (err) {
|
|
- pr_err("ioctl SIOCSHWTSTAMP failed: %m");
|
|
- return err;
|
|
- }
|
|
- }
|
|
+ err = hwts_init(fd, device, filter1, filter2, tx_type);
|
|
+ if (err)
|
|
+ return err;
|
|
}
|
|
|
|
if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING,
|
|
diff --git a/sk.h b/sk.h
|
|
index d91d5d8..fd4d820 100644
|
|
--- a/sk.h
|
|
+++ b/sk.h
|
|
@@ -23,6 +23,16 @@
|
|
#include "address.h"
|
|
#include "transport.h"
|
|
|
|
+/**
|
|
+ * Defines the available Hardware time-stamp setting modes.
|
|
+ */
|
|
+
|
|
+enum hwts_filter_mode {
|
|
+ HWTS_FILTER_NORMAL, /* set hardware filters in normal way */
|
|
+ HWTS_FILTER_CHECK, /* check filters but do not change them */
|
|
+ HWTS_FILTER_FULL, /* Use time-stamp on all received packets */
|
|
+};
|
|
+
|
|
/**
|
|
* Contains timestamping information returned by the GET_TS_INFO ioctl.
|
|
* @valid: set to non-zero when the info struct contains valid data.
|
|
@@ -131,4 +141,9 @@ extern int sk_tx_timeout;
|
|
*/
|
|
extern int sk_check_fupsync;
|
|
|
|
+/**
|
|
+ * Hardware time-stamp setting mode
|
|
+ */
|
|
+extern enum hwts_filter_mode sk_hwts_filter_mode;
|
|
+
|
|
#endif
|