>
>
>> Device driver can only get info about the current PTP port state
>> from ptp4l, because it doesn’t have direct access to it.
>>
>
> And this helps?
>
Yes, with dynamically switching RX filters I was able to change my Ethernet
controller state from Master to Slave and vice versa.

I meant a little different in my description, but I'll consider your
recommendations and update the description.

Do you suggest using HWTSTAMP_FILTER_PTP_V1?
> Or only HWTSTAMP_FILTER_PTP_V2?
>

I suggest using only HWTSTAMP_FILTER_PTP_V2 filters. I'll also mention it
in the description.

On Tue, 14 Nov 2023 at 23:21, Erez <erezge...@gmail.com> wrote:

>
>
> On Tue, 14 Nov 2023 at 23:21, Erez <erezge...@gmail.com> wrote:

>
>
> On Mon, 13 Nov 2023 at 18:49, IlorDash <ilordas...@gmail.com> wrote:
>
>> From: Ilya Orazov <ilordas...@gmail.com>
>>
>> Added adv_rx_filter config that allows to send SIOCSHWTSTAMP ioctl with
>> HWTSTAMP_FILTER_PTP_XXX_SYNC or HWTSTAMP_FILTER_PTP_XXX_DELAY_REQ
>> rx filters based on whether the Device is Slave or Master respectively.
>> This Feature is added for all transport levels.
>
>
>> I’m using Ethernet controller with PTP support, which requires to
>> determine which PTP packet on Rx it must timestamp: SYNC or DELAY_REQ
>> packets based on whether the device is Slave or Masterrespectively.
>
> Unfortunately, I’ve found out that ptp4l can’t send SIOCSHWTSTAMP ioctl
>> with HWTSTAMP_FILTER_PTP_XXX_SYNC or HWTSTAMP_FILTER_PTP_XXX_DELAY_REQ
>> rx filters, and sends only EVENT rx filters to device driver.
>>
>
> This is by design, not a mistake.
> Most controllers allow timestamp all RX packets.
> Users usually limit, to save resources.
>
> You can set the values using the 'hwstamp_ctl' tool.
>
> The reason to add this functionality to ptp4l is to allow dynamic change
> from
> master to slave.
>
> Please update the description to explain properly.
>
>
>
>> Device driver can only get info about the current PTP port state
>> from ptp4l, because it doesn’t have direct access to it.
>>
>
> And this helps?
>
>
>> I assumed, if these filters are defined in Kernel, they might be used in
>>
>
> No need to fix the kernel.
>
>
>> ptp4l utility to fix this. So I added adv_rx_filter config that allows
>> to send SIOCSHWTSTAMP ioctl with HWTSTAMP_FILTER_PTP_XXX_SYNC or
>> HWTSTAMP_FILTER_PTP_XXX_DELAY_REQ rx filters for all transport levels.
>>
>
> This new feature does make sense.
> But no need to talk on "Unfortunately" or "fix the kernel".
> Just add explanation on why you can *NOT* use RX timestamp on all PTP
> packets.
> And explanation on the new feature.
>
>
>>
>> Signed-off-by: Ilya Orazov <ilordas...@gmail.com>
>> ---
>>  config.c            |  1 +
>>  port.c              | 17 ++++++++++++++
>>  ptp4l.8             |  8 +++++++
>>  ptp4l.c             |  1 +
>>  raw.c               | 13 +++++++++++
>>  sk.c                | 56 ++++++++++++++++++++++++++++++++++++++++-----
>>  sk.h                | 15 ++++++++++++
>>  transport.c         |  7 ++++++
>>  transport.h         |  5 ++++
>>  transport_private.h |  3 +++
>>  udp.c               | 14 ++++++++++++
>>  udp6.c              | 14 ++++++++++++
>>  12 files changed, 148 insertions(+), 6 deletions(-)
>>
>> diff --git a/config.c b/config.c
>> index b104f1b..642b78c 100644
>> --- a/config.c
>> +++ b/config.c
>> @@ -268,6 +268,7 @@ struct config_item config_tab[] = {
>>         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),
>> +       GLOB_ITEM_INT("adv_rx_filter", 0, 0, 1),
>>         PORT_ITEM_INT("hybrid_e2e", 0, 0, 1),
>>         PORT_ITEM_INT("ignore_source_id", 0, 0, 1),
>>         PORT_ITEM_INT("ignore_transport_specific", 0, 0, 1),
>> diff --git a/port.c b/port.c
>> index 5803cd3..2376925 100644
>> --- a/port.c
>> +++ b/port.c
>> @@ -3526,6 +3526,23 @@ int port_state_update(struct port *p, enum
>> fsm_event event, int mdiff)
>>                 p->unicast_state_dirty = true;
>>         }
>>         if (next != p->state) {
>> +               if (sk_adv_rx_filter == 1) {
>> +                       pr_debug("port state update prev %d next %d",
>> p->state,
>> +                                next);
>> +
>> +                       if ((next == PS_MASTER) || (next ==
>> PS_GRAND_MASTER))
>> +                               transport_update_rx_filter(p->trp,
>> p->iface,
>> +                                                          &p->fda,
>> +
>> p->timestamping,
>> +                                                          true);
>> +
>> +                       if (next == PS_UNCALIBRATED)
>> +                               transport_update_rx_filter(p->trp,
>> p->iface,
>> +                                                          &p->fda,
>> +
>> p->timestamping,
>> +                                                          false);
>> +               }
>> +
>>                 port_show_transition(p, next, event);
>>                 p->state = next;
>>                 port_notify_event(p, NOTIFY_PORT_STATE);
>> diff --git a/ptp4l.8 b/ptp4l.8
>> index 40c66c2..9d838eb 100644
>> --- a/ptp4l.8
>> +++ b/ptp4l.8
>> @@ -142,6 +142,14 @@ See UNICAST DISCOVERY OPTIONS, below.
>>
>>  .SH PORT OPTIONS
>>
>> +.TP
>> +.B adv_rx_filter
>> +Enable support of HWTSTAMP_FILTER_PTP_XX_SYNC and
>> HWTSTAMP_FILTER_PTP_XX_DELAY_REQ.
>> +Some Ethernet controllers doesn't support PTP event packets,
>> +thus they must be provided with correct rx_filter for timestamping
>> required packets
>> +(SYNC or DELAY_REQ) depends on whether it's Slave or Master respectively.
>> +The default is 0 or disabled.
>>
>
> Do you suggest using HWTSTAMP_FILTER_PTP_V1?
> Or only HWTSTAMP_FILTER_PTP_V2?
>
>
>
>> +
>>  .TP
>>  .B announceReceiptTimeout
>>  The number of missed Announce messages before the last Announce messages
>> diff --git a/ptp4l.c b/ptp4l.c
>> index c61175b..8f9531a 100644
>> --- a/ptp4l.c
>> +++ b/ptp4l.c
>> @@ -191,6 +191,7 @@ int main(int argc, char *argv[])
>>         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");
>> +       sk_adv_rx_filter = config_get_int(cfg, NULL, "adv_rx_filter");
>>
>>         if (config_get_int(cfg, NULL, "clock_servo") ==
>> CLOCK_SERVO_NTPSHM) {
>>                 config_set_int(cfg, "kernel_leap", 0);
>> diff --git a/raw.c b/raw.c
>> index 1b978f0..7af3b2a 100644
>> --- a/raw.c
>> +++ b/raw.c
>> @@ -363,6 +363,18 @@ no_mac:
>>         return -1;
>>  }
>>
>> +static int raw_update_rx_filter(struct interface *iface, struct fdarray
>> *fda,
>> +                               enum timestamp_type ts_type, bool
>> is_master)
>> +{
>> +       int err;
>> +       const char *name;
>> +
>> +       name = interface_label(iface);
>> +       err = sk_ts_update_rx_filter(fda->fd[FD_EVENT], name, ts_type,
>> +                                    TRANS_IEEE_802_3, is_master);
>> +       return err;
>> +}
>> +
>>  static int raw_recv(struct transport *t, int fd, void *buf, int buflen,
>>                     struct address *addr, struct hw_timestamp *hwts)
>>  {
>> @@ -476,6 +488,7 @@ struct transport *raw_transport_create(void)
>>                 return NULL;
>>         raw->t.close   = raw_close;
>>         raw->t.open    = raw_open;
>> +       raw->t.update_rx_filter = raw_update_rx_filter;
>>         raw->t.recv    = raw_recv;
>>         raw->t.send    = raw_send;
>>         raw->t.release = raw_release;
>> diff --git a/sk.c b/sk.c
>> index 19395c9..a641e45 100644
>> --- a/sk.c
>> +++ b/sk.c
>> @@ -41,6 +41,8 @@
>>
>>  int sk_tx_timeout = 1;
>>  int sk_check_fupsync;
>> +int sk_tx_type = -1;
>> +int sk_adv_rx_filter = -1;
>>  enum hwts_filter_mode sk_hwts_filter_mode = HWTS_FILTER_NORMAL;
>>
>>  /* private methods */
>> @@ -56,7 +58,7 @@ static void init_ifreq(struct ifreq *ifreq, struct
>> hwtstamp_config *cfg,
>>         ifreq->ifr_data = (void *) cfg;
>>  }
>>
>> -static int hwts_init(int fd, const char *device, int rx_filter,
>> +static int hwts_set(int fd, const char *device, int rx_filter,
>>         int rx_filter2, int tx_type)
>>  {
>>         struct ifreq ifreq;
>> @@ -131,7 +133,7 @@ static int hwts_init(int fd, const char *device, int
>> rx_filter,
>>                 pr_err("The current filter does not match the required");
>>                 return -1;
>>         }
>> -
>> +       sk_tx_type = cfg.tx_type;
>>         return 0;
>>  }
>>
>> @@ -556,6 +558,36 @@ int sk_set_priority(int fd, int family, uint8_t dscp)
>>         return 0;
>>  }
>>
>> +int sk_ts_update_rx_filter(int fd, const char *device, enum
>> timestamp_type type,
>> +                          enum transport_type transport, bool is_master)
>> +{
>> +       int err, filter1, filter2 = 0;
>> +
>> +       if (type == TS_SOFTWARE)
>> +               return 0;
>> +
>> +       filter1 = (is_master) ? HWTSTAMP_FILTER_PTP_V2_DELAY_REQ :
>> +                               HWTSTAMP_FILTER_PTP_V2_SYNC;
>> +       switch (transport) {
>> +       case TRANS_UDP_IPV4:
>> +       case TRANS_UDP_IPV6:
>> +               filter2 = (is_master) ?
>> HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ :
>> +                                       HWTSTAMP_FILTER_PTP_V2_L4_SYNC;
>> +               break;
>> +       case TRANS_IEEE_802_3:
>> +               filter2 = (is_master) ?
>> HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ :
>> +                                       HWTSTAMP_FILTER_PTP_V2_L2_SYNC;
>> +               break;
>> +       default:
>> +               return -1;
>> +       }
>> +       pr_debug("update rx filter1 %d, filter2 %d, sk_tx_type %d",
>> filter1,
>> +                filter2, sk_tx_type);
>> +       err = hwts_set(fd, device, filter1, filter2, sk_tx_type);
>> +
>> +       return err;
>> +}
>> +
>>  int sk_timestamping_init(int fd, const char *device, enum timestamp_type
>> type,
>>                          enum transport_type transport, int vclock)
>>  {
>> @@ -585,7 +617,11 @@ int sk_timestamping_init(int fd, const char *device,
>> enum timestamp_type type,
>>         }
>>
>>         if (type != TS_SOFTWARE) {
>> -               filter1 = HWTSTAMP_FILTER_PTP_V2_EVENT;
>> +               if (sk_adv_rx_filter == 1) {
>> +                       filter1 = HWTSTAMP_FILTER_PTP_V2_SYNC;
>> +               } else {
>> +                       filter1 = HWTSTAMP_FILTER_PTP_V2_EVENT;
>> +               }
>>                 switch (type) {
>>                 case TS_SOFTWARE:
>>                         tx_type = HWTSTAMP_TX_OFF;
>> @@ -604,10 +640,18 @@ int sk_timestamping_init(int fd, const char
>> *device, enum timestamp_type type,
>>                 switch (transport) {
>>                 case TRANS_UDP_IPV4:
>>                 case TRANS_UDP_IPV6:
>> -                       filter2 = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
>> +                       if (sk_adv_rx_filter == 1) {
>> +                               filter2 = HWTSTAMP_FILTER_PTP_V2_L4_SYNC;
>> +                       } else {
>> +                               filter2 = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
>> +                       }
>>                         break;
>>                 case TRANS_IEEE_802_3:
>> -                       filter2 = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
>> +                       if (sk_adv_rx_filter == 1) {
>> +                               filter2 = HWTSTAMP_FILTER_PTP_V2_L2_SYNC;
>> +                       } else {
>> +                               filter2 = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
>> +                       }
>>                         break;
>>                 case TRANS_DEVICENET:
>>                 case TRANS_CONTROLNET:
>> @@ -615,7 +659,7 @@ int sk_timestamping_init(int fd, const char *device,
>> enum timestamp_type type,
>>                 case TRANS_UDS:
>>                         return -1;
>>                 }
>> -               err = hwts_init(fd, device, filter1, filter2, tx_type);
>> +               err = hwts_set(fd, device, filter1, filter2, tx_type);
>>                 if (err)
>>                         return err;
>>         }
>> diff --git a/sk.h b/sk.h
>> index 76062d0..88dc878 100644
>> --- a/sk.h
>> +++ b/sk.h
>> @@ -146,6 +146,19 @@ int sk_get_error(int fd);
>>   */
>>  int sk_set_priority(int fd, int family, uint8_t dscp);
>>
>> +/**
>> + * If sk_adv_rx_filter is set, then handle XXX_SYNC and
>> + * XXX_DELAY_REQ hwtstamp_rx_filters.
>> + * @param fd          An open socket.
>> + * @param device      The name of the network interface to configure.
>> + * @param type        The requested flavor of time stamping.
>> + * @param transport   The type of transport used.
>> + * @param is_master   Is current port state is Master.
>> + * @return            Zero on success, non-zero otherwise.
>> + */
>> +int sk_ts_update_rx_filter(int fd, const char *device, enum
>> timestamp_type type,
>> +                          enum transport_type transport, bool is_master);
>> +
>>  /**
>>   * Enable time stamping on a given network interface.
>>   * @param fd          An open socket.
>> @@ -171,6 +184,8 @@ extern int sk_tx_timeout;
>>   */
>>  extern int sk_check_fupsync;
>>
>> +extern int sk_adv_rx_filter;
>> +
>>  /**
>>   * Hardware time-stamp setting mode
>>   */
>> diff --git a/transport.c b/transport.c
>> index 9366fbf..c27137b 100644
>> --- a/transport.c
>> +++ b/transport.c
>> @@ -37,6 +37,13 @@ int transport_open(struct transport *t, struct
>> interface *iface,
>>         return t->open(t, iface, fda, tt);
>>  }
>>
>> +int transport_update_rx_filter(struct transport *t, struct interface
>> *iface,
>> +                              struct fdarray *fda, enum timestamp_type
>> tt,
>> +                              bool is_master)
>> +{
>> +       return t->update_rx_filter(iface, fda, tt, is_master);
>> +}
>> +
>>  int transport_recv(struct transport *t, int fd, struct ptp_message *msg)
>>  {
>>         return t->recv(t, fd, msg, sizeof(msg->data), &msg->address,
>> &msg->hwts);
>> diff --git a/transport.h b/transport.h
>> index 7a7f87b..37ef0f1 100644
>> --- a/transport.h
>> +++ b/transport.h
>> @@ -22,6 +22,7 @@
>>
>>  #include <time.h>
>>  #include <inttypes.h>
>> +#include <stdbool.h>
>>
>>  #include "fd.h"
>>  #include "msg.h"
>> @@ -60,6 +61,10 @@ int transport_close(struct transport *t, struct
>> fdarray *fda);
>>  int transport_open(struct transport *t, struct interface *iface,
>>                    struct fdarray *fda, enum timestamp_type tt);
>>
>> +int transport_update_rx_filter(struct transport *t, struct interface
>> *iface,
>> +                              struct fdarray *fda, enum timestamp_type
>> tt,
>> +                              bool is_master);
>> +
>>  int transport_recv(struct transport *t, int fd, struct ptp_message *msg);
>>
>>  /**
>> diff --git a/transport_private.h b/transport_private.h
>> index ec28e47..61d277f 100644
>> --- a/transport_private.h
>> +++ b/transport_private.h
>> @@ -35,6 +35,9 @@ struct transport {
>>         int (*open)(struct transport *t, struct interface *iface,
>>                     struct fdarray *fda, enum timestamp_type tt);
>>
>> +       int (*update_rx_filter)(struct interface *iface, struct fdarray
>> *fda,
>> +                               enum timestamp_type ts_type, bool
>> is_master);
>> +
>>         int (*recv)(struct transport *t, int fd, void *buf, int buflen,
>>                     struct address *addr, struct hw_timestamp *hwts);
>>
>> diff --git a/udp.c b/udp.c
>> index 7c9402e..b66ff7e 100644
>> --- a/udp.c
>> +++ b/udp.c
>> @@ -208,6 +208,19 @@ no_event:
>>         return -1;
>>  }
>>
>> +static int udp_update_rx_filter(struct interface *iface, struct fdarray
>> *fda,
>> +                               enum timestamp_type ts_type, bool
>> is_master)
>> +{
>> +       int err;
>> +       const char *name;
>> +
>> +       name = interface_label(iface);
>> +       err = sk_ts_update_rx_filter(fda->fd[FD_EVENT], name, ts_type,
>> +                                    TRANS_UDP_IPV4, is_master);
>> +
>> +       return err;
>> +}
>> +
>>  static int udp_recv(struct transport *t, int fd, void *buf, int buflen,
>>                     struct address *addr, struct hw_timestamp *hwts)
>>  {
>> @@ -302,6 +315,7 @@ struct transport *udp_transport_create(void)
>>                 return NULL;
>>         udp->t.close = udp_close;
>>         udp->t.open  = udp_open;
>> +       udp->t.update_rx_filter = udp_update_rx_filter;
>>         udp->t.recv  = udp_recv;
>>         udp->t.send  = udp_send;
>>         udp->t.release = udp_release;
>> diff --git a/udp6.c b/udp6.c
>> index bde1710..6a75962 100644
>> --- a/udp6.c
>> +++ b/udp6.c
>> @@ -225,6 +225,19 @@ no_event:
>>         return -1;
>>  }
>>
>> +static int udp6_update_rx_filter(struct interface *iface, struct fdarray
>> *fda,
>> +                                enum timestamp_type ts_type, bool
>> is_master)
>> +{
>> +       int err;
>> +       const char *name;
>> +
>> +       name = interface_label(iface);
>> +       err = sk_ts_update_rx_filter(fda->fd[FD_EVENT], name, ts_type,
>> +                                    TRANS_UDP_IPV6, is_master);
>> +
>> +       return err;
>> +}
>> +
>>  static int udp6_recv(struct transport *t, int fd, void *buf, int buflen,
>>                      struct address *addr, struct hw_timestamp *hwts)
>>  {
>> @@ -318,6 +331,7 @@ struct transport *udp6_transport_create(void)
>>                 return NULL;
>>         udp6->t.close   = udp6_close;
>>         udp6->t.open    = udp6_open;
>> +       udp6->t.update_rx_filter = udp6_update_rx_filter;
>>         udp6->t.recv    = udp6_recv;
>>         udp6->t.send    = udp6_send;
>>         udp6->t.release = udp6_release;
>> --
>> 2.34.1
>>
>>
>>
>> _______________________________________________
>> Linuxptp-devel mailing list
>> Linuxptp-devel@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/linuxptp-devel
>>
>

-- 
Best regards,
Ilya Orazov
_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to