Netdev List
 help / color / mirror / Atom feed
From: Bastien Curutchet <bastien.curutchet@bootlin.com>
To: Jakub Kicinski <kuba@kernel.org>
Cc: woojung.huh@microchip.com, UNGLinuxDriver@microchip.com,
	andrew@lunn.ch, olteanv@gmail.com, davem@davemloft.net,
	edumazet@google.com, pabeni@redhat.com, richardcochran@gmail.com,
	linux@armlinux.org.uk, horms@kernel.org,
	maxime.chevallier@bootlin.com, pascal.eberhard@se.com,
	miquel.raynal@bootlin.com, thomas.petazzoni@bootlin.com,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH net-next v3 10/10] net: dsa: microchip: add two-steps PTP support for KSZ8463
Date: Fri, 31 Jul 2026 12:18:20 +0200	[thread overview]
Message-ID: <b1ecccc0-dfad-4b9c-a012-1ddd9e2f1401@bootlin.com> (raw)
In-Reply-To: <20260731022346.800416-1-kuba@kernel.org>

Hi

On 7/31/26 4:23 AM, Jakub Kicinski wrote:
> This is an AI-generated review of your patch. The human sending this
> email has considered the AI review valid, or at least plausible.
> ---
> --- Patch [10]: [PATCH net-next v3 10/10] net: dsa: microchip: add two-steps PTP support for KSZ8463 ---
> commit 17314cc888f74f2fde26bc0da770a948737b2b66
> Author: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
> 
> net: dsa: microchip: add two-steps PTP support for KSZ8463
> 
> This adds L2 two-step PTP timestamping for the KSZ8463 by registering the
> generic KSZ PTP clock and adding KSZ8463-specific .get_ts_info and
> .port_hwtstamp_set callbacks.  A new per-port last_tx_is_pdelayresp flag is
> used to decide which of the two timestamp registers behind the shared
> interrupt status bit should be read.
> 
> A few questions below.
> 
>> diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c
>> index ac9e8ef5774a..941ae9f66f70 100644
>> --- a/drivers/net/dsa/microchip/ksz8.c
>> +++ b/drivers/net/dsa/microchip/ksz8.c
>> @@ -242,8 +242,11 @@ static int ksz8463_girq_setup(struct ksz_device *dev)
>>   
>>   static int ksz8463_reset_switch(struct ksz_device *dev)
>>   {
>> -	ksz_cfg(dev, KSZ8463_REG_SW_RESET, KSZ8463_GLOBAL_SOFTWARE_RESET, true);
>> -	ksz_cfg(dev, KSZ8463_REG_SW_RESET, KSZ8463_GLOBAL_SOFTWARE_RESET,
>> +	ksz_cfg(dev, KSZ8463_REG_SW_RESET,
>> +		KSZ8463_GLOBAL_SOFTWARE_RESET | KSZ8463_PTP_SOFTWARE_RESET,
>> +		true);
>> +	ksz_cfg(dev, KSZ8463_REG_SW_RESET,
>> +		KSZ8463_GLOBAL_SOFTWARE_RESET | KSZ8463_PTP_SOFTWARE_RESET,
>>   		false);
>>   	return 0;
>>   }
> 
> [Severity: Low]
> ksz8463_reset_switch() is called unconditionally from ksz8463_setup(),
> before and independently of the "if (dev->irq > 0)" block, and
> independently of CONFIG_NET_DSA_MICROCHIP_KSZ_PTP.
> 
> So the PTP reset domain (BIT(2) of 0x126) is now toggled also on boards
> that never register a PTP clock, and in kernels built without the KSZ PTP
> support.
> 
> The changelog only describes adding two-step PTP support and does not
> mention resetting the PTP block.  Could the rationale be added to the
> commit message, or the extra reset bit be moved into the PTP setup path?
> 

This PTP reset doesn't have any effect on non-PTP features so this is 
transparent for people that don't use PTP.
>> @@ -2474,17 +2477,24 @@ static int ksz8463_setup(struct dsa_switch *ds)
>>   		ret = ksz8463_ptp_irq_setup(ds);
>>   		if (ret)
>>   			goto free_girq;
>> +
>> +		ret = ksz_ptp_clock_register(ds);
>> +		if (ret) {
>> +			dev_err(dev->dev, "Failed to register PTP clock: %d\n",
>> +				ret);
>> +			goto free_ptp_irq;
>> +		}
>>   	}
> 
> [Severity: Medium]
> Does registering the generic clock here also advertise periodic output and
> programmable pins that the KSZ8463 path does not implement?
> 
> ksz_ptp_clock_register() fills the capabilities unconditionally for every
> chip:
> 
> 	ptp_data->caps.enable		= ksz_ptp_enable;
> 	ptp_data->caps.verify		= ksz_ptp_verify_pin;
> 	ptp_data->caps.n_pins		= KSZ_PTP_N_GPIO;
> 	ptp_data->caps.n_per_out	= 3;
> 	...
> 	ptp_data->caps.pin_config = ptp_data->pin_config;
> 
> The trigger-output code behind those callbacks uses absolute KSZ9477 and
> LAN937x register literals rather than dev->info->regs[], for example in
> ksz_ptp_tou_reset() and ksz_ptp_configure_perout():
> 
> 	ksz_rmw32(dev, REG_PTP_UNIT_INDEX__4,
> 		  PTP_GPIO_INDEX | PTP_TOU_INDEX, data32);   /* 0x0520 */
> 	...
> 	ksz_write32(dev, REG_TRIG_TARGET_NANOSEC, ...);     /* 0x0530+ */
> 
> On KSZ8463 the PTP block lives at 0x600 and above (ksz8463_regs[]:
> PTP_CLK_CTRL 0x0600, PTP_MSG_CONF1 0x0620), and ksz8463_get_port_addr()
> only relocates offsets >= 0x600, so 0x0520-0x0548 are not KSZ8463 PTP
> registers.  The KSZ8463 32-bit regmap declares max_register = BIT(13) - 1
> and the KSZ8463 entry in ksz_switch_chips[] has neither wr_table nor
> rd_table, so these accesses are not filtered and reach the SPI bus.
> 
> ksz_ptp_verify_pin() accepts PTP_PF_PEROUT, and ksz_ptp_tou_gpio() returns
> 0 for anything that is not LAN937x, so a PTP_PIN_SETFUNC followed by
> PTP_PEROUT_REQUEST on the new clock can report success while writing into
> unrelated registers.  Should the pin/perout capabilities be left out for
> this chip?
> 

