Message ID | 20221128103227.23171-3-arun.ramadoss@microchip.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | net: dsa: microchip: add PTP support for KSZ9563/KSZ8563 and LAN937x | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Clearly marked for net-next |
netdev/fixes_present | success | Fixes tag not required for -next series |
netdev/subject_prefix | success | Link |
netdev/cover_letter | success | Series has a cover letter |
netdev/patch_count | success | Link |
netdev/header_inline | success | No static functions without inline keyword in header files |
netdev/build_32bit | success | Errors and warnings before: 0 this patch: 0 |
netdev/cc_maintainers | success | CCed 11 of 11 maintainers |
netdev/build_clang | success | Errors and warnings before: 0 this patch: 0 |
netdev/module_param | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Signed-off-by tag matches author and committer |
netdev/check_selftest | success | No net selftest shell script |
netdev/verify_fixes | success | No Fixes tag |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 0 this patch: 0 |
netdev/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 134 lines checked |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/source_inline | success | Was 0 now: 0 |
On Mon, Nov 28, 2022 at 4:03 PM Arun Ramadoss <arun.ramadoss@microchip.com> wrote: > > From: Christian Eggers <ceggers@arri.de> > > This patch adds the routine for get_ts_info, hwstamp_get, set. This enables > the PTP support towards userspace applications such as linuxptp. > Tx timestamping can be enabled per port and Rx timestamping enabled > globally. > > Signed-off-by: Christian Eggers <ceggers@arri.de> > Co-developed-by: Arun Ramadoss <arun.ramadoss@microchip.com> > Signed-off-by: Arun Ramadoss <arun.ramadoss@microchip.com> > > --- > RFC v2 -> Patch v1 > - moved tagger set and get function to separate patch > - Removed unnecessary comments > --- > drivers/net/dsa/microchip/ksz_common.c | 2 + > drivers/net/dsa/microchip/ksz_common.h | 4 ++ > drivers/net/dsa/microchip/ksz_ptp.c | 77 +++++++++++++++++++++++++- > drivers/net/dsa/microchip/ksz_ptp.h | 14 +++++ > 4 files changed, 95 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c > index 2d09cd141db6..7b85b258270c 100644 > --- a/drivers/net/dsa/microchip/ksz_common.c > +++ b/drivers/net/dsa/microchip/ksz_common.c > @@ -2873,6 +2873,8 @@ static const struct dsa_switch_ops ksz_switch_ops = { > .port_change_mtu = ksz_change_mtu, > .port_max_mtu = ksz_max_mtu, > .get_ts_info = ksz_get_ts_info, > + .port_hwtstamp_get = ksz_hwtstamp_get, > + .port_hwtstamp_set = ksz_hwtstamp_set, > }; > > struct ksz_device *ksz_switch_alloc(struct device *base, void *priv) > diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h > index 5a6bfd42c6f9..cd20f39a565f 100644 > --- a/drivers/net/dsa/microchip/ksz_common.h > +++ b/drivers/net/dsa/microchip/ksz_common.h > @@ -103,6 +103,10 @@ struct ksz_port { > struct ksz_device *ksz_dev; > struct ksz_irq pirq; > u8 num; > +#if IS_ENABLED(CONFIG_NET_DSA_MICROCHIP_KSZ_PTP) > + u8 hwts_tx_en; > + bool hwts_rx_en; I see that the hwts_rx_en gets removed in the later patch. Instead you could add rx filters support only later when you have the final code in place. > +#endif > }; > > struct ksz_device { > diff --git a/drivers/net/dsa/microchip/ksz_ptp.c b/drivers/net/dsa/microchip/ksz_ptp.c > index c737635ca266..a41418c6adf6 100644 > --- a/drivers/net/dsa/microchip/ksz_ptp.c > +++ b/drivers/net/dsa/microchip/ksz_ptp.c > @@ -36,15 +36,88 @@ int ksz_get_ts_info(struct dsa_switch *ds, int port, struct ethtool_ts_info *ts) > SOF_TIMESTAMPING_RX_HARDWARE | > SOF_TIMESTAMPING_RAW_HARDWARE; > > - ts->tx_types = BIT(HWTSTAMP_TX_OFF); > + ts->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ONESTEP_P2P); > > - ts->rx_filters = BIT(HWTSTAMP_FILTER_NONE); > + ts->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL); > > ts->phc_index = ptp_clock_index(ptp_data->clock); > > return 0; > } > > +int ksz_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr) > +{ > + struct ksz_device *dev = ds->priv; > + struct hwtstamp_config config; > + > + config.flags = 0; > + > + config.tx_type = dev->ports[port].hwts_tx_en; > + > + if (dev->ports[port].hwts_rx_en) > + config.rx_filter = HWTSTAMP_FILTER_ALL; > + else > + config.rx_filter = HWTSTAMP_FILTER_NONE; > + > + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? > + -EFAULT : 0; > +} > + > +static int ksz_set_hwtstamp_config(struct ksz_device *dev, int port, > + struct hwtstamp_config *config) > +{ > + struct ksz_port *prt = &dev->ports[port]; > + > + if (config->flags) > + return -EINVAL; > + > + switch (config->tx_type) { > + case HWTSTAMP_TX_OFF: > + case HWTSTAMP_TX_ONESTEP_P2P: > + prt->hwts_tx_en = config->tx_type; > + break; > + default: > + return -ERANGE; > + } > + > + switch (config->rx_filter) { > + case HWTSTAMP_FILTER_NONE: > + prt->hwts_rx_en = false; > + break; > + default: > + prt->hwts_rx_en = true; > + break; > + } > + > + return 0; > +} > + > +int ksz_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr) > +{ > + struct ksz_device *dev = ds->priv; > + struct ksz_ptp_data *ptp_data; > + struct hwtstamp_config config; > + int ret; > + > + ptp_data = &dev->ptp_data; > + > + mutex_lock(&ptp_data->lock); > + > + ret = copy_from_user(&config, ifr->ifr_data, sizeof(config)); > + if (ret) > + goto error_return; > + > + ret = ksz_set_hwtstamp_config(dev, port, &config); > + if (ret) > + goto error_return; > + > + ret = copy_to_user(ifr->ifr_data, &config, sizeof(config)); > + > +error_return: > + mutex_unlock(&ptp_data->lock); > + return ret; > +} > + > static int _ksz_ptp_gettime(struct ksz_device *dev, struct timespec64 *ts) > { > u32 nanoseconds; > diff --git a/drivers/net/dsa/microchip/ksz_ptp.h b/drivers/net/dsa/microchip/ksz_ptp.h > index ea9fa46caa01..17f455c3b2c5 100644 > --- a/drivers/net/dsa/microchip/ksz_ptp.h > +++ b/drivers/net/dsa/microchip/ksz_ptp.h > @@ -23,6 +23,8 @@ void ksz_ptp_clock_unregister(struct dsa_switch *ds); > > int ksz_get_ts_info(struct dsa_switch *ds, int port, > struct ethtool_ts_info *ts); > +int ksz_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr); > +int ksz_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr); > > #else > > @@ -40,6 +42,18 @@ static inline void ksz_ptp_clock_unregister(struct dsa_switch *ds) { } > > #define ksz_get_ts_info NULL > > +static inline int ksz_hwtstamp_get(struct dsa_switch *ds, int port, > + struct ifreq *ifr) > +{ > + return -EOPNOTSUPP; > +} > + > +static inline int ksz_hwtstamp_set(struct dsa_switch *ds, int port, > + struct ifreq *ifr) > +{ > + return -EOPNOTSUPP; > +} > + > #endif /* End of CONFIG_NET_DSA_MICROCHIP_KSZ_PTP */ > > #endif > -- > 2.36.1 >
Hi Pavan, Thanks for the comment. On Tue, 2022-11-29 at 14:19 +0530, Pavan Chebbi wrote: > On Mon, Nov 28, 2022 at 4:03 PM Arun Ramadoss > <arun.ramadoss@microchip.com> wrote: > > > > From: Christian Eggers <ceggers@arri.de> > > > > This patch adds the routine for get_ts_info, hwstamp_get, set. This > > enables > > the PTP support towards userspace applications such as linuxptp. > > Tx timestamping can be enabled per port and Rx timestamping enabled > > globally. > > > > Signed-off-by: Christian Eggers <ceggers@arri.de> > > Co-developed-by: Arun Ramadoss <arun.ramadoss@microchip.com> > > Signed-off-by: Arun Ramadoss <arun.ramadoss@microchip.com> > > > > --- > > RFC v2 -> Patch v1 > > - moved tagger set and get function to separate patch > > - Removed unnecessary comments > > --- > > drivers/net/dsa/microchip/ksz_common.c | 2 + > > drivers/net/dsa/microchip/ksz_common.h | 4 ++ > > drivers/net/dsa/microchip/ksz_ptp.c | 77 > > +++++++++++++++++++++++++- > > drivers/net/dsa/microchip/ksz_ptp.h | 14 +++++ > > 4 files changed, 95 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/net/dsa/microchip/ksz_common.c > > b/drivers/net/dsa/microchip/ksz_common.c > > index 2d09cd141db6..7b85b258270c 100644 > > --- a/drivers/net/dsa/microchip/ksz_common.c > > +++ b/drivers/net/dsa/microchip/ksz_common.c > > @@ -2873,6 +2873,8 @@ static const struct dsa_switch_ops > > ksz_switch_ops = { > > .port_change_mtu = ksz_change_mtu, > > .port_max_mtu = ksz_max_mtu, > > .get_ts_info = ksz_get_ts_info, > > + .port_hwtstamp_get = ksz_hwtstamp_get, > > + .port_hwtstamp_set = ksz_hwtstamp_set, > > }; > > > > struct ksz_device *ksz_switch_alloc(struct device *base, void > > *priv) > > diff --git a/drivers/net/dsa/microchip/ksz_common.h > > b/drivers/net/dsa/microchip/ksz_common.h > > index 5a6bfd42c6f9..cd20f39a565f 100644 > > --- a/drivers/net/dsa/microchip/ksz_common.h > > +++ b/drivers/net/dsa/microchip/ksz_common.h > > @@ -103,6 +103,10 @@ struct ksz_port { > > struct ksz_device *ksz_dev; > > struct ksz_irq pirq; > > u8 num; > > +#if IS_ENABLED(CONFIG_NET_DSA_MICROCHIP_KSZ_PTP) > > + u8 hwts_tx_en; > > + bool hwts_rx_en; > > I see that the hwts_rx_en gets removed in the later patch. Instead > you > could add rx filters support only later when you have the final code > in place. In RFC v2, this patch 2 and next patch 3 are in single patch. There are two simple reasons, I had splitted them two. One is to have logical commit and ease of code review. Patch 2 will add the hwtstamp_set and get dsa hooks and patch 3 to mechanism to coordinate with the tag_ksz.c to add additional 4 bytes in tail tag when PTP is enabled based on tagger_data. Second reason to split is to have patch authorship. I had used the Christian Eggers patch and extending support for LAN937x. In the initial series, it has dsa_port->priv variable to store the ptp_shared_data. Now priv variable is removed from dsa_port so I used tagger_data based on sja1105 implementation. As it is different from intial patch series, moved to separate patch. > > > +#endif > > }; > > > > > > > > > > > > #endif > > -- > > 2.36.1 > >
On Mon, Nov 28, 2022 at 04:02:17PM +0530, Arun Ramadoss wrote: > diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h > index 5a6bfd42c6f9..cd20f39a565f 100644 > --- a/drivers/net/dsa/microchip/ksz_common.h > +++ b/drivers/net/dsa/microchip/ksz_common.h > @@ -103,6 +103,10 @@ struct ksz_port { > struct ksz_device *ksz_dev; > struct ksz_irq pirq; > u8 num; > +#if IS_ENABLED(CONFIG_NET_DSA_MICROCHIP_KSZ_PTP) > + u8 hwts_tx_en; Variable named "en" (enable) which takes the values 0 or 2? Not good. Also, why is the type not enum hwtstamp_tx_types, but u8? Can't you name this "enum hwtstamp_tx_types tx_type"? > + bool hwts_rx_en; > +#endif > }; > > struct ksz_device { > diff --git a/drivers/net/dsa/microchip/ksz_ptp.c b/drivers/net/dsa/microchip/ksz_ptp.c > index c737635ca266..a41418c6adf6 100644 > --- a/drivers/net/dsa/microchip/ksz_ptp.c > +++ b/drivers/net/dsa/microchip/ksz_ptp.c > @@ -36,15 +36,88 @@ int ksz_get_ts_info(struct dsa_switch *ds, int port, struct ethtool_ts_info *ts) > SOF_TIMESTAMPING_RX_HARDWARE | > SOF_TIMESTAMPING_RAW_HARDWARE; > > - ts->tx_types = BIT(HWTSTAMP_TX_OFF); > + ts->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ONESTEP_P2P); > > - ts->rx_filters = BIT(HWTSTAMP_FILTER_NONE); > + ts->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL); > > ts->phc_index = ptp_clock_index(ptp_data->clock); > > return 0; > } > > +int ksz_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr) > +{ > + struct ksz_device *dev = ds->priv; > + struct hwtstamp_config config; > + > + config.flags = 0; > + > + config.tx_type = dev->ports[port].hwts_tx_en; > + > + if (dev->ports[port].hwts_rx_en) > + config.rx_filter = HWTSTAMP_FILTER_ALL; > + else > + config.rx_filter = HWTSTAMP_FILTER_NONE; > + > + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? > + -EFAULT : 0; > +} > + > +static int ksz_set_hwtstamp_config(struct ksz_device *dev, int port, > + struct hwtstamp_config *config) > +{ > + struct ksz_port *prt = &dev->ports[port]; > + > + if (config->flags) > + return -EINVAL; > + > + switch (config->tx_type) { > + case HWTSTAMP_TX_OFF: > + case HWTSTAMP_TX_ONESTEP_P2P: > + prt->hwts_tx_en = config->tx_type; > + break; > + default: > + return -ERANGE; > + } > + > + switch (config->rx_filter) { > + case HWTSTAMP_FILTER_NONE: > + prt->hwts_rx_en = false; > + break; > + default: > + prt->hwts_rx_en = true; > + break; > + } > + > + return 0; > +} > + > +int ksz_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr) > +{ > + struct ksz_device *dev = ds->priv; > + struct ksz_ptp_data *ptp_data; > + struct hwtstamp_config config; > + int ret; > + > + ptp_data = &dev->ptp_data; > + > + mutex_lock(&ptp_data->lock); I'm not sure that this mutex serves any purpose at all? One could have argued that concurrent calls to ksz_hwtstamp_get() shouldn't be able to see incoherent values of prt->hwts_tx_en and of prt->hwts_rx_en. But ksz_hwtstamp_get() doesn't acquire this mutex, so that is not true, this isn't why the mutex is acquired here. I don't know why it is. > + > + ret = copy_from_user(&config, ifr->ifr_data, sizeof(config)); > + if (ret) > + goto error_return; > + > + ret = ksz_set_hwtstamp_config(dev, port, &config); > + if (ret) > + goto error_return; > + > + ret = copy_to_user(ifr->ifr_data, &config, sizeof(config)); > + > +error_return: > + mutex_unlock(&ptp_data->lock); > + return ret; > +}
Hi Vladimir, On Thu, 2022-12-01 at 02:39 +0200, Vladimir Oltean wrote: > EXTERNAL EMAIL: Do not click links or open attachments unless you > know the content is safe > > On Mon, Nov 28, 2022 at 04:02:17PM +0530, Arun Ramadoss wrote: > > diff --git a/drivers/net/dsa/microchip/ksz_common.h > > b/drivers/net/dsa/microchip/ksz_common.h > > index 5a6bfd42c6f9..cd20f39a565f 100644 > > --- a/drivers/net/dsa/microchip/ksz_common.h > > +++ b/drivers/net/dsa/microchip/ksz_common.h > > @@ -103,6 +103,10 @@ struct ksz_port { > > struct ksz_device *ksz_dev; > > struct ksz_irq pirq; > > u8 num; > > +#if IS_ENABLED(CONFIG_NET_DSA_MICROCHIP_KSZ_PTP) > > + u8 hwts_tx_en; > > Variable named "en" (enable) which takes the values 0 or 2? Not good. > Also, why is the type not enum hwtstamp_tx_types, but u8? Can't you > name > this "enum hwtstamp_tx_types tx_type"? > > > + bool hwts_rx_en; > > +#endif > > }; I will rename variable. > > > > struct ksz_device { > > diff --git a/drivers/net/dsa/microchip/ksz_ptp.c > > b/drivers/net/dsa/microchip/ksz_ptp.c > > index c737635ca266..a41418c6adf6 100644 > > --- a/drivers/net/dsa/microchip/ksz_ptp.c > > +++ b/drivers/net/dsa/microchip/ksz_ptp.c > > @@ -36,15 +36,88 @@ int ksz_get_ts_info(struct dsa_switch *ds, int > > port, struct ethtool_ts_info *ts) > > SOF_TIMESTAMPING_RX_HARDWARE | > > SOF_TIMESTAMPING_RAW_HARDWARE; > > > > - ts->tx_types = BIT(HWTSTAMP_TX_OFF); > > + ts->tx_types = BIT(HWTSTAMP_TX_OFF) | > > BIT(HWTSTAMP_TX_ONESTEP_P2P); > > > > - ts->rx_filters = BIT(HWTSTAMP_FILTER_NONE); > > + ts->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | > > BIT(HWTSTAMP_FILTER_ALL); > > > > ts->phc_index = ptp_clock_index(ptp_data->clock); > > > > return 0; > > } > > > > +int ksz_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq > > *ifr) > > +{ > > + struct ksz_device *dev = ds->priv; > > + struct hwtstamp_config config; > > + > > + config.flags = 0; > > + > > + config.tx_type = dev->ports[port].hwts_tx_en; > > + > > + if (dev->ports[port].hwts_rx_en) > > + config.rx_filter = HWTSTAMP_FILTER_ALL; > > + else > > + config.rx_filter = HWTSTAMP_FILTER_NONE; > > + > > + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? > > + -EFAULT : 0; > > +} > > + > > +static int ksz_set_hwtstamp_config(struct ksz_device *dev, int > > port, > > + struct hwtstamp_config *config) > > +{ > > + struct ksz_port *prt = &dev->ports[port]; > > + > > + if (config->flags) > > + return -EINVAL; > > + > > + switch (config->tx_type) { > > + case HWTSTAMP_TX_OFF: > > + case HWTSTAMP_TX_ONESTEP_P2P: > > + prt->hwts_tx_en = config->tx_type; > > + break; > > + default: > > + return -ERANGE; > > + } > > + > > + switch (config->rx_filter) { > > + case HWTSTAMP_FILTER_NONE: > > + prt->hwts_rx_en = false; > > + break; > > + default: > > + prt->hwts_rx_en = true; > > + break; > > + } > > + > > + return 0; > > +} > > + > > +int ksz_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq > > *ifr) > > +{ > > + struct ksz_device *dev = ds->priv; > > + struct ksz_ptp_data *ptp_data; > > + struct hwtstamp_config config; > > + int ret; > > + > > + ptp_data = &dev->ptp_data; > > + > > + mutex_lock(&ptp_data->lock); > > I'm not sure that this mutex serves any purpose at all? > > One could have argued that concurrent calls to ksz_hwtstamp_get() > shouldn't be able to see incoherent values of prt->hwts_tx_en and of > prt->hwts_rx_en. > > But ksz_hwtstamp_get() doesn't acquire this mutex, so that is not > true, > this isn't why the mutex is acquired here. I don't know why it is. Mutex is not needed. I will remove it. > > > + > > + ret = copy_from_user(&config, ifr->ifr_data, sizeof(config)); > > + if (ret) > > + goto error_return; > > + > > + ret = ksz_set_hwtstamp_config(dev, port, &config); > > + if (ret) > > + goto error_return; > > + > > + ret = copy_to_user(ifr->ifr_data, &config, sizeof(config)); > > + > > +error_return: > > + mutex_unlock(&ptp_data->lock); > > + return ret; > > +}
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 2d09cd141db6..7b85b258270c 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -2873,6 +2873,8 @@ static const struct dsa_switch_ops ksz_switch_ops = { .port_change_mtu = ksz_change_mtu, .port_max_mtu = ksz_max_mtu, .get_ts_info = ksz_get_ts_info, + .port_hwtstamp_get = ksz_hwtstamp_get, + .port_hwtstamp_set = ksz_hwtstamp_set, }; struct ksz_device *ksz_switch_alloc(struct device *base, void *priv) diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index 5a6bfd42c6f9..cd20f39a565f 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -103,6 +103,10 @@ struct ksz_port { struct ksz_device *ksz_dev; struct ksz_irq pirq; u8 num; +#if IS_ENABLED(CONFIG_NET_DSA_MICROCHIP_KSZ_PTP) + u8 hwts_tx_en; + bool hwts_rx_en; +#endif }; struct ksz_device { diff --git a/drivers/net/dsa/microchip/ksz_ptp.c b/drivers/net/dsa/microchip/ksz_ptp.c index c737635ca266..a41418c6adf6 100644 --- a/drivers/net/dsa/microchip/ksz_ptp.c +++ b/drivers/net/dsa/microchip/ksz_ptp.c @@ -36,15 +36,88 @@ int ksz_get_ts_info(struct dsa_switch *ds, int port, struct ethtool_ts_info *ts) SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE; - ts->tx_types = BIT(HWTSTAMP_TX_OFF); + ts->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ONESTEP_P2P); - ts->rx_filters = BIT(HWTSTAMP_FILTER_NONE); + ts->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL); ts->phc_index = ptp_clock_index(ptp_data->clock); return 0; } +int ksz_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr) +{ + struct ksz_device *dev = ds->priv; + struct hwtstamp_config config; + + config.flags = 0; + + config.tx_type = dev->ports[port].hwts_tx_en; + + if (dev->ports[port].hwts_rx_en) + config.rx_filter = HWTSTAMP_FILTER_ALL; + else + config.rx_filter = HWTSTAMP_FILTER_NONE; + + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? + -EFAULT : 0; +} + +static int ksz_set_hwtstamp_config(struct ksz_device *dev, int port, + struct hwtstamp_config *config) +{ + struct ksz_port *prt = &dev->ports[port]; + + if (config->flags) + return -EINVAL; + + switch (config->tx_type) { + case HWTSTAMP_TX_OFF: + case HWTSTAMP_TX_ONESTEP_P2P: + prt->hwts_tx_en = config->tx_type; + break; + default: + return -ERANGE; + } + + switch (config->rx_filter) { + case HWTSTAMP_FILTER_NONE: + prt->hwts_rx_en = false; + break; + default: + prt->hwts_rx_en = true; + break; + } + + return 0; +} + +int ksz_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr) +{ + struct ksz_device *dev = ds->priv; + struct ksz_ptp_data *ptp_data; + struct hwtstamp_config config; + int ret; + + ptp_data = &dev->ptp_data; + + mutex_lock(&ptp_data->lock); + + ret = copy_from_user(&config, ifr->ifr_data, sizeof(config)); + if (ret) + goto error_return; + + ret = ksz_set_hwtstamp_config(dev, port, &config); + if (ret) + goto error_return; + + ret = copy_to_user(ifr->ifr_data, &config, sizeof(config)); + +error_return: + mutex_unlock(&ptp_data->lock); + return ret; +} + static int _ksz_ptp_gettime(struct ksz_device *dev, struct timespec64 *ts) { u32 nanoseconds; diff --git a/drivers/net/dsa/microchip/ksz_ptp.h b/drivers/net/dsa/microchip/ksz_ptp.h index ea9fa46caa01..17f455c3b2c5 100644 --- a/drivers/net/dsa/microchip/ksz_ptp.h +++ b/drivers/net/dsa/microchip/ksz_ptp.h @@ -23,6 +23,8 @@ void ksz_ptp_clock_unregister(struct dsa_switch *ds); int ksz_get_ts_info(struct dsa_switch *ds, int port, struct ethtool_ts_info *ts); +int ksz_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr); +int ksz_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr); #else @@ -40,6 +42,18 @@ static inline void ksz_ptp_clock_unregister(struct dsa_switch *ds) { } #define ksz_get_ts_info NULL +static inline int ksz_hwtstamp_get(struct dsa_switch *ds, int port, + struct ifreq *ifr) +{ + return -EOPNOTSUPP; +} + +static inline int ksz_hwtstamp_set(struct dsa_switch *ds, int port, + struct ifreq *ifr) +{ + return -EOPNOTSUPP; +} + #endif /* End of CONFIG_NET_DSA_MICROCHIP_KSZ_PTP */ #endif