netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Vadim Fedorenko <vadim.fedorenko@linux.dev>
To: Jiri Pirko <jiri@resnulli.us>, Vadim Fedorenko <vadfed@meta.com>
Cc: Jakub Kicinski <kuba@kernel.org>,
	Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>,
	Jonathan Lemon <jonathan.lemon@gmail.com>,
	Paolo Abeni <pabeni@redhat.com>,
	poros@redhat.com, mschmidt@redhat.com, netdev@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org
Subject: Re: [PATCH RFC v6 6/6] ptp_ocp: implement DPLL ops
Date: Wed, 15 Mar 2023 00:10:33 +0000	[thread overview]
Message-ID: <d192e0ac-3fa3-c799-ac93-84a17e6f6d50@linux.dev> (raw)
In-Reply-To: <ZBBG2xRhLOIPMD0+@nanopsycho>

On 14/03/2023 10:05, Jiri Pirko wrote:
> Sun, Mar 12, 2023 at 03:28:07AM CET, vadfed@meta.com wrote:
>> Implement basic DPLL operations in ptp_ocp driver as the
>> simplest example of using new subsystem.
>>
>> Signed-off-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
>> ---
>> drivers/ptp/Kconfig   |   1 +
>> drivers/ptp/ptp_ocp.c | 209 ++++++++++++++++++++++++++++++++++++++++--
>> 2 files changed, 200 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
>> index fe4971b65c64..8c4cfabc1bfa 100644
>> --- a/drivers/ptp/Kconfig
>> +++ b/drivers/ptp/Kconfig
>> @@ -177,6 +177,7 @@ config PTP_1588_CLOCK_OCP
>> 	depends on COMMON_CLK
>> 	select NET_DEVLINK
>> 	select CRC16
>> +	select DPLL
>> 	help
>> 	  This driver adds support for an OpenCompute time card.
>>
>> diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
>> index 4bbaccd543ad..02c95e724ec8 100644
>> --- a/drivers/ptp/ptp_ocp.c
>> +++ b/drivers/ptp/ptp_ocp.c
>> @@ -23,6 +23,8 @@
>> #include <linux/mtd/mtd.h>
>> #include <linux/nvmem-consumer.h>
>> #include <linux/crc16.h>
>> +#include <linux/dpll.h>
>> +#include <uapi/linux/dpll.h>
> 
> Don't include UAPI directly. I'm pretty sure I had this comment earlier.
> 

Ah, yeah, you've mentioned it for ice driver last time, but I forgot to 
check it here. Removed.

