This allows a completely software implementation if driver support is not
available.
Signed-off-by: Andy Lutomirski <***@amacapital.net>
---
port.c | 8 ++++++++
ptp4l.c | 3 +--
sk.c | 12 +++++++++++-
transport.h | 1 +
4 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/port.c b/port.c
index f03aa05..a4d8efa 100644
--- a/port.c
+++ b/port.c
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <linux/net_tstamp.h>
#include "bmc.h"
#include "clock.h"
@@ -2170,6 +2171,13 @@ struct port *port_open(int phc_index,
return NULL;
}
+ if (timestamping == TS_SOFTWARE &&
+ !(interface->ts_info.so_timestamping &
+ SOF_TIMESTAMPING_TX_SOFTWARE)) {
+ pr_warning("port %d: falling back to userspace tx timestamping");
+ timestamping = TS_SOFTWARE_USERTX;
+ }
+
p->pod = interface->pod;
p->name = interface->name;
p->clock = clock;
diff --git a/ptp4l.c b/ptp4l.c
index a83e3fe..4b0c7a7 100644
--- a/ptp4l.c
+++ b/ptp4l.c
@@ -315,8 +315,7 @@ int main(int argc, char *argv[])
switch (*timestamping) {
case TS_SOFTWARE:
- required_modes |= SOF_TIMESTAMPING_TX_SOFTWARE |
- SOF_TIMESTAMPING_RX_SOFTWARE |
+ required_modes |= SOF_TIMESTAMPING_RX_SOFTWARE |
SOF_TIMESTAMPING_SOFTWARE;
break;
case TS_LEGACY_HW:
diff --git a/sk.c b/sk.c
index 0437ad8..d87fdc0 100644
--- a/sk.c
+++ b/sk.c
@@ -214,6 +214,11 @@ int sk_receive(int fd, void *buf, int buflen,
msg.msg_control = control;
msg.msg_controllen = sizeof(control);
+ if (flags == MSG_ERRQUEUE && hwts->type == TS_SOFTWARE_USERTX) {
+ clock_gettime(CLOCK_REALTIME, &hwts->ts);
+ return 1;
+ }
+
if (flags == MSG_ERRQUEUE) {
struct pollfd pfd = { fd, 0, 0 };
res = poll(&pfd, 1, sk_tx_timeout);
@@ -252,6 +257,7 @@ int sk_receive(int fd, void *buf, int buflen,
switch (hwts->type) {
case TS_SOFTWARE:
+ case TS_SOFTWARE_USERTX:
hwts->ts = ts[0];
break;
case TS_HARDWARE:
@@ -276,6 +282,10 @@ int sk_timestamping_init(int fd, char *device, enum timestamp_type type,
SOF_TIMESTAMPING_RX_SOFTWARE |
SOF_TIMESTAMPING_SOFTWARE;
break;
+ case TS_SOFTWARE_USERTX:
+ flags = SOF_TIMESTAMPING_RX_SOFTWARE |
+ SOF_TIMESTAMPING_SOFTWARE;
+ break;
case TS_HARDWARE:
case TS_ONESTEP:
flags = SOF_TIMESTAMPING_TX_HARDWARE |
@@ -291,7 +301,7 @@ int sk_timestamping_init(int fd, char *device, enum timestamp_type type,
return -1;
}
- if (type != TS_SOFTWARE) {
+ if (type != TS_SOFTWARE && type != TS_SOFTWARE_USERTX) {
filter1 = HWTSTAMP_FILTER_PTP_V2_EVENT;
one_step = type == TS_ONESTEP ? 1 : 0;
switch (transport) {
diff --git a/transport.h b/transport.h
index 46af456..68c3c4d 100644
--- a/transport.h
+++ b/transport.h
@@ -49,6 +49,7 @@ enum transport_event {
enum timestamp_type {
TS_SOFTWARE,
+ TS_SOFTWARE_USERTX,
TS_HARDWARE,
TS_LEGACY_HW,
TS_ONESTEP,
--
1.8.3.1