Proper PEROUT support is going to be added in un upcoming series and 
will address this.

>> @@ -3129,9 +3143,9 @@ const struct dsa_switch_ops ksz8463_switch_ops = {
>>   	.port_max_mtu		= ksz88xx_max_mtu,
>>   	.suspend		= ksz_suspend,
>>   	.resume			= ksz_resume,
>> -	.get_ts_info		= ksz_get_ts_info,
>> +	.get_ts_info		= ksz8463_get_ts_info,
>>   	.port_hwtstamp_get	= ksz_hwtstamp_get,
>> -	.port_hwtstamp_set	= ksz_hwtstamp_set,
>> +	.port_hwtstamp_set	= ksz8463_hwtstamp_set,
>>   	.port_txtstamp		= ksz_port_txtstamp,
>>   	.port_rxtstamp		= ksz_port_rxtstamp,
>>   	.port_setup_tc		= ksz8_setup_tc,
> 
> [ ... ]
> 
>> diff --git a/drivers/net/dsa/microchip/ksz_ptp.c b/drivers/net/dsa/microchip/ksz_ptp.c
>> index be6b8240ac03..9d8b78687f53 100644
>> --- a/drivers/net/dsa/microchip/ksz_ptp.c
>> +++ b/drivers/net/dsa/microchip/ksz_ptp.c
>> @@ -297,6 +297,31 @@ static int ksz_ptp_enable_mode(struct ksz_device *dev)
>>   			 tag_en ? PTP_ENABLE : 0);
>>   }
>>   
>> +int ksz8463_get_ts_info(struct dsa_switch *ds, int port,
>> +			struct kernel_ethtool_ts_info *ts)
>> +{
>> +	struct ksz_device *dev = ds->priv;
>> +	struct ksz_ptp_data *ptp_data;
>> +
>> +	ptp_data = &dev->ptp_data;
>> +
>> +	if (!ptp_data->clock)
>> +		return -ENODEV;
>> +
>> +	ts->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
>> +			      SOF_TIMESTAMPING_RX_HARDWARE |
>> +			      SOF_TIMESTAMPING_RAW_HARDWARE;
>> +
>> +	ts->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);
>> +
>> +	ts->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
>> +			 BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT);
>> +
>> +	ts->phc_index = ptp_clock_index(ptp_data->clock);
>> +
>> +	return 0;
>> +}
>> +
> 
> [Severity: Low]
> This isn't a bug, but this is a near-verbatim copy of ksz_get_ts_info(),
> with only tx_types and rx_filters differing, and ksz8463_hwtstamp_set()
> below is a byte-for-byte copy of ksz_hwtstamp_set() apart from the inner
> helper call.
> 
> ksz_get_ts_info() already differentiates chips inline:
> 
> 	if (is_lan937x(dev))
> 		ts->tx_types |= BIT(HWTSTAMP_TX_ON);
> 
> and ksz_set_hwtstamp_config() does the same with:
> 
> 	if (!is_lan937x(dev))
> 		return -ERANGE;
> 
> Could the KSZ8463 differences be expressed the same way, or through
> ksz_chip_data fields, instead of a second pair of callbacks plus a second
> set of "#define ... NULL" stubs in ksz_ptp.h?  As it stands the missing
> clock check discussed below has to be fixed in two places.
> 