> 
>>
>> #define PCI_VENDOR_ID_FACEBOOK			0x1d9b
>> #define PCI_DEVICE_ID_FACEBOOK_TIMECARD		0x0400
>> @@ -267,6 +269,7 @@ struct ptp_ocp_sma_connector {
>> 	bool	fixed_dir;
>> 	bool	disabled;
>> 	u8	default_fcn;
>> +	struct dpll_pin *dpll_pin;
>> };
>>
>> struct ocp_attr_group {
>> @@ -353,6 +356,7 @@ struct ptp_ocp {
>> 	struct ptp_ocp_signal	signal[4];
>> 	struct ptp_ocp_sma_connector sma[4];
> 
> It is quite customary to use defines for const numbers like this. Why
> don't you do that in ptp_ocp?

Historical reasons. Jonathan might answer this question.
I will add it to my TODO list for the driver.

>> 	const struct ocp_sma_op *sma_op;
>> +	struct dpll_device *dpll;
>> };
>>
>> #define OCP_REQ_TIMESTAMP	BIT(0)
>> @@ -2689,16 +2693,9 @@ sma4_show(struct device *dev, struct device_attribute *attr, char *buf)
>> }
>>
>> static int
>> -ptp_ocp_sma_store(struct ptp_ocp *bp, const char *buf, int sma_nr)
>> +ptp_ocp_sma_store_val(struct ptp_ocp *bp, int val, enum ptp_ocp_sma_mode mode, int sma_nr)
>> {
>> 	struct ptp_ocp_sma_connector *sma = &bp->sma[sma_nr - 1];
>> -	enum ptp_ocp_sma_mode mode;
>> -	int val;
>> -
>> -	mode = sma->mode;
>> -	val = sma_parse_inputs(bp->sma_op->tbl, buf, &mode);
>> -	if (val < 0)
>> -		return val;
>>
>> 	if (sma->fixed_dir && (mode != sma->mode || val & SMA_DISABLE))
>> 		return -EOPNOTSUPP;
>> @@ -2733,6 +2730,21 @@ ptp_ocp_sma_store(struct ptp_ocp *bp, const char *buf, int sma_nr)
>> 	return val;
>> }
>>
>> +static int
>> +ptp_ocp_sma_store(struct ptp_ocp *bp, const char *buf, int sma_nr)
>> +{
>> +	struct ptp_ocp_sma_connector *sma = &bp->sma[sma_nr - 1];
>> +	enum ptp_ocp_sma_mode mode;
>> +	int val;
>> +
>> +	mode = sma->mode;
>> +	val = sma_parse_inputs(bp->sma_op->tbl, buf, &mode);
>> +	if (val < 0)
>> +		return val;
>> +
>> +	return ptp_ocp_sma_store_val(bp, val, mode, sma_nr);
>> +}
>> +
>> static ssize_t
>> sma1_store(struct device *dev, struct device_attribute *attr,
>> 	   const char *buf, size_t count)
>> @@ -4171,12 +4183,151 @@ ptp_ocp_detach(struct ptp_ocp *bp)
>> 	device_unregister(&bp->dev);
>> }
>>
>> +static int ptp_ocp_dpll_pin_to_sma(const struct ptp_ocp *bp, const struct dpll_pin *pin)
>> +{
>> +	int i;
>> +
>> +	for (i = 0; i < 4; i++) {
>> +		if (bp->sma[i].dpll_pin == pin)
>> +			return i;
> 
> Just pass &bp->sma[i] as a priv to dpll_pin_register().
> and get that pointer directly in pin ops. No need for lookup and use of
> sma_nr at all.

I'm still thinking about the change that you proposed to remove these
_priv() helpers. I have to look into ice code to be sure we won't break
any assumptions in it with moving to additional (void *) parameter.

> 
>> +	}
>> +	return -1;
>> +}
>> +
>> +static int ptp_ocp_dpll_lock_status_get(const struct dpll_device *dpll,
>> +				    enum dpll_lock_status *status,
>> +				    struct netlink_ext_ack *extack)
>> +{
>> +	struct ptp_ocp *bp = (struct ptp_ocp *)dpll_priv(dpll);
> 
> No need to cast (void *), remove it.
> 
Fixed everywhere in the code, thanks.


> 
>> +	int sync;
>> +
>> +	sync = ioread32(&bp->reg->status) & OCP_STATUS_IN_SYNC;
>> +	*status = sync ? DPLL_LOCK_STATUS_LOCKED : DPLL_LOCK_STATUS_UNLOCKED;
>> +
>> +	return 0;
>> +}
>> +
>> +static int ptp_ocp_dpll_source_idx_get(const struct dpll_device *dpll,
>> +				    u32 *idx, struct netlink_ext_ack *extack)
>> +{
>> +	struct ptp_ocp *bp = (struct ptp_ocp *)dpll_priv(dpll);
>> +
>> +	if (bp->pps_select) {
>> +		*idx = ioread32(&bp->pps_select->gpio1);
>> +		return 0;
>> +	}
>> +	return -EINVAL;
>> +}
>> +
>> +static int ptp_ocp_dpll_mode_get(const struct dpll_device *dpll,
>> +				    u32 *mode, struct netlink_ext_ack *extack)
>> +{
>> +	*mode = DPLL_MODE_AUTOMATIC;
>> +
> 
> No need for empty line, I believe.

Ok.

>> +	return 0;
>> +}
>> +
>> +static bool ptp_ocp_dpll_mode_supported(const struct dpll_device *dpll,
>> +				    const enum dpll_mode mode,
>> +				    struct netlink_ext_ack *extack)
>> +{
>> +	if (mode == DPLL_MODE_AUTOMATIC)
>> +		return true;
>> +
>> +	return false;
> 
> Just:
> 	return mode == DPLL_MODE_AUTOMATIC;
> 
Done, thanks!

>> +}
>> +
>> +static int ptp_ocp_dpll_direction_get(const struct dpll_pin *pin,
>> +				     const struct dpll_device *dpll,
>> +				     enum dpll_pin_direction *direction,
>> +				     struct netlink_ext_ack *extack)
>> +{
>> +	struct ptp_ocp *bp = (struct ptp_ocp *)dpll_priv(dpll);
>> +	int sma_nr = ptp_ocp_dpll_pin_to_sma(bp, pin);
>> +
>> +	if (sma_nr < 0)
>> +		return -EINVAL;
>> +
>> +	*direction = bp->sma[sma_nr].mode == SMA_MODE_IN ? DPLL_PIN_DIRECTION_SOURCE :
>> +							   DPLL_PIN_DIRECTION_OUTPUT;
>> +	return 0;
>> +}
>> +
>> +static int ptp_ocp_dpll_direction_set(const struct dpll_pin *pin,
>> +				     const struct dpll_device *dpll,
>> +				     enum dpll_pin_direction direction,
>> +				     struct netlink_ext_ack *extack)
>> +{
>> +	struct ptp_ocp *bp = (struct ptp_ocp *)dpll_priv(dpll);
>> +	int sma_nr = ptp_ocp_dpll_pin_to_sma(bp, pin);
>> +	enum ptp_ocp_sma_mode mode;
>> +
>> +	if (sma_nr < 0)
>> +		return -EINVAL;
>> +
>> +	mode = direction == DPLL_PIN_DIRECTION_SOURCE ? SMA_MODE_IN : SMA_MODE_OUT;
>> +	return ptp_ocp_sma_store_val(bp, 0, mode, sma_nr);
>> +}
>> +
>> +static int ptp_ocp_dpll_frequency_set(const struct dpll_pin *pin,
>> +			      const struct dpll_device *dpll,
>> +			      const u32 frequency,
> 
> Why you need const for u32?

No need, true, removed.

> 
>> +			      struct netlink_ext_ack *extack)
>> +{
>> +	struct ptp_ocp *bp = (struct ptp_ocp *)dpll_priv(dpll);
>> +	int sma_nr = ptp_ocp_dpll_pin_to_sma(bp, pin);
>> +	int val = frequency == 10000000 ? 0 : 1;
> 
> This is weird. I believe you should handle unsupported frequencies
> gracefully.
> 

Currently hardware supports fixed frequencies only. That's why I have to
do this kind of "dance". Hopefully we will improve it to support 
variable frequency.

> 
>> +
>> +	if (sma_nr < 0)
>> +		return -EINVAL;
>> +
>> +
> 
> Avoid double empty lines.
> 

Yep.

> 
>> +	return ptp_ocp_sma_store_val(bp, val, bp->sma[sma_nr].mode, sma_nr);
>> +}
>> +
>> +static int ptp_ocp_dpll_frequency_get(const struct dpll_pin *pin,
>> +			      const struct dpll_device *dpll,
>> +			      u32 *frequency,
>> +			      struct netlink_ext_ack *extack)
>> +{
>> +	struct ptp_ocp *bp = (struct ptp_ocp *)dpll_priv(dpll);
>> +	int sma_nr = ptp_ocp_dpll_pin_to_sma(bp, pin);
>> +	u32 val;
>> +
>> +	if (sma_nr < 0)
>> +		return -EINVAL;
>> +
>> +	val = bp->sma_op->get(bp, sma_nr);
>> +	if (!val)
>> +		*frequency = 1000000;
>> +	else
>> +		*frequency = 0;
> 
> I don't follow. How the frequency could be 0? Does that mean that the
> pin is disabled? If yes, you should rather implement
> .state_on_dpll_get
> .state_on_dpll_set
> 
> and leave the frequency constant.

It's actually a mistake. It should be 1 which means 1Hz, PPS. The value 
returned by sma_op->get is actually the type of the signal where 0 is 
1PPS, 1 is 10Mhz and so on.

> 
> 
>> +	return 0;
>> +}
>> +
>> +static struct dpll_device_ops dpll_ops = {
> 
> const
> 

Will change it together with API part. Otherwise it doesn't compile.

> 
>> +	.lock_status_get = ptp_ocp_dpll_lock_status_get,
>> +	.source_pin_idx_get = ptp_ocp_dpll_source_idx_get,
> 
> Should be called "source_pin_get" and return (struct dpll_pin *)
> On the driver api level, no reason to pass indexes. Work with objects.
> 

Good point, will improve it.

> 
>> +	.mode_get = ptp_ocp_dpll_mode_get,
>> +	.mode_supported = ptp_ocp_dpll_mode_supported,
>> +};
>> +
>> +static struct dpll_pin_ops dpll_pins_ops = {
> 
> const
> 

Yep.

> 
>> +	.frequency_get = ptp_ocp_dpll_frequency_get,
>> +	.frequency_set = ptp_ocp_dpll_frequency_set,
>> +	.direction_get = ptp_ocp_dpll_direction_get,
>> +	.direction_set = ptp_ocp_dpll_direction_set,
>> +};
>> +
>> static int
>> ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>> {
>> +	struct dpll_pin_properties prop;
>> 	struct devlink *devlink;
>> +	char sma[4] = "SMA0";
> 
> Won't fit. Just use:
> char *sma = "SMA0"
> to be safe
> 
Got it.

> 
>> 	struct ptp_ocp *bp;
>> -	int err;
>> +	int err, i;
>> +	u64 clkid;
>>
>> 	devlink = devlink_alloc(&ptp_ocp_devlink_ops, sizeof(*bp), &pdev->dev);
>> 	if (!devlink) {
>> @@ -4226,8 +4377,44 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>>
>> 	ptp_ocp_info(bp);
>> 	devlink_register(devlink);
>> -	return 0;
>>
>> +	clkid = pci_get_dsn(pdev);
>> +	bp->dpll = dpll_device_get(clkid, 0, THIS_MODULE);
>> +	if (!bp->dpll) {
>> +		dev_err(&pdev->dev, "dpll_device_alloc failed\n");
>> +		goto out;
>> +	}
>> +
>> +	err = dpll_device_register(bp->dpll, DPLL_TYPE_PPS, &dpll_ops, bp, &pdev->dev);
>> +	if (err)
>> +		goto out;
>> +
>> +	prop.description = &sma[0];
>> +	prop.freq_supported = DPLL_PIN_FREQ_SUPP_MAX;
>> +	prop.type = DPLL_PIN_TYPE_EXT;
>> +	prop.any_freq_max = 10000000;
>> +	prop.any_freq_min = 0;
>> +	prop.capabilities = DPLL_PIN_CAPS_DIRECTION_CAN_CHANGE;
>> +
>> +	for (i = 0; i < 4; i++) {
>> +		sma[3] = 0x31 + i;
> 
> Ugh. Just use the static const array as I suggested in the dpll patch
> reply. Helps you avoid this sort of "magic".
> 
well, yes. but at the same time Arkadiusz raised a good question about
accessing driver's memory from the subsystem code - doesn't look clean.

> 
>> +		bp->sma[i].dpll_pin = dpll_pin_get(clkid, i, THIS_MODULE, &prop);
>> +		if (IS_ERR_OR_NULL(bp->sma[i].dpll_pin)) {
> 
> How it could be NULL?
> 

Allocation fail?

> 
>> +			bp->sma[i].dpll_pin = NULL;
> 
> This would not be needed if the error path iterates over
> indexes which were successul.
> 

Yeah, I'll make it the same way it's done in ice.


> 
>> +			goto out_dpll;
>> +		}
>> +		err = dpll_pin_register(bp->dpll, bp->sma[i].dpll_pin, &dpll_pins_ops, bp, NULL);
>> +		if (err)
>> +			goto out_dpll;
>> +	}
>> +
>> +	return 0;
>> +out_dpll:
>> +	for (i = 0; i < 4; i++) {
>> +		if (bp->sma[i].dpll_pin)
> 
> You don't do unregister of pin here.
> 
Yeah, actually error path and unload path should be re-implemented.

> 
>> +			dpll_pin_put(bp->sma[i].dpll_pin);
>> +	}
>> +	dpll_device_put(bp->dpll);
>> out:
>> 	ptp_ocp_detach(bp);
>> out_disable:
>> @@ -4243,6 +4430,8 @@ ptp_ocp_remove(struct pci_dev *pdev)
>> 	struct ptp_ocp *bp = pci_get_drvdata(pdev);
>> 	struct devlink *devlink = priv_to_devlink(bp);
>>
>> +	dpll_device_unregister(bp->dpll);
>> +	dpll_device_put(bp->dpll);
>> 	devlink_unregister(devlink);
>> 	ptp_ocp_detach(bp);
>> 	pci_disable_device(pdev);
>> -- 
>> 2.34.1
>>


  reply	other threads:[~2023-03-15  0:10 UTC|newest]

Thread overview: 105+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-12  2:28 [PATCH RFC v6 0/6] Create common DPLL/clock configuration API Vadim Fedorenko
2023-03-12  2:28 ` [PATCH RFC v6 1/6] dpll: spec: Add Netlink spec in YAML Vadim Fedorenko
2023-03-14 14:44   ` Jiri Pirko
2023-03-16 13:15     ` Kubalewski, Arkadiusz
2023-03-16 13:45       ` Jiri Pirko
2023-03-16 15:19         ` Jiri Pirko
2023-03-17  0:53           ` Kubalewski, Arkadiusz
2023-03-17 10:07             ` Jiri Pirko
2023-03-17  0:52         ` Kubalewski, Arkadiusz
2023-03-17 10:05           ` Jiri Pirko
2023-03-17 14:29             ` Jiri Pirko
2023-03-17 15:14             ` Kubalewski, Arkadiusz
2023-03-17 16:20               ` Jiri Pirko
2023-03-17 18:22                 ` Kubalewski, Arkadiusz
2023-03-20  8:10                   ` Jiri Pirko
2023-03-21  4:05       ` Jakub Kicinski
2023-03-21  4:13         ` Jakub Kicinski
2023-03-21  4:20           ` Jakub Kicinski
2023-03-17 16:23   ` Jiri Pirko
2023-03-21  4:00     ` Jakub Kicinski
2023-03-17 16:53   ` Jiri Pirko
2023-03-17 18:50     ` Kubalewski, Arkadiusz
2023-03-12  2:28 ` [PATCH RFC v6 2/6] dpll: Add DPLL framework base functions Vadim Fedorenko
2023-03-13 16:21   ` Jiri Pirko
2023-03-13 22:59     ` Vadim Fedorenko
2023-03-14  9:21       ` Jiri Pirko
2023-03-14 17:50         ` Kubalewski, Arkadiusz
2023-03-15  9:22           ` Jiri Pirko
2023-03-16 12:31             ` Jiri Pirko
2023-03-28 15:22             ` Vadim Fedorenko
2023-04-01 12:49               ` Jiri Pirko
2023-04-03 18:18             ` Jakub Kicinski
2023-04-09  7:51               ` Jiri Pirko
     [not found]                 ` <20230410153149.602c6bad@kernel.org>
2023-04-16 16:23                   ` Jiri Pirko
2023-04-17 15:53                     ` Vadim Fedorenko
     [not found]                     ` <20230417124942.4305abfa@kernel.org>
2023-04-27  8:05                       ` Paolo Abeni
2023-04-27 10:20                         ` Vadim Fedorenko
     [not found]                       ` <ZFDPaXlJainSOqmV@nanopsycho>
     [not found]                         ` <20230502083244.19543d26@kernel.org>
2023-05-03  7:56                           ` Jiri Pirko
2023-05-04  2:16                             ` Jakub Kicinski
2023-05-04 11:00                               ` Jiri Pirko
2023-05-04 11:14                                 ` Jiri Pirko
2023-05-04 16:04                                 ` Jakub Kicinski
2023-05-04 17:51                                   ` Jiri Pirko
2023-05-04 18:44                                     ` Jakub Kicinski
2023-05-05 10:41                                       ` Jiri Pirko
2023-05-05 15:35                                         ` Jakub Kicinski
2023-05-07  7:58                                           ` Jiri Pirko
2023-05-08  6:50                                             ` Paolo Abeni
2023-05-08 12:17                                               ` Jiri Pirko
2023-05-08 19:42                                                 ` Jakub Kicinski
2023-05-09  7:53                                                   ` Jiri Pirko
2023-05-09 14:52                                                     ` Jakub Kicinski
2023-05-09 15:21                                                       ` Jiri Pirko
2023-05-09 17:53                                                         ` Jakub Kicinski
2023-05-10  6:17                                                           ` Jiri Pirko
2023-03-14 16:43       ` Kubalewski, Arkadiusz
2023-03-15 12:14         ` Jiri Pirko
2023-03-14  9:30   ` Jiri Pirko
2023-03-14 15:45   ` Jiri Pirko
2023-03-14 18:35     ` Kubalewski, Arkadiusz
2023-03-15 14:43       ` Jiri Pirko
2023-03-15 15:29   ` Jiri Pirko
2023-03-16 12:20   ` Jiri Pirko
2023-03-16 12:37   ` Jiri Pirko
2023-03-16 13:53   ` Jiri Pirko
2023-03-16 16:16   ` Jiri Pirko
2023-03-17 16:21   ` Jiri Pirko
2023-03-20 10:24   ` Jiri Pirko
2023-03-21 13:34   ` Jiri Pirko
2023-03-23 11:18   ` Jiri Pirko
2023-03-24  9:29   ` Jiri Pirko
2023-03-12  2:28 ` [PATCH RFC v6 3/6] dpll: documentation on DPLL subsystem interface Vadim Fedorenko
2023-03-14 16:14   ` Jiri Pirko
2023-04-03 10:21     ` Kubalewski, Arkadiusz
2023-03-16 13:46   ` Jiri Pirko
2023-04-03 10:23     ` Kubalewski, Arkadiusz
2023-03-12  2:28 ` [PATCH RFC v6 4/6] ice: add admin commands to access cgu configuration Vadim Fedorenko
2023-03-12  2:28 ` [PATCH RFC v6 5/6] ice: implement dpll interface to control cgu Vadim Fedorenko
2023-03-12  2:28 ` [PATCH RFC v6 6/6] ptp_ocp: implement DPLL ops Vadim Fedorenko
2023-03-14 10:05   ` Jiri Pirko
2023-03-15  0:10     ` Vadim Fedorenko [this message]
2023-03-15 12:24       ` Jiri Pirko
2023-03-31 23:28         ` Vadim Fedorenko
2023-04-01 12:53           ` Jiri Pirko
2023-03-15 15:34   ` Jiri Pirko
2023-03-15 15:52     ` Vadim Fedorenko
2023-03-16 12:12   ` Jiri Pirko
2023-03-13 12:20 ` [PATCH RFC v6 0/6] Create common DPLL/clock configuration API Jiri Pirko
2023-03-13 15:33   ` Vadim Fedorenko
2023-03-13 16:22     ` Jiri Pirko
2023-03-13 16:31       ` Vadim Fedorenko
2023-03-17 16:10     ` Jiri Pirko
2023-03-18  5:01       ` Jakub Kicinski
2023-03-23 11:21 ` Jiri Pirko
2023-03-23 18:00   ` Vadim Fedorenko
2023-03-26 17:00 ` [patch dpll-rfc 0/7] dpll: initial patchset extension by mlx5 implementation Jiri Pirko
2023-03-26 17:00   ` [patch dpll-rfc 1/7] dpll: make ops function args const Jiri Pirko
2023-03-26 17:00   ` [patch dpll-rfc 2/7] dpll: allow to call device register multiple times Jiri Pirko
2023-03-26 17:00   ` [patch dpll-rfc 3/7] dpll: introduce a helper to get first dpll ref and use it Jiri Pirko
2023-03-26 17:00   ` [patch dpll-rfc 4/7] dpll: allow to call pin register multiple times Jiri Pirko
2023-03-26 17:00   ` [patch dpll-rfc 5/7] dpll: export dpll_pin_notify() Jiri Pirko
2023-03-26 17:00   ` [patch dpll-rfc 6/7] netdev: expose DPLL pin handle for netdevice Jiri Pirko
2023-03-26 17:00   ` [patch dpll-rfc 7/7] mlx5: Implement SyncE support using DPLL infrastructure Jiri Pirko
2023-03-28 16:36   ` [patch dpll-rfc 0/7] dpll: initial patchset extension by mlx5 implementation Vadim Fedorenko
2023-04-01 12:54     ` Jiri Pirko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d192e0ac-3fa3-c799-ac93-84a17e6f6d50@linux.dev \
    --to=vadim.fedorenko@linux.dev \
    --cc=arkadiusz.kubalewski@intel.com \
    --cc=jiri@resnulli.us \
    --cc=jonathan.lemon@gmail.com \
    --cc=kuba@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=mschmidt@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=poros@redhat.com \
    --cc=vadfed@meta.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).