It feels more readable to me to have a ksz8463-specific function that 
exactly tells what's supported or not.

>> @@ -341,6 +366,72 @@ int ksz_hwtstamp_get(struct dsa_switch *ds, int port,
>>   	return 0;
>>   }
>>   
>> +static int ksz8463_set_hwtstamp_config(struct ksz_device *dev,
>> +				       struct ksz_port *prt,
>> +				       struct kernel_hwtstamp_config *config)
>> +{
>> +	const u16 *regs = dev->info->regs;
>> +	int ret;
>> +
>> +	if (config->flags)
>> +		return -EINVAL;
>> +
>> +	switch (config->tx_type) {
>> +	case HWTSTAMP_TX_OFF:
>> +		prt->ptpmsg_irq[KSZ8463_SYNC_MSG].ts_en  = false;
>> +		prt->ptpmsg_irq[KSZ8463_XDREQ_PDRES_MSG].ts_en = false;
>> +		prt->hwts_tx_en = false;
>> +		break;
>> +	case HWTSTAMP_TX_ON:
>> +		prt->ptpmsg_irq[KSZ8463_SYNC_MSG].ts_en  = true;
>> +		prt->ptpmsg_irq[KSZ8463_XDREQ_PDRES_MSG].ts_en = true;
>> +		prt->hwts_tx_en = true;
>> +
>> +		ret = ksz_rmw16(dev, regs[PTP_MSG_CONF1], PTP_1STEP, 0);
>> +		if (ret)
>> +			return ret;
>> +
>> +		break;
>> +	default:
>> +		return -ERANGE;
>> +	}
>> +
>> +	switch (config->rx_filter) {
>> +	case HWTSTAMP_FILTER_NONE:
>> +		prt->hwts_rx_en = false;
>> +		break;
>> +	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
>> +	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
>> +		config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
>> +		prt->hwts_rx_en = true;
>> +		break;
>> +	default:
>> +		config->rx_filter = HWTSTAMP_FILTER_NONE;
>> +		return -ERANGE;
>> +	}
>> +
>> +	return ksz_ptp_enable_mode(dev);
>> +}
> 
> [Severity: Medium]
> Only L2 filters are accepted here and the changelog says "IPv4 and IPv6
> layers aren't supported", but should PTP_IPV4_UDP_ENABLE (BIT(4)) and
> PTP_IPV6_UDP_ENABLE (BIT(3)) of PTP_MSG_CONF1 be cleared somewhere?
> 
> The only writes to that register are the set-only rmw in
> ksz_ptp_clock_register():
> 
> 	ret = ksz_rmw16(dev, regs[PTP_MSG_CONF1],
> 			PTP_TC_P2P | PTP_802_1AS | PTP_ETH_ENABLE,
> 			PTP_TC_P2P | PTP_802_1AS | PTP_ETH_ENABLE);
> 
> and the PTP_1STEP clear above, so the transport-detect bits keep their
> reset value.  With the new PTP soft reset in ksz8463_reset_switch() the
> register is back at its hardware default, and the existing comment in
> ksz8463_config_cpu_port() suggests the default is not zero on this chip:
> 
> 	/* Turn off PTP function as the switch enables it by default */
> 	regmap_update_bits(ksz_regmap_16(dev), KSZ8463_PTP_MSG_CONF1,
> 			   PTP_ENABLE, 0);
> 
> If BIT(3)/BIT(4) are set after reset, UDP-encapsulated PTP frames are
> detected too, and since PTP_802_1AS forwards detected PTP frames to the
> host port only, L4 PTP traffic crossing the switch would be trapped and
> could raise timestamp interrupts the driver does not expect.
> 
>> +
>> +int ksz8463_hwtstamp_set(struct dsa_switch *ds, int port,
>> +			 struct kernel_hwtstamp_config *config,
>> +			 struct netlink_ext_ack *extack)
>> +{
>> +	struct ksz_device *dev = ds->priv;
>> +	struct ksz_port *prt;
>> +	int ret;
>> +
>> +	prt = &dev->ports[port];
>> +
>> +	ret = ksz8463_set_hwtstamp_config(dev, prt, config);
>> +	if (ret)
>> +		return ret;
>> +
>> +	prt->tstamp_config = *config;
>> +
>> +	return 0;
>> +}
>> +
> 
> [Severity: High]
> This isn't a bug introduced by this patch, but can this path be reached on
> a KSZ8463 without a PTP clock and oops?
> 
> ksz8463_get_ts_info() added above returns -ENODEV when ptp_data->clock is
> NULL, while ksz8463_hwtstamp_set() has no such check and always ends in
> ksz_ptp_enable_mode(), which does:
> 
> 	if (tag_en)
> 		ptp_schedule_worker(ptp_data->clock, 0);
> 	else
> 		ptp_cancel_worker_sync(ptp_data->clock);
> 
> ksz8463_setup() only calls ksz_ptp_clock_register() (the sole place where
> ptp_data->lock, ptp_data->clock_lock and ptp_data->clock are initialized)
> inside "if (dev->irq > 0)", but ksz8463_switch_ops installs
> .port_hwtstamp_set unconditionally, and dsa_user_hwtstamp_set() only
> checks that the op pointer exists.
> 
> dev->irq comes from spi->irq in ksz_spi_probe() and is 0 when the DT node
> describes no interrupt, which the driver supports.  In that case even a
> trivial HWTSTAMP_TX_OFF plus HWTSTAMP_FILTER_NONE request ends in
> ptp_cancel_worker_sync(NULL), which passes &ptp->aux_work to
> kthread_cancel_delayed_work_sync().
> 
> The same hole existed before with the generic ksz_hwtstamp_set(), but the
> new KSZ8463-specific copy keeps it while making the clock and lock
> initialization conditional.  Would a "!ptp_data->clock" check, as done in
> the new ksz8463_get_ts_info(), be appropriate here?
> 

If ksz_ptp_clock_register() isn't called, the ptp_clock_register() isn't 
called so the PTP clock isn't exposed to userspace and if I'm not 
mistaken ksz8463_hwtstamp_set() can't be called if the PTP clock isn't 
exposed to userspace.

>> @@ -571,6 +662,31 @@ static void ksz_ptp_txtstamp_skb(struct ksz_device *dev,
>>   	skb_complete_tx_timestamp(skb, &hwtstamps);
>>   }
>>   
>> +static void ksz8463_set_pdelayresp_flag(struct ksz_port *prt,
>> +					struct sk_buff *skb)
>> +{
>> +	struct ptp_header *hdr;
>> +	unsigned int type;
>> +	u8 ptp_msg_type;
>> +
>> +	if (!ksz_is_ksz8463(prt->ksz_dev))
>> +		return;
>> +
>> +	if (skb_linearize(skb))
>> +		return;
>> +
>> +	type = ptp_classify_raw(skb);
>> +	if (type == PTP_CLASS_NONE)
>> +		return;
>> +
>> +	hdr = ptp_parse_header(skb, type);
>> +	if (!hdr)
>> +		return;
>> +
>> +	ptp_msg_type = ptp_get_msgtype(hdr, type);
>> +	prt->last_tx_is_pdelayresp = (ptp_msg_type == PTP_MSGTYPE_PDELAY_RESP);
>> +}
>> +
>>   void ksz_port_deferred_xmit(struct kthread_work *work)
>>   {
>>   	struct ksz_deferred_xmit_work *xmit_work = work_to_xmit_work(work);
>> @@ -587,6 +703,8 @@ void ksz_port_deferred_xmit(struct kthread_work *work)
>>   
>>   	reinit_completion(&prt->tstamp_msg_comp);
>>   
>> +	ksz8463_set_pdelayresp_flag(prt, skb);
>> +
>>   	dsa_enqueue_skb(skb, skb->dev);
>>   
>>   	ksz_ptp_txtstamp_skb(dev, prt, clone);
> 
> [Severity: Medium]
> Can a late timestamp interrupt observe the flag of the following packet?
> 
> prt->last_tx_is_pdelayresp is written here from the deferred-xmit kthread
> and read from the threaded PTP interrupt in ksz_ptp_msg_thread_fn() ->
> ksz_read_ts(), with no lock, no READ_ONCE()/WRITE_ONCE() and no barrier.
> 
> Correctness seems to depend on the interrupt for packet N always being
> consumed before packet N+1 is queued, but ksz_ptp_txtstamp_skb() gives up
> after a timeout:
> 
> 	ret = wait_for_completion_timeout(&prt->tstamp_msg_comp,
> 					  msecs_to_jiffies(100));
> 	if (!ret)
> 		return;
> 
> So for a Pdelay_Resp whose interrupt is late, the worker can proceed to
> the next frame (say a Pdelay_Req) and set the flag to false; the delayed
> interrupt for the Pdelay_Resp then reads KSZ8463_REG_PORT_DREQ_TS instead
> of DREQ_TS + KSZ8463_DRESP_TS_OFFSET and completes tstamp_msg_comp, so
> that value is handed to skb_complete_tx_timestamp() for the next packet.
> 
> reinit_completion() is a plain "x->done = 0" while complete() takes
> x->wait.lock, so it cannot discard the stale completion either.  Is there
> something that ties an interrupt to the packet it belongs to?
> 

Packets are serialized through ksz_port_deferred_xmit() so interrupt for 
packet N+1 firing before interrupt for packet N isn't likely to happen.
>> @@ -979,7 +1097,22 @@ void ksz_ptp_clock_unregister(struct dsa_switch *ds)
>>   
>>   static int ksz_read_ts(struct ksz_port *port, u16 reg, u32 *ts)
>>   {
>> -	return ksz_read32(port->ksz_dev, reg, ts);
>> +	u16 ts_reg = reg;
>> +
>> +	/**
>        ^^^^
> 
> [Severity: Low]
> This isn't a bug, but "/**" is the kernel-doc marker and this is an
> ordinary comment inside a function body, so plain "/*" would be better.
> 
>> +	 * On KSZ8463 DREQ and DRESP timestamps share one interrupt line
>                                                            ^^^^^^^^^^^^^^
> 
> [Severity: Low]
> The commit message says the two timestamps "share one interrupt bit
> status", which matches the hardware: KSZ8463_REG_PORT_DREQ_TS and
> KSZ8463_REG_PORT_DRESP_TS share a single status bit in
> KSZ8463_PTP_TS_ISR rather than sitting on separate interrupt lines.  The
> sentence is also missing a terminating period.
> 
>> +	 * so we have to check the nature of the latest event sent to know
>> +	 * where the timestamp is located
>> +	 */
>> +	if (ksz_is_ksz8463(port->ksz_dev)) {
>> +		const struct ksz_dev_ops *ops = port->ksz_dev->dev_ops;
>> +
>> +		if (port->last_tx_is_pdelayresp &&
>> +		    ts_reg == ops->get_port_addr(port->num, KSZ8463_REG_PORT_DREQ_TS))
>> +			ts_reg += KSZ8463_DRESP_TS_OFFSET;
>> +	}
>> +
>> +	return ksz_read32(port->ksz_dev, ts_reg, ts);
>>   }
> 
> [ ... ]

I'll fix these two if I need to respin.


Best regards,
Bastien

      reply	other threads:[~2026-07-31 10:18 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-27 10:20 [PATCH net-next v3 00/10] net: dsa: microchip: add PTP support for KSZ8463 Bastien Curutchet (Schneider Electric)
2026-07-27 10:20 ` [PATCH net-next v3 01/10] net: dsa: microchip: implement ksz8463_setup() Bastien Curutchet (Schneider Electric)
2026-07-31  2:23   ` Jakub Kicinski
2026-07-31  6:57     ` Bastien Curutchet
2026-07-27 10:20 ` [PATCH net-next v3 02/10] net: dsa: microchip: split ksz8_config_cpu_port() Bastien Curutchet (Schneider Electric)
2026-07-27 10:20 ` [PATCH net-next v3 03/10] net: dsa: microchip: allow the use of other IRQ operations Bastien Curutchet (Schneider Electric)
2026-07-27 10:20 ` [PATCH net-next v3 04/10] net: dsa: microchip: add PTP interrupt handling for KSZ8463 Bastien Curutchet (Schneider Electric)
2026-07-31  2:23   ` Jakub Kicinski
2026-07-31  8:41     ` Bastien Curutchet
2026-07-27 10:20 ` [PATCH net-next v3 05/10] net: dsa: microchip: adapt port offset for KSZ8463's PTP register Bastien Curutchet (Schneider Electric)
2026-07-27 10:20 ` [PATCH net-next v3 06/10] net: dsa: tag_ksz: move the KSZ8795 tag handling below ksz_xmit_timestamp() Bastien Curutchet (Schneider Electric)
2026-07-27 10:20 ` [PATCH net-next v3 07/10] net: dsa: tag_ksz: share code for KSZ8795 and KSZ9893 xmit operations Bastien Curutchet (Schneider Electric)
2026-07-31  2:23   ` Jakub Kicinski
2026-07-31  9:14     ` Bastien Curutchet
2026-07-27 10:20 ` [PATCH net-next v3 08/10] net: dsa: microchip: add KSZ8463 tail tag handling Bastien Curutchet (Schneider Electric)
2026-07-31  2:23   ` Jakub Kicinski
2026-07-31  6:15     ` Bastien Curutchet
2026-07-31  2:23   ` Jakub Kicinski
2026-07-31  9:59     ` Bastien Curutchet
2026-07-27 10:20 ` [PATCH net-next v3 09/10] net: dsa: microchip: explicitly enable detection of L2 PTP frames Bastien Curutchet (Schneider Electric)
2026-07-27 10:20 ` [PATCH net-next v3 10/10] net: dsa: microchip: add two-steps PTP support for KSZ8463 Bastien Curutchet (Schneider Electric)
2026-07-31  2:23   ` Jakub Kicinski
2026-07-31 10:18     ` Bastien Curutchet [this message]

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=b1ecccc0-dfad-4b9c-a012-1ddd9e2f1401@bootlin.com \
    --to=bastien.curutchet@bootlin.com \
    --cc=UNGLinuxDriver@microchip.com \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=maxime.chevallier@bootlin.com \
    --cc=miquel.raynal@bootlin.com \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    --cc=pabeni@redhat.com \
    --cc=pascal.eberhard@se.com \
    --cc=richardcochran@gmail.com \
    --cc=thomas.petazzoni@bootlin.com \
    --cc=woojung.huh@microchip.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