Netdev List
 help / color / mirror / Atom feed
* Re: [net-next 7/9] net: ethernet: ravb: Add callback for gPTP clock index
From: Sergey Shtylyov @ 2026-06-13  8:05 UTC (permalink / raw)
  To: Niklas Söderlund, Paul Barker, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
	Geert Uytterhoeven, Magnus Damm, netdev, linux-renesas-soc,
	devicetree, linux-kernel
In-Reply-To: <20260610102432.3538432-8-niklas.soderlund+renesas@ragnatech.se>

On 6/10/26 1:24 PM, Niklas Söderlund wrote:

> Prepare for adding Gen4 support which have an optional external gPTP



> clock. Add a callback to get the clock index and use it to determine if
> the device shall report gPTP support.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>

Reviewed-by: Sergey Shtylyov <sergei.shtylyov@gmail.com>

[...]

MBR, Sergey


^ permalink raw reply

* Re: [PATCH] net: correcting section tags for .init and .exit data/functions
From: kernel test robot @ 2026-06-13  8:05 UTC (permalink / raw)
  To: xur, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Neal Cardwell, Kuniyuki Iwashima, Willem de Bruijn,
	David Ahern, Ido Schimmel, Andreas Färber,
	Manivannan Sadhasivam, Nathan Chancellor, Nick Desaulniers,
	Bill Wendling, Justin Stitt, Maciej Żenczykowski,
	Yue Haibing, Jeff Layton, Kees Cook, Fernando Fernandez Mancera,
	Gustavo A. R. Silva, Sabrina Dubroca, Masahiro Yamada,
	Nicolas Schier, linux-kernel, linux-arm-kernel, linux-actions
  Cc: llvm, oe-kbuild-all, netdev
In-Reply-To: <20260612162257.896792-1-xur@google.com>

Hi,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 2b414a95b8f7307d42173ba9e580d6d3e2bcbfce]

url:    https://github.com/intel-lab-lkp/linux/commits/xur-google-com/net-correcting-section-tags-for-init-and-exit-data-functions/20260613-002737
base:   2b414a95b8f7307d42173ba9e580d6d3e2bcbfce
patch link:    https://lore.kernel.org/r/20260612162257.896792-1-xur%40google.com
patch subject: [PATCH] net: correcting section tags for .init and .exit data/functions
config: x86_64-rhel-9.4-rust (https://download.01.org/0day-ci/archive/20260613/202606131033.U9FHCI7B-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project f43d6834093b19baf79beda8c0337ab020ac5f17)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260613/202606131033.U9FHCI7B-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202606131033.U9FHCI7B-lkp@intel.com/

All warnings (new ones prefixed by >>, old ones prefixed by <<):

>> WARNING: modpost: vmlinux: section mismatch in reference: tcpv6_init+0x68 (section: .text) -> mptcpv6_init (section: .init.text)

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [PATCH v1 net-next 1/1] tcp: Replace min_tso_segs() with tso_segs() CC callback for TCP Prague
From: chia-yu.chang @ 2026-06-13  8:08 UTC (permalink / raw)
  To: andrii, eddyz87, horms, dsahern, bpf, netdev, pabeni, jhs, kuba,
	stephen, davem, edumazet, andrew+netdev, donald.hunter, kuniyu,
	ij, ncardwell, koen.de_schepper, g.white, ingemar.s.johansson,
	mirja.kuehlewind, cheshire, rs.ietf, Jason_Livingood, vidhi_goel
  Cc: Chia-Yu Chang

From: Chia-Yu Chang <chia-yu.chang@nokia-bell-labs.com>

This patch replaces existing min_tso_segs() with tso_segs() CC callbak
for CC algorithm to provides explicit tso segment number of each data
burst and overrides tcp_tso_autosize().

No functional change.

Signed-off-by: Ilpo Järvinen <ij@kernel.org>
Signed-off-by: Chia-Yu Chang <chia-yu.chang@nokia-bell-labs.com>
---
 include/net/tcp.h                                |  7 +++++--
 net/ipv4/bpf_tcp_ca.c                            |  4 ++--
 net/ipv4/tcp_bbr.c                               | 14 +++++++++++---
 net/ipv4/tcp_output.c                            | 12 ++++++------
 tools/testing/selftests/bpf/progs/tcp_ca_kfunc.c |  8 ++++----
 5 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/include/net/tcp.h b/include/net/tcp.h
index f063eccbbba3..34d370ea9ceb 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -824,6 +824,9 @@ unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu);
 unsigned int tcp_current_mss(struct sock *sk);
 u32 tcp_clamp_probe0_to_user_timeout(const struct sock *sk, u32 when);
 
+u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now,
+		     int min_tso_segs);
+
 /* Bound MSS / TSO packet size with the half of the window */
 static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize)
 {
@@ -1361,8 +1364,8 @@ struct tcp_congestion_ops {
 	/* hook for packet ack accounting (optional) */
 	void (*pkts_acked)(struct sock *sk, const struct ack_sample *sample);
 
-	/* override sysctl_tcp_min_tso_segs (optional) */
-	u32 (*min_tso_segs)(struct sock *sk);
+	/* override tcp_tso_autosize (optional)*/
+	u32 (*tso_segs)(struct sock *sk, u32 mss_now);
 
 	/* new value of cwnd after loss (required) */
 	u32  (*undo_cwnd)(struct sock *sk);
diff --git a/net/ipv4/bpf_tcp_ca.c b/net/ipv4/bpf_tcp_ca.c
index 791e15063237..ed4fea98dfde 100644
--- a/net/ipv4/bpf_tcp_ca.c
+++ b/net/ipv4/bpf_tcp_ca.c
@@ -284,7 +284,7 @@ static void bpf_tcp_ca_pkts_acked(struct sock *sk, const struct ack_sample *samp
 {
 }
 
-static u32 bpf_tcp_ca_min_tso_segs(struct sock *sk)
+static u32 bpf_tcp_ca_tso_segs(struct sock *sk, u32 mss_now)
 {
 	return 0;
 }
@@ -320,7 +320,7 @@ static struct tcp_congestion_ops __bpf_ops_tcp_congestion_ops = {
 	.cwnd_event_tx_start = bpf_tcp_ca_cwnd_event_tx_start,
 	.in_ack_event = bpf_tcp_ca_in_ack_event,
 	.pkts_acked = bpf_tcp_ca_pkts_acked,
-	.min_tso_segs = bpf_tcp_ca_min_tso_segs,
+	.tso_segs = bpf_tcp_ca_tso_segs,
 	.cong_control = bpf_tcp_ca_cong_control,
 	.undo_cwnd = bpf_tcp_ca_undo_cwnd,
 	.sndbuf_expand = bpf_tcp_ca_sndbuf_expand,
diff --git a/net/ipv4/tcp_bbr.c b/net/ipv4/tcp_bbr.c
index 82378a2bfd1e..15536564246c 100644
--- a/net/ipv4/tcp_bbr.c
+++ b/net/ipv4/tcp_bbr.c
@@ -297,11 +297,19 @@ static void bbr_set_pacing_rate(struct sock *sk, u32 bw, int gain)
 }
 
 /* override sysctl_tcp_min_tso_segs */
-__bpf_kfunc static u32 bbr_min_tso_segs(struct sock *sk)
+static u32 bbr_min_tso_segs(struct sock *sk)
 {
 	return READ_ONCE(sk->sk_pacing_rate) < (bbr_min_tso_rate >> 3) ? 1 : 2;
 }
 
+__bpf_kfunc static u32 bbr_tso_segs(struct sock *sk, u32 mss_now)
+{
+	u32 min_tso;
+
+	min_tso = bbr_min_tso_segs(sk);
+	return tcp_tso_autosize(sk, mss_now, min_tso);
+}
+
 static u32 bbr_tso_segs_goal(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -1151,7 +1159,7 @@ static struct tcp_congestion_ops tcp_bbr_cong_ops __read_mostly = {
 	.undo_cwnd	= bbr_undo_cwnd,
 	.cwnd_event_tx_start	= bbr_cwnd_event_tx_start,
 	.ssthresh	= bbr_ssthresh,
-	.min_tso_segs	= bbr_min_tso_segs,
+	.tso_segs	= bbr_tso_segs,
 	.get_info	= bbr_get_info,
 	.set_state	= bbr_set_state,
 };
@@ -1163,7 +1171,7 @@ BTF_ID_FLAGS(func, bbr_sndbuf_expand)
 BTF_ID_FLAGS(func, bbr_undo_cwnd)
 BTF_ID_FLAGS(func, bbr_cwnd_event_tx_start)
 BTF_ID_FLAGS(func, bbr_ssthresh)
-BTF_ID_FLAGS(func, bbr_min_tso_segs)
+BTF_ID_FLAGS(func, bbr_tso_segs)
 BTF_ID_FLAGS(func, bbr_set_state)
 BTF_KFUNCS_END(tcp_bbr_check_kfunc_ids)
 
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 26dd751ec72a..14fde0aa14be 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2253,8 +2253,8 @@ static bool tcp_nagle_check(bool partial, const struct tcp_sock *tp,
  * for every 2^9 usec (aka 512 us) of RTT, so that the RTT-based allowance
  * is below 1500 bytes after 6 * ~500 usec = 3ms.
  */
-static u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now,
-			    int min_tso_segs)
+u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now,
+		     int min_tso_segs)
 {
 	unsigned long bytes;
 	u32 r;
@@ -2278,11 +2278,11 @@ static u32 tcp_tso_segs(struct sock *sk, unsigned int mss_now)
 	const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops;
 	u32 min_tso, tso_segs;
 
-	min_tso = ca_ops->min_tso_segs ?
-			ca_ops->min_tso_segs(sk) :
-			READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_min_tso_segs);
+	min_tso = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_min_tso_segs);
 
-	tso_segs = tcp_tso_autosize(sk, mss_now, min_tso);
+	tso_segs = ca_ops->tso_segs ?
+			ca_ops->tso_segs(sk, mss_now) :
+			tcp_tso_autosize(sk, mss_now, min_tso);
 	return min_t(u32, tso_segs, sk->sk_gso_max_segs);
 }
 
diff --git a/tools/testing/selftests/bpf/progs/tcp_ca_kfunc.c b/tools/testing/selftests/bpf/progs/tcp_ca_kfunc.c
index 0a3e9d35bf6f..58262e490336 100644
--- a/tools/testing/selftests/bpf/progs/tcp_ca_kfunc.c
+++ b/tools/testing/selftests/bpf/progs/tcp_ca_kfunc.c
@@ -10,7 +10,7 @@ extern u32 bbr_sndbuf_expand(struct sock *sk) __ksym;
 extern u32 bbr_undo_cwnd(struct sock *sk) __ksym;
 extern void bbr_cwnd_event_tx_start(struct sock *sk) __ksym;
 extern u32 bbr_ssthresh(struct sock *sk) __ksym;
-extern u32 bbr_min_tso_segs(struct sock *sk) __ksym;
+extern u32 bbr_tso_segs(struct sock *sk, u32 mss_now) __ksym;
 extern void bbr_set_state(struct sock *sk, u8 new_state) __ksym;
 
 extern void dctcp_init(struct sock *sk) __ksym;
@@ -90,9 +90,9 @@ u32 BPF_PROG(ssthresh, struct sock *sk)
 }
 
 SEC("struct_ops")
-u32 BPF_PROG(min_tso_segs, struct sock *sk)
+u32 BPF_PROG(tso_segs, struct sock *sk, u32 mss_now)
 {
-	return bbr_min_tso_segs(sk);
+	return bbr_tso_segs(sk, mss_now);
 }
 
 SEC("struct_ops")
@@ -120,7 +120,7 @@ struct tcp_congestion_ops tcp_ca_kfunc = {
 	.cwnd_event	= (void *)cwnd_event,
 	.cwnd_event_tx_start = (void *)cwnd_event_tx_start,
 	.ssthresh	= (void *)ssthresh,
-	.min_tso_segs	= (void *)min_tso_segs,
+	.tso_segs	= (void *)tso_segs,
 	.set_state	= (void *)set_state,
 	.pkts_acked     = (void *)pkts_acked,
 	.name		= "tcp_ca_kfunc",
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH net-next v2 1/3] dt-bindings: ptp: renesas,rcar-gen4-gptp: Add R-Car Gen4
From: Krzysztof Kozlowski @ 2026-06-13  8:11 UTC (permalink / raw)
  To: Niklas Söderlund
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven, Magnus Damm, Richard Cochran, Andrew Lunn,
	DavidS. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	linux-renesas-soc, devicetree, linux-kernel, netdev
In-Reply-To: <20260612092851.2141782-2-niklas.soderlund+renesas@ragnatech.se>

On Fri, Jun 12, 2026 at 11:28:49AM +0200, Niklas Söderlund wrote:
> Add bindings for the R-Car Gen4 gPTP timer. The timer enables accurate
> synchronization of the clock in the control system. The timer is
> system-wide and used by different Ethernet devices on each Gen4 platform.
> 
>   - On R-Car S4 it is shared between RSWITCH and RAVB.
> 
>   - On R-Car V4H it is shared between RTSN and RAVB.
> 
>   - On R-Car V4M it is only used by RAVB.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> ---

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>

Best regards,
Krzysztof


^ permalink raw reply

* Re: [net-next 9/9] net: ethernet: ravb: Add gPTP support for Gen4
From: Sergey Shtylyov @ 2026-06-13  8:16 UTC (permalink / raw)
  To: Niklas Söderlund, Paul Barker, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
	Geert Uytterhoeven, Magnus Damm, netdev, linux-renesas-soc,
	devicetree, linux-kernel
In-Reply-To: <20260610102432.3538432-10-niklas.soderlund+renesas@ragnatech.se>

On 6/10/26 1:24 PM, Niklas Söderlund wrote:

> While driver advertise gPTP support on Gen4 platforms it is in fact

   Advertises.

> completely broken. On R-Car Gen4 devices the RAVB module have no
> internal gPTP clock as generations before it. Instead it utilizes a
> system wide gPTP clock.
> 
> This change utilizes the refactoring of the RAVB gPTP code to add
> support for a system wide clock and stops the Gen4 devices trying to use

   System-wide?

> the non-existing internal gPTP clock.
> 
> To remain backward compatible the device tree property needed
> (renesas,gptp) to get hold of the system gPTP clock is optional. If the

   Can't parse this statement...

> property is not present, or not enabled, the RAVB driver will no longer
> advertise gPTP support to user-space.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>

Reviewed-by: Sergey Shtylyov <sergei.shtylyov@gmail.com>

[...]

> diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
> index caad95a9c3c5..acdfb56bb135 100644
> --- a/drivers/net/ethernet/renesas/ravb.h
> +++ b/drivers/net/ethernet/renesas/ravb.h
> @@ -249,6 +249,8 @@ enum APSR_BIT {
>  	APSR_RDM	= 0x00002000,
>  	APSR_TDM	= 0x00004000,
>  	APSR_MIISELECT	= 0x01000000,	/* R-Car V4M only */
> +	APSR_GPTPTIMER_SOURCE = BIT(25), /* Gen4 */
> +	APSR_GPTPCLOCK	= BIT(29),	/* Gen4 */

   Hum, the other *enum* entries don't use BIT()...

[...]

MBR, Sergey


^ permalink raw reply

* Re: [PATCH v3 5/6] pds_core: add host backed memory support for firmware
From: Paolo Abeni @ 2026-06-13  8:17 UTC (permalink / raw)
  To: Nikhil P. Rao, netdev
  Cc: Brett Creeley, Andrew Lunn, David S . Miller, Eric Dumazet,
	Jakub Kicinski, linux-kernel, Eric Joyner, Vamsi Atluri
In-Reply-To: <20260608223256.12357-6-nikhil.rao@amd.com>

On 6/9/26 12:32 AM, Nikhil P. Rao wrote:
> +static int pdsc_host_mem_add_one(struct pdsc *pdsc, int index)
> +{
> +	struct pdsc_host_mem *hm = &pdsc->host_mem_reqs[index];
> +	union pds_core_dev_comp comp = {};
> +	union pds_core_dev_cmd cmd = {};
> +	int err;
> +
> +	memset(hm, 0, sizeof(*hm));

Minor nit: the buffer is kzmalloced() no need to zero it again.

> +	cmd.host_mem.opcode = PDS_CORE_CMD_HOST_MEM;
> +	cmd.host_mem.oper = PDS_CORE_HOST_MEM_QUERY;
> +	cmd.host_mem.index = cpu_to_le16(index);
> +	dev_dbg(pdsc->dev, "Sending devcmd for mem query index %d\n", index);
> +	err = pdsc_devcmd(pdsc, &cmd, &comp, pdsc->devcmd_timeout);
> +	if (err || comp.status != PDS_RC_SUCCESS) {
> +		dev_err(pdsc->dev, "mem query failed err %d status %d\n",
> +			err, comp.status);
> +		return err ? err : -EIO;
> +	}
> +	hm->size = le32_to_cpu(comp.host_mem.size);
> +	hm->tag = le16_to_cpu(comp.host_mem.tag);
> +	dev_dbg(pdsc->dev, "mem query returned size %d tag %d\n",
> +		hm->size, hm->tag);
> +
> +	if (!hm->size || hm->size > PDSC_HOST_MEM_MAX_CONTIG) {
> +		dev_err(pdsc->dev, "invalid size %d for tag %d\n",
> +			hm->size, hm->tag);
> +		err = -EINVAL;
> +		goto err_del;
> +	}
> +
> +	hm->order = get_order(hm->size);
> +	hm->pg = alloc_pages(GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN, hm->order);
> +	if (!hm->pg) {
> +		dev_err(pdsc->dev, "alloc order %d failed for tag %d\n",
> +			hm->order, hm->tag);

Minor nit: as this is a gracefully handled failure, possibly dev_warn()
is more suited and the message itself should be less alarming.

[...]
> +void pdsc_host_mem_add(struct pdsc *pdsc)
> +{
> +	union pds_core_dev_comp comp = {};
> +	union pds_core_dev_cmd cmd = {};
> +	u16 count;
> +	int err;
> +	int i;
> +
> +	if (!(pdsc->dev_ident.capabilities &
> +	     cpu_to_le64(PDS_CORE_DEV_CAP_HOST_MEM)))
> +		return;
> +
> +	cmd.host_mem.opcode = PDS_CORE_CMD_HOST_MEM;
> +	cmd.host_mem.oper = PDS_CORE_HOST_MEM_GET_COUNT;
> +	cmd.host_mem.index = cpu_to_le16(PDSC_HOST_MEM_MAX_COUNT);
> +	cmd.host_mem.max_contig = cpu_to_le32(PDSC_HOST_MEM_MAX_CONTIG);
> +	dev_dbg(pdsc->dev, "Sending devcmd for mem get count max_contig %u\n",
> +		PDSC_HOST_MEM_MAX_CONTIG);
> +	err = pdsc_devcmd(pdsc, &cmd, &comp, pdsc->devcmd_timeout);
> +	if (err || comp.status != PDS_RC_SUCCESS) {
> +		dev_err(pdsc->dev, "mem get count failed err %d status %d\n",
> +			err, comp.status);
> +		return;
> +	}
> +
> +	count = min(le16_to_cpu(comp.host_mem.count),
> +		    PDSC_HOST_MEM_MAX_COUNT);
> +	dev_dbg(pdsc->dev, "mem get count returned count %d\n", count);
> +	if (count == 0)
> +		return;
> +
> +	pdsc->host_mem_reqs = kzalloc_objs(*pdsc->host_mem_reqs, count,
> +					   GFP_KERNEL);
> +	if (!pdsc->host_mem_reqs) {
> +		dev_err(pdsc->dev, "failed to alloc host_mem_reqs array\n");
> +		return;
> +	}
> +
> +	for (i = 0; i < count; i++) {
> +		err = pdsc_host_mem_add_one(pdsc, i);
> +		if (err)
> +			break;

When pdsc_host_mem_add_one() returns an error, pdsc->host_mem_reqs[i].pg
will be zero. Errors are not propagate to the caller...

> +	}
> +}
> +
> +void pdsc_host_mem_free(struct pdsc *pdsc)
> +{
> +	int i;
> +
> +	if (!pdsc->host_mem_reqs)
> +		return;

... and this function will be unconditionally called on shutdown with
non zero host_mem_reqs.

> +
> +	for (i = 0; i < pdsc->num_host_mem_reqs; i++) {
> +		dma_unmap_page(pdsc->dev, pdsc->host_mem_reqs[i].pa,
> +			       pdsc->host_mem_reqs[i].size,
> +			       DMA_BIDIRECTIONAL);
> +		__free_pages(pdsc->host_mem_reqs[i].pg,

so  pdsc->host_mem_reqs[i].pg can be zero here. AFAICS at least
__free_pages() -> ___free_pages -> put_page_testzero ->
page_ref_count(0) will oops.

I find strange AI did not catch the above, so I'm possibly missing
something?!?

/P


^ permalink raw reply

* Re: [PATCH net-next v3] net: mana: Add Interrupt Moderation support
From: Simon Horman @ 2026-06-13  8:20 UTC (permalink / raw)
  To: haiyangz
  Cc: Simon Horman, linux-hyperv, netdev, kys, haiyangz, wei.liu, decui,
	longli, andrew+netdev, davem, edumazet, kuba, pabeni, kotaranov,
	shradhagupta, ernis, dipayanroy, gargaditya, kees, leitao,
	linux-kernel, linux-rdma, paulros
In-Reply-To: <20260611190239.2532429-1-haiyangz@linux.microsoft.com>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
Full review at: https://sashiko.dev
---
Date:   Thu Jun 11 19:02:22 2026 +0000

    net: mana: Add Interrupt Moderation support
    
    This commit adds Static and Dynamic Interrupt Moderation (DIM) support for
    Rx and Tx. It updates the queue creation procedure, adds functions to
    collect stats for DIM, and provides ethtool handler support to get/set
    the moderation settings.

> diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
> index 26aef21c6c2c8..d92e022d8533c 100644
> --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> @@ -1579,6 +1579,9 @@ int mana_create_wq_obj(struct mana_port_context *apc,
>  
>  	mana_gd_init_req_hdr(&req.hdr, MANA_CREATE_WQ_OBJ,
>  			     sizeof(req), sizeof(resp));
> +
> +	req.hdr.req.msg_version = GDMA_MESSAGE_V3;
> +	req.hdr.resp.msg_version = GDMA_MESSAGE_V2;
>  	req.vport = vport;
>  	req.wq_type = wq_type;
>  	req.wq_gdma_region = wq_spec->gdma_region;
> @@ -1587,6 +1590,9 @@ int mana_create_wq_obj(struct mana_port_context *apc,
>  	req.cq_size = cq_spec->queue_size;
>  	req.cq_moderation_ctx_id = cq_spec->modr_ctx_id;
>  	req.cq_parent_qid = cq_spec->attached_eq;
> +	req.req_cq_moderation = cq_spec->req_cq_moderation;
> +	req.cq_moderation_comp = cq_spec->cq_moderation_comp;
> +	req.cq_moderation_usec = cq_spec->cq_moderation_usec;

[Severity: High]
Does this break queue creation on older Azure host firmwares?

The code unconditionally bumps the WQ object creation request to use
GDMA_MESSAGE_V3 and passes the req_cq_moderation flag. If the firmware does
not support GDMA_PF_CAP_FLAG_1_DYN_INTERRUPT_MODERATION, could the firmware
reject the queue creation request and break device initialization entirely?

[ ... ]

> +static void mana_update_tx_dim(struct mana_cq *cq)
> +{
> +	struct mana_port_context *apc = netdev_priv(cq->txq->ndev);
> +	struct dim_sample dim_sample = {};
> +	struct mana_txq *txq = cq->txq;
> +
> +	if (!apc->tx_dim_enabled)
> +		return;
> +
> +	dim_update_sample(READ_ONCE(cq->dim_event_ctr), txq->stats.packets,
> +			  txq->stats.bytes, &dim_sample);
> +	net_dim(&cq->dim, &dim_sample);
> +}

[Severity: High]
Does this measure the CPU enqueue rate rather than the hardware completion
rate?

It appears that txq->stats.packets is incremented in mana_start_xmit()
upon enqueue, not during completion in mana_poll_tx_cq(). Dynamic interrupt
moderation relies on measuring the actual hardware completion rate to
function correctly.

Additionally, is it safe to read txq->stats.packets here without the
u64_stats_fetch_begin() retry loop? Reading a 64-bit statistic locklessly
without the synchronization primitives could result in torn reads on 32-bit
systems.

[ ... ]

> @@ -2324,7 +2434,13 @@ static int mana_cq_handler(void *context, struct gdma_queue *gdma_queue)
>  	if (w < cq->budget) {
>  		mana_gd_ring_cq(gdma_queue, SET_ARM_BIT);
>  		cq->work_done_since_doorbell = 0;
> -		napi_complete_done(&cq->napi, w);
> +
> +		if (napi_complete_done(&cq->napi, w)) {
> +			if (cq->type == MANA_CQ_TYPE_RX)
> +				mana_update_rx_dim(cq);
> +			else
> +				mana_update_tx_dim(cq);
> +		}

[Severity: High]
Is it safe to call mana_update_rx_dim() and mana_update_tx_dim() after
napi_complete_done()?

Since napi_complete_done() ends the NAPI polling cycle and relinquishes
mutual exclusion, and the hardware interrupt was already re-armed by
mana_gd_ring_cq() right before this, couldn't a new packet trigger an
interrupt immediately? This could allow NAPI to be scheduled on another CPU
concurrently while this CPU is still running the DIM update, potentially
corrupting the non-thread-safe net_dim() state machine.

[ ... ]

> @@ -2562,6 +2685,9 @@ static int mana_create_txq(struct mana_port_context *apc,
>  		napi_enable_locked(&cq->napi);
>  		txq->napi_initialized = true;
>  
> +		INIT_WORK(&cq->dim.work, mana_tx_dim_work);
> +		cq->dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;

[Severity: High]
Could this allow NAPI to schedule an uninitialized work_struct?

napi_enable_locked() is called right before INIT_WORK(). Once NAPI is
enabled, it can be scheduled to run immediately (for example, via netpoll).
If NAPI executes before INIT_WORK completes, mana_update_tx_dim() would
pass the uninitialized cq->dim to net_dim(), which could cause a kernel
panic when it attempts to call schedule_work().

This pattern also occurs in mana_create_rxq().

> diff --git a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
> index 94e658d07a27e..67a2b282ff4da 100644
> --- a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
> +++ b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c

[ ... ]

> @@ -440,18 +474,123 @@ static int mana_set_coalesce(struct net_device *ndev,
> +		if (enable_rx_dim)
> +			apc->rx_dim_enabled = true;
> +		if (enable_tx_dim)
> +			apc->tx_dim_enabled = true;

[Severity: High]
Could the lack of memory barriers here expose uninitialized DIM structures
to NAPI?

The driver initializes DIM via mana_dim_change() and then sets
apc->rx_dim_enabled to true. Without an smp_store_release() here and a
corresponding smp_load_acquire() in mana_update_rx_dim(), weakly-ordered
CPUs like ARM64 might reorder the stores. Concurrently, NAPI polling might
observe the flag as true before the initialization is fully visible in memory,
potentially invoking net_dim() on garbage memory.

^ permalink raw reply

* [PATCH bpf] bpf, sockmap: fix BUG_ON in skb_to_sgvec() on a resized ingress skb
From: Sechang Lim @ 2026-06-13  8:24 UTC (permalink / raw)
  To: John Fastabend, Jakub Sitnicki, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni
  Cc: Simon Horman, Liu Jian, Daniel Borkmann, Cong Wang, netdev, bpf,
	linux-kernel

sk_psock_skb_ingress_enqueue() maps a received message into a scatterlist
with skb_to_sgvec(skb, sg, off, len). On the SK_SKB strparser path off and
len come from the message's strp_msg (stm->offset and stm->full_len), set
by the stream parser. strparser does not trim the skb, so normally
skb->len - off >= full_len and len is within the skb.

An SK_SKB verdict (or parser) program may call bpf_skb_change_tail() and
shrink the skb after full_len was recorded. len then covers more bytes than
the skb holds, __skb_to_sgvec() walks past the data and trips BUG_ON(len):

  kernel BUG at net/core/skbuff.c:5286!
  RIP: 0010:__skb_to_sgvec+0x78c/0x790
  Call Trace:
   <IRQ>
   skb_to_sgvec+0x32/0x90
   sk_psock_skb_ingress_enqueue+0x42/0x370
   sk_psock_skb_ingress_self+0x1a8/0x200
   sk_psock_verdict_apply+0x33c/0x360
   sk_psock_strp_read+0x24a/0x370
   __strp_recv+0x66d/0xda0
   __tcp_read_sock+0x13d/0x590
   tcp_bpf_strp_read_sock+0x195/0x320
   strp_data_ready+0x267/0x340
   sk_psock_strp_data_ready+0x1ce/0x350
   tcp_data_queue+0x1364/0x2fd0
   </IRQ>

Clamp len to skb->len - off, and drop the message if off is already past
the skb. sk_psock_skb_ingress_enqueue() is the only skb_to_sgvec() caller
and both ingress paths (verdict SK_PASS and the backlog worker) reach it.
The clamp is a no-op unless the skb was shrunk.

Fixes: 7303524e04af ("skmsg: Lose offset info in sk_psock_skb_ingress")
Signed-off-by: Sechang Lim <rhkrqnwk98@gmail.com>
---
 net/core/skmsg.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/net/core/skmsg.c b/net/core/skmsg.c
index e1850caf1a71..2961178ebd1e 100644
--- a/net/core/skmsg.c
+++ b/net/core/skmsg.c
@@ -550,6 +550,10 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb,
 {
 	int num_sge, copied;
 
+	if (off >= skb->len)
+		return -EINVAL;
+	len = min_t(u32, len, skb->len - off);
+
 	/* skb_to_sgvec will fail when the total number of fragments in
 	 * frag_list and frags exceeds MAX_MSG_FRAGS. For example, the
 	 * caller may aggregate multiple skbs.
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH] net: airoha: Fix non-standard return value in airoha_ppe_get_wdma_info()
From: Lorenzo Bianconi @ 2026-06-13  8:27 UTC (permalink / raw)
  To: Wayen.Yan
  Cc: netdev, horms, pabeni, kuba, edumazet, andrew+netdev,
	angelogioacchino.delregno, matthias.bgg, linux-arm-kernel,
	linux-mediatek
In-Reply-To: <6a2ca3d9.ad59c0a6.147df9.2a62@mx.google.com>

[-- Attachment #1: Type: text/plain, Size: 1138 bytes --]

> airoha_ppe_get_wdma_info() returns -1 when the last path in the
> forwarding path stack is not of type DEV_PATH_MTK_WDMA. This is not
> a standard kernel error code. Replace it with -EINVAL since the
> input path type is invalid from the caller's perspective.

Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>

> 
> Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC")
> Signed-off-by: Wayen.Yan <win847@gmail.com>
> ---
>  drivers/net/ethernet/airoha/airoha_ppe.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
> index 5c9dff6..7260177 100644
> --- a/drivers/net/ethernet/airoha/airoha_ppe.c
> +++ b/drivers/net/ethernet/airoha/airoha_ppe.c
> @@ -264,7 +264,7 @@ static int airoha_ppe_get_wdma_info(struct net_device *dev, const u8 *addr,
>  
>  	path = &stack.path[stack.num_paths - 1];
>  	if (path->type != DEV_PATH_MTK_WDMA)
> -		return -1;
> +		return -EINVAL;
>  
>  	info->idx = path->mtk_wdma.wdma_idx;
>  	info->bss = path->mtk_wdma.bss;
> -- 
> 2.51.0
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH] net: airoha: Fix typos in comments and Kconfig
From: Lorenzo Bianconi @ 2026-06-13  8:30 UTC (permalink / raw)
  To: Wayen.Yan
  Cc: netdev, horms, pabeni, kuba, edumazet, andrew+netdev,
	angelogioacchino.delregno, matthias.bgg, linux-arm-kernel,
	linux-mediatek
In-Reply-To: <6a2ca74a.c5b1db4e.21a698.01e7@mx.google.com>

[-- Attachment #1: Type: text/plain, Size: 2599 bytes --]

> Fix several typos found during code review:
> - Kconfig: "Aiorha" -> "Airoha" in NET_AIROHA_FLOW_STATS help text
> - Comment: "CMD1" -> "CDM1" (Central DMA, not Command)
> - Comments: "GMD1/2/3/4" -> "GDM1/2/3/4" (Gigabit DMA, not GMD)
> 
> These are pure comment and documentation fixes with no functional impact.
> 
> Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC")
> Signed-off-by: Wayen.Yan <win847@gmail.com>

Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>

> ---
>  drivers/net/ethernet/airoha/Kconfig      |  2 +-
>  drivers/net/ethernet/airoha/airoha_eth.c | 10 +++++-----
>  2 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/ethernet/airoha/Kconfig b/drivers/net/ethernet/airoha/Kconfig
> index ad3ce50..1f6640a 100644
> --- a/drivers/net/ethernet/airoha/Kconfig
> +++ b/drivers/net/ethernet/airoha/Kconfig
> @@ -29,6 +29,6 @@ config NET_AIROHA_FLOW_STATS
>  	bool "Airoha flow stats"
>  	depends on NET_AIROHA && NET_AIROHA_NPU
>  	help
> -	  Enable Aiorha flowtable statistic counters.
> +	  Enable Airoha flowtable statistic counters.
>  
>  endif #NET_VENDOR_AIROHA
> diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
> index 31cdb11..9d9d34a 100644
> --- a/drivers/net/ethernet/airoha/airoha_eth.c
> +++ b/drivers/net/ethernet/airoha/airoha_eth.c
> @@ -294,18 +294,18 @@ static void airoha_fe_pse_ports_init(struct airoha_eth *eth)
>  			      FIELD_PREP(PSE_ALLRSV_MASK, all_rsv));
>  	}
>  
> -	/* CMD1 */
> +	/* CDM1 */
>  	for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM1]; q++)
>  		airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM1, q,
>  					 PSE_QUEUE_RSV_PAGES);
> -	/* GMD1 */
> +	/* GDM1 */
>  	for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM1]; q++)
>  		airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM1, q,
>  					 PSE_QUEUE_RSV_PAGES);
> -	/* GMD2 */
> +	/* GDM2 */
>  	for (q = 6; q < pse_port_num_queues[FE_PSE_PORT_GDM2]; q++)
>  		airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM2, q, 0);
> -	/* GMD3 */
> +	/* GDM3 */
>  	for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM3]; q++)
>  		airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM3, q,
>  					 PSE_QUEUE_RSV_PAGES);
> @@ -340,7 +340,7 @@ static void airoha_fe_pse_ports_init(struct airoha_eth *eth)
>  							 q, 0);
>  		}
>  	}
> -	/* GMD4 */
> +	/* GDM4 */
>  	for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM4]; q++)
>  		airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM4, q,
>  					 PSE_QUEUE_RSV_PAGES);
> -- 
> 2.51.0
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH] net: airoha: Fix always-true condition in PPE1 queue reservation loop
From: Lorenzo Bianconi @ 2026-06-13  8:36 UTC (permalink / raw)
  To: Wayen.Yan
  Cc: netdev, horms, pabeni, kuba, edumazet, andrew+netdev,
	angelogioacchino.delregno, matthias.bgg, linux-arm-kernel,
	linux-mediatek
In-Reply-To: <6a2ca3de.ad59c0a6.147df9.2ac1@mx.google.com>

[-- Attachment #1: Type: text/plain, Size: 1590 bytes --]

> In airoha_fe_pse_ports_init(), the inner condition for PPE1 queue
> reservation is identical to the for-loop bound, making it always true
> and the else branch dead code:
> 
>   for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE1]; q++) {
>       if (q < pse_port_num_queues[FE_PSE_PORT_PPE1])  /* always true */
>           set RSV_PAGES;
>       else
>           set 0;  /* unreachable */
>   }
> 
> The intended behavior is to reserve pages only for the first half of
> the queues, matching the PPE2 implementation on line 334 which
> correctly uses the /2 divisor. Fix the PPE1 condition accordingly.
> 
> Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC")
> Signed-off-by: Wayen.Yan <win847@gmail.com>

Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>

> ---
>  drivers/net/ethernet/airoha/airoha_eth.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
> index 31cdb11..999f517 100644
> --- a/drivers/net/ethernet/airoha/airoha_eth.c
> +++ b/drivers/net/ethernet/airoha/airoha_eth.c
> @@ -311,7 +311,7 @@ static void airoha_fe_pse_ports_init(struct airoha_eth *eth)
>  					 PSE_QUEUE_RSV_PAGES);
>  	/* PPE1 */
>  	for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE1]; q++) {
> -		if (q < pse_port_num_queues[FE_PSE_PORT_PPE1])
> +		if (q < pse_port_num_queues[FE_PSE_PORT_PPE1] / 2)
>  			airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q,
>  						 PSE_QUEUE_RSV_PAGES);
>  		else
> -- 
> 2.51.0
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH] net: dsa: sja1105: fix refcount leak in sja1105_setup_tc_taprio()
From: Paolo Abeni @ 2026-06-13  8:41 UTC (permalink / raw)
  To: Wentao Liang, olteanv, andrew, davem, edumazet, kuba
  Cc: linux-kernel, netdev, stable
In-Reply-To: <20260609074002.204113-1-vulab@iscas.ac.cn>

On 6/9/26 9:40 AM, Wentao Liang wrote:
> In sja1105_setup_tc_taprio(), taprio_offload_get() acquires a
> reference on the new offload and stores it in
> tas_data->offload[port]. If sja1105_init_scheduling() or
> sja1105_static_config_reload() later fails, the function returns
> without releasing the reference via taprio_offload_free(). The
> stored pointer is thus leaked, as the driver will not clean it up
> unless a subsequent TAPRIO_CMD_DESTROY is received, which may
> never happen.
> 
> Fix the leak by calling taprio_offload_free() and resetting
> tas_data->offload[port] to NULL on both error paths.
> 
> Cc: stable@vger.kernel.org
> Fixes: 317ab5b86c8e ("net: dsa: sja1105: Configure the Time-Aware Scheduler via tc-taprio offload")
> Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
> ---
>  drivers/net/dsa/sja1105/sja1105_tas.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/dsa/sja1105/sja1105_tas.c b/drivers/net/dsa/sja1105/sja1105_tas.c
> index e47967b12d5d..96cb5aa04910 100644
> --- a/drivers/net/dsa/sja1105/sja1105_tas.c
> +++ b/drivers/net/dsa/sja1105/sja1105_tas.c
> @@ -575,10 +575,18 @@ int sja1105_setup_tc_taprio(struct dsa_switch *ds, int port,
>  	tas_data->offload[port] = taprio_offload_get(admin);
>  
>  	rc = sja1105_init_scheduling(priv);
> -	if (rc < 0)
> +	if (rc < 0) {
> +		taprio_offload_free(tas_data->offload[port]);
> +		tas_data->offload[port] = NULL;
>  		return rc;
> +	}
>  
> -	return sja1105_static_config_reload(priv, SJA1105_SCHEDULING);
> +	rc = sja1105_static_config_reload(priv, SJA1105_SCHEDULING);
> +	if (rc < 0) {
> +		taprio_offload_free(tas_data->offload[port]);
> +		tas_data->offload[port] = NULL;

I think the config-cleanup issues mentioned by sashiko here should be
addressed.

/P


^ permalink raw reply

* Re: [PATCH iproute2-next] ipaddress: add support for showing IPv4 devconf attributes
From: Fernando Fernandez Mancera @ 2026-06-13  7:22 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, dsahern, davem, edumazet, kuba, pabeni, horms
In-Reply-To: <bdccf9bf-994d-445c-8167-4bcd8cd77e6e@suse.de>

On 6/13/26 8:41 AM, Fernando Fernandez Mancera wrote:
> On 6/13/26 4:29 AM, Stephen Hemminger wrote:
>> On Sat, 13 Jun 2026 01:17:22 +0200
>> Fernando Fernandez Mancera <fmancera@suse.de> wrote:
>>
>>> tatic void print_inet(FILE *fp, struct rtattr *inet_attr)
>>> +{
>>> +    struct rtattr *tb[IFLA_INET_MAX + 1];
>>> +
>>> +    parse_rtattr_nested(tb, IFLA_INET_MAX, inet_attr);
>>> +
>>> +    if (tb[IFLA_INET_CONF] && show_details) {
>>> +        int *conf = RTA_DATA(tb[IFLA_INET_CONF]);
>>> +        int max_elements = RTA_PAYLOAD(tb[IFLA_INET_CONF]) / 
>>> sizeof(int);
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_FORWARDING)
>>> +            print_string(PRINT_ANY, "forwarding", "forwarding %s ",
>>> +                     conf[IPV4_DEVCONF_FORWARDING - 1] ? "on" : "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_MC_FORWARDING)
>>> +            print_string(PRINT_ANY, "mc_forwarding", "mc_forwarding 
>>> %s ",
>>> +                     conf[IPV4_DEVCONF_MC_FORWARDING - 1] ? "on" : 
>>> "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_PROXY_ARP)
>>> +            print_string(PRINT_ANY, "proxy_arp", "proxy_arp %s ",
>>> +                     conf[IPV4_DEVCONF_PROXY_ARP - 1] ? "on" : "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_ACCEPT_REDIRECTS)
>>> +            print_string(PRINT_ANY, "accept_redirects",
>>> +                     "accept_redirects %s ",
>>> +                     conf[IPV4_DEVCONF_ACCEPT_REDIRECTS - 1] ? 
>>> "on" : "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_SECURE_REDIRECTS)
>>> +            print_string(PRINT_ANY, "secure_redirects",
>>> +                     "secure_redirects %s ",
>>> +                     conf[IPV4_DEVCONF_SECURE_REDIRECTS - 1] ? 
>>> "on" : "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_SEND_REDIRECTS)
>>> +            print_string(PRINT_ANY, "send_redirects", 
>>> "send_redirects %s ",
>>> +                     conf[IPV4_DEVCONF_SEND_REDIRECTS - 1] ? "on" : 
>>> "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_SHARED_MEDIA)
>>> +            print_string(PRINT_ANY, "shared_media", "shared_media %s ",
>>> +                     conf[IPV4_DEVCONF_SHARED_MEDIA - 1] ? "on" : 
>>> "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_RP_FILTER)
>>> +            print_int(PRINT_ANY, "rp_filter", "rp_filter %d ",
>>> +                  conf[IPV4_DEVCONF_RP_FILTER - 1]);
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE)
>>> +            print_string(PRINT_ANY, "accept_source_route",
>>> +                     "accept_source_route %s ",
>>> +                     conf[IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE - 1] ? 
>>> "on" : "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_BOOTP_RELAY)
>>> +            print_string(PRINT_ANY, "bootp_relay", "bootp_relay %s ",
>>> +                     conf[IPV4_DEVCONF_BOOTP_RELAY - 1] ? "on" : 
>>> "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_LOG_MARTIANS)
>>> +            print_string(PRINT_ANY, "log_martians", "log_martians %s ",
>>> +                     conf[IPV4_DEVCONF_LOG_MARTIANS - 1] ? "on" : 
>>> "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_TAG)
>>> +            print_int(PRINT_ANY, "tag", "tag %d ",
>>> +                  conf[IPV4_DEVCONF_TAG - 1]);
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_ARPFILTER)
>>> +            print_string(PRINT_ANY, "arpfilter", "arpfilter %s ",
>>> +                     conf[IPV4_DEVCONF_ARPFILTER - 1] ? "on" : "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_MEDIUM_ID)
>>> +            print_int(PRINT_ANY, "medium_id", "medium_id %d ",
>>> +                  conf[IPV4_DEVCONF_MEDIUM_ID - 1]);
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_NOXFRM)
>>> +            print_string(PRINT_ANY, "noxfrm", "noxfrm %s ",
>>> +                     conf[IPV4_DEVCONF_NOXFRM - 1] ? "on" : "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_NOPOLICY)
>>> +            print_string(PRINT_ANY, "nopolicy", "nopolicy %s ",
>>> +                     conf[IPV4_DEVCONF_NOPOLICY - 1] ? "on" : "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_FORCE_IGMP_VERSION)
>>> +            print_int(PRINT_ANY, "force_igmp_version", 
>>> "force_igmp_version %d ",
>>> +                  conf[IPV4_DEVCONF_FORCE_IGMP_VERSION - 1]);
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_ARP_ANNOUNCE)
>>> +            print_int(PRINT_ANY, "arp_announce", "arp_announce %d ",
>>> +                  conf[IPV4_DEVCONF_ARP_ANNOUNCE - 1]);
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_ARP_IGNORE)
>>> +            print_int(PRINT_ANY, "arp_ignore", "arp_ignore %d ",
>>> +                  conf[IPV4_DEVCONF_ARP_IGNORE - 1]);
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_PROMOTE_SECONDARIES)
>>> +            print_string(PRINT_ANY, "promote_secondaries",
>>> +                     "promote_secondaries %s ",
>>> +                     conf[IPV4_DEVCONF_PROMOTE_SECONDARIES - 1] ? 
>>> "on" : "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_ARP_ACCEPT)
>>> +            print_int(PRINT_ANY, "arp_accept", "arp_accept %d ",
>>> +                  conf[IPV4_DEVCONF_ARP_ACCEPT - 1]);
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_ARP_NOTIFY)
>>> +            print_string(PRINT_ANY, "arp_notify", "arp_notify %s ",
>>> +                     conf[IPV4_DEVCONF_ARP_NOTIFY - 1] ? "on" : "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_ACCEPT_LOCAL)
>>> +            print_string(PRINT_ANY, "accept_local", "accept_local %s ",
>>> +                     conf[IPV4_DEVCONF_ACCEPT_LOCAL - 1] ? "on" : 
>>> "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_SRC_VMARK)
>>> +            print_string(PRINT_ANY, "src_vmark", " src_vmark %s",
>>> +                     conf[IPV4_DEVCONF_SRC_VMARK - 1] ? "on" : "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_PROXY_ARP_PVLAN)
>>> +            print_string(PRINT_ANY, "proxy_arp_pvlan", 
>>> "proxy_arp_pvlan %s ",
>>> +                     conf[IPV4_DEVCONF_PROXY_ARP_PVLAN - 1] ? "on" : 
>>> "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_ROUTE_LOCALNET)
>>> +            print_string(PRINT_ANY, "route_localnet", 
>>> "route_localnet %s ",
>>> +                     conf[IPV4_DEVCONF_ROUTE_LOCALNET - 1] ? "on" : 
>>> "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_BC_FORWARDING)
>>> +            print_string(PRINT_ANY, "bc_forwarding", "bc_forwarding 
>>> %s ",
>>> +                     conf[IPV4_DEVCONF_BC_FORWARDING - 1] ? "on" : 
>>> "off");
>>> +
>>> +        if (max_elements >= 
>>> IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL)
>>> +            print_int(PRINT_ANY, "igmpv2_unsolicited_report_interval",
>>> +                  "igmpv2_unsolicited_report_interval %d ",
>>> +                  
>>> conf[IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL - 1]);
>>> +
>>> +        if (max_elements >= 
>>> IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL)
>>> +            print_int(PRINT_ANY, "igmpv3_unsolicited_report_interval",
>>> +                  "igmpv3_unsolicited_report_interval %d ",
>>> +                  
>>> conf[IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL - 1]);
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN)
>>> +            print_string(PRINT_ANY, "ignore_routes_with_linkdown",
>>> +                     "ignore_routes_with_linkdown %s ",
>>> +                     conf[IPV4_DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN - 
>>> 1] ?
>>> +                     "on" : "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_DROP_UNICAST_IN_L2_MULTICAST)
>>> +            print_string(PRINT_ANY, "drop_unicast_in_l2_multicast",
>>> +                     "drop_unicast_in_l2_multicast %s ",
>>> +                     conf[IPV4_DEVCONF_DROP_UNICAST_IN_L2_MULTICAST 
>>> - 1] ?
>>> +                     "on" : "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_DROP_GRATUITOUS_ARP)
>>> +            print_string(PRINT_ANY, "drop_gratuitous_arp",
>>> +                     "drop_gratuitous_arp %s ",
>>> +                     conf[IPV4_DEVCONF_DROP_GRATUITOUS_ARP - 1] ? 
>>> "on" : "off");
>>> +
>>> +        if (max_elements >= IPV4_DEVCONF_ARP_EVICT_NOCARRIER)
>>> +            print_string(PRINT_ANY, "arp_evict_nocarrier",
>>> +                     "arp_evict_nocarrier %s ",
>>> +                     conf[IPV4_DEVCONF_ARP_EVICT_NOCARRIER - 1] ? 
>>> "on" : "off");
>>> +    }
>>> +}
>>> +
>> There are three different ways to display a flag value in JSON used in 
>> iproute2.
>> This one is my least favorite.
>>
>> The three ways are:
>>     - print_bool
>>     - print_null (only if on)
>>     - print_string
>>
>> I would use the print_null pattern but print_bool would also be ok.
>>
> 
> Thanks for the suggestion Stephen, I would pick print_bool in this case.
> 
> If one of the options evolves to supporting something else we could 
> easily adapt it without breaking compatibility if we use print_bool. If 
> we use print_null I don't think we could do that.
> 

Hm. I am actually not so sure about this..

the current print_string approach matches the setter and also the 
netconf side. While print_bool would be easier to parse for JSON, it 
looks not so good for command line output.

print_null presents a different problem, users would need to make sure 
their parsing is working with an iproute2 version that support these new 
attributes.

So I am not so sure what is the best option here.

^ permalink raw reply

* Re: [PATCH v2 net] octeontx2-af: npc: Fix size of entry2cntr_map
From: patchwork-bot+netdevbpf @ 2026-06-13  9:00 UTC (permalink / raw)
  To: Ratheesh Kannoth
  Cc: kuba, linux-kernel, naveenm, netdev, sbhatta, sgoutham,
	andrew+netdev, davem, edumazet, pabeni
In-Reply-To: <20260610022344.969774-1-rkannoth@marvell.com>

Hello:

This patch was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:

On Wed, 10 Jun 2026 07:53:44 +0530 you wrote:
> KASAN prints below splat. This is caused by allocating counter for
> reserved mcam entry for cpt 2nd pass entry. But mcam->entry2cntr_map
> is not allocated for reserved entries.
> 
> BUG: KASAN: slab-out-of-bounds in npc_map_mcam_entry_and_cntr+0xb0/0x1a0
> Write of size 2 at addr ffff0001033e7ffe by task kworker/0:1/14
> 
> [...]

Here is the summary with links:
  - [v2,net] octeontx2-af: npc: Fix size of entry2cntr_map
    https://git.kernel.org/netdev/net/c/f9cd6fabe0e7

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* [PATCH] r8152: add vendor/device ID for CoreChips SR9900
From: zjzhao @ 2026-06-13  9:01 UTC (permalink / raw)
  To: hayeswang; +Cc: andrew+netdev, linux-usb, netdev, linux-kernel, zjzhao-eda

From: zjzhao-eda <zjzhao@edatec.cn>

The CoreChips SR9900 (0x0fe6:0x9900) is a USB 2.0 10/100
Ethernet adapter. Testing shows it works correctly with the
r8152 driver, reaching wire speed (94 Mbps) with zero packet
loss on both TCP and UDP.

Tested on Raspberry Pi, including hotplug and extended data
transfer.

Signed-off-by: zjzhao-eda <zjzhao@edatec.cn>
---
 drivers/net/usb/r8152.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index d61074178279..ea1733e3619c 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -10062,6 +10062,7 @@ static const struct usb_device_id rtl8152_table[] = {
 	{ USB_DEVICE(VENDOR_ID_DELL,    0xb097) },
 	{ USB_DEVICE(VENDOR_ID_ASUS,    0x1976) },
 	{ USB_DEVICE(VENDOR_ID_TRENDNET, 0xe02b) },
+	{ USB_DEVICE(0x0fe6, 0x9900) },
 	{}
 };
 
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH net-next v5 1/3] net: airoha: use int instead of atomic_t for qdma users counter
From: Lorenzo Bianconi @ 2026-06-13  9:06 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: linux-arm-kernel, linux-mediatek, netdev
In-Reply-To: <20260611-airoha-ethtool-priv_flags-v5-1-c11de08486d1@kernel.org>

[-- Attachment #1: Type: text/plain, Size: 3901 bytes --]

> QDMA users counter is always accessed holding RTNL lock so we do not
> require atomic_t for it.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
>  drivers/net/ethernet/airoha/airoha_eth.c | 4 ++--
>  drivers/net/ethernet/airoha/airoha_eth.h | 2 +-
>  2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
> index 504247c8bae9..9eb9b6a139b3 100644
> --- a/drivers/net/ethernet/airoha/airoha_eth.c
> +++ b/drivers/net/ethernet/airoha/airoha_eth.c
> @@ -1812,7 +1812,7 @@ static int airoha_dev_open(struct net_device *netdev)
>  	airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG,
>  			GLOBAL_CFG_TX_DMA_EN_MASK |
>  			GLOBAL_CFG_RX_DMA_EN_MASK);
> -	atomic_inc(&qdma->users);
> +	qdma->users++;
>  
>  	if (!airoha_is_lan_gdm_dev(dev) &&
>  	    airoha_ppe_is_enabled(qdma->eth, 1))
> @@ -1866,7 +1866,7 @@ static int airoha_dev_stop(struct net_device *netdev)
>  					    REG_GDM_FWD_CFG(port->id),
>  					    FE_PSE_PORT_DROP);
>  
> -	if (atomic_dec_and_test(&qdma->users)) {
> +	if (!--qdma->users) {
>  		airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG,
>  				  GLOBAL_CFG_TX_DMA_EN_MASK |
>  				  GLOBAL_CFG_RX_DMA_EN_MASK);

commenting on sashiko's report:
https://sashiko.dev/#/patchset/20260611-airoha-ethtool-priv_flags-v5-0-c11de08486d1%40kernel.org

- This is a pre-existing issue, but by not cleaning the TX queues when
  qdma->users > 0, does this leave the stopped device's packets in flight?
  When airoha_dev_stop() is called, it resets the device's BQL counters via
  netdev_tx_reset_subqueue(). By skipping the cleanup when other devices are
  still sharing this QDMA ring, any pending skbs originating from the stopped
  device are left to linger in the hardware TX ring.
  Because the hardware continues to process the shared ring on behalf of the
  remaining interfaces, the active NAPI poll will process their completions in
  airoha_qdma_tx_napi_poll():
  		if (skb) {
  			struct netdev_queue *txq;
  			txq = skb_get_tx_queue(skb->dev, skb);
  			netdev_tx_completed_queue(txq, 1, skb->len);
  			dev_kfree_skb_any(skb);
  		}
  Can this cause an unsigned underflow in dql->num_queued since the BQL
  state was already reset to 0 by ndo_stop?

  - This issue is valid, but as pointed out by sashiko, this problem has not
    been introduced by this patch. In particular, I think we should remove
    netdev_tx_reset_subqueue() in airoha_dev_stop() and run
    netdev_tx_completed_queue() in airoha_qdma_cleanup_tx_queue(). We need to
    pay attention to not loop over already unregistered net_devices in
    airoha_qdma_cleanup_tx_queue() run from airoha_remove().
    I will post a dedicated patch for this issue.

- Also, if the device was being unregistered, unregister_netdev() frees the
  netdev memory without waiting for TX skbs (which do not hold a reference to
  dev). Could this lead to a use-after-free when dereferencing skb->dev here?
  Should the driver selectively purge skbs belonging to the stopping netdev
  from the shared TX ring before ndo_stop returns?

  - I do not think this is a problem in the current codebase since the
    net_devices are unregistered just during module unload running
    airoha_remove() where we run airoha_qdma_stop_napi() to stop TX/RX NAPIs.

Regards,
Lorenzo

> diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
> index 8f42973f9cf5..24fd8dcf7fca 100644
> --- a/drivers/net/ethernet/airoha/airoha_eth.h
> +++ b/drivers/net/ethernet/airoha/airoha_eth.h
> @@ -526,7 +526,7 @@ struct airoha_qdma {
>  	struct airoha_eth *eth;
>  	void __iomem *regs;
>  
> -	atomic_t users;
> +	int users;
>  
>  	struct airoha_irq_bank irq_banks[AIROHA_MAX_NUM_IRQ_BANKS];
>  
> 
> -- 
> 2.54.0
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* [PATCH net-next v4] ixgbe: implement get_queue_stats_rx
From: Kshitiz Bartariya @ 2026-06-13  9:12 UTC (permalink / raw)
  To: anthony.l.nguyen, przemyslaw.kitszel, andrew+netdev, davem,
	edumazet, kuba, pabeni, jedrzej.jagielski
  Cc: Kshitiz Bartariya, intel-wired-lan, netdev, linux-kernel

Hook into the netdev_stat_ops interface to expose per RX queue
statistics through the netdev generic netlink API.

The following counters are filled:
 - bytes: maps directly to bytes
 - packets: maps directly to packets
 - alloc_fail: sum of alloc_rx_page_failed and alloc_rx_buff_failed
 - csum_bad: maps directly to csum_err, which is incremented for both
   IP header and L4 checksum errors in ixgbe_rx_checksum().

The new per-queue stats can be observed with:
  $ ynltool qstats show scope queue

Reviewed-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
Signed-off-by: Kshitiz Bartariya <kshitiz.bartariya@zohomail.in>
---
v4:
 - Changed comment format from // to /* */
 - Moved ixgbe_stat_ops declaration next to the ixgbe_netdev_ops
 Suggested by Jedrzej Jagielski.

v3:
 - Added bytes and packets stats counters
 - Implemented ixgbe_get_base_stats function
 As suggested by AI on 
 https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260603174857.78666-1-kshitiz.bartariya%40zohomail.in
 https://lore.kernel.org/lkml/20260612084605.19785-1-kshitiz.bartariya@zohomail.in/

v2:
 Amended commit message with command to get RX queue stats as 
 suggested by Jedrzej Jagielski.
 https://lore.kernel.org/lkml/20260603174857.78666-1-kshitiz.bartariya@zohomail.in/

v1: 
 https://lore.kernel.org/lkml/20260602100932.21838-1-kshitiz.bartariya@zohomail.in/

 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 30 +++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index bc16e4c93fd4..67844e25af23 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -9759,6 +9759,30 @@ static void ixgbe_get_stats64(struct net_device *netdev,
 	stats->rx_missed_errors	= netdev->stats.rx_missed_errors;
 }
 
+static void ixgbe_get_queue_stats_rx(struct net_device *dev, int idx,
+				     struct netdev_queue_stats_rx *stats)
+{
+	struct ixgbe_adapter *adapter = ixgbe_from_netdev(dev);
+	struct ixgbe_ring *ring = adapter->rx_ring[idx];
+
+	stats->bytes = ring->stats.bytes;
+	stats->packets = ring->stats.packets;
+	stats->alloc_fail = ring->rx_stats.alloc_rx_page_failed +
+			    ring->rx_stats.alloc_rx_buff_failed;
+	stats->csum_bad = ring->rx_stats.csum_err;
+}
+
+static void ixgbe_get_base_stats(struct net_device *dev,
+				 struct netdev_queue_stats_rx *rx,
+				 struct netdev_queue_stats_tx *tx)
+{
+	/* ixgbe has no inactive queues */
+	rx->bytes = 0;
+	rx->packets = 0;
+	rx->alloc_fail = 0;
+	rx->csum_bad = 0;
+}
+
 static int ixgbe_ndo_get_vf_stats(struct net_device *netdev, int vf,
 				  struct ifla_vf_stats *vf_stats)
 {
@@ -11116,6 +11140,11 @@ static const struct net_device_ops ixgbe_netdev_ops = {
 	.ndo_hwtstamp_set	= ixgbe_ptp_hwtstamp_set,
 };
 
+static const struct netdev_stat_ops ixgbe_stat_ops = {
+	.get_queue_stats_rx = ixgbe_get_queue_stats_rx,
+	.get_base_stats = ixgbe_get_base_stats,
+};
+
 static void ixgbe_disable_txr_hw(struct ixgbe_adapter *adapter,
 				 struct ixgbe_ring *tx_ring)
 {
@@ -11662,6 +11691,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	hw->phy.mdio.mdio_write = ixgbe_mdio_write;
 
 	netdev->netdev_ops = &ixgbe_netdev_ops;
+	netdev->stat_ops = &ixgbe_stat_ops;
 	ixgbe_set_ethtool_ops(netdev);
 	netdev->watchdog_timeo = 5 * HZ;
 	strscpy(netdev->name, pci_name(pdev), sizeof(netdev->name));
-- 
2.50.1 (Apple Git-155)


^ permalink raw reply related

* Re: [PATCHv2 0/4] m68k: coldfire: fix non-standard readX()/writeX() functions
From: Paolo Abeni @ 2026-06-13  9:22 UTC (permalink / raw)
  To: Greg Ungerer, linux-m68k
  Cc: linux-kernel, arnd, wei.fang, frank.li, shenwei.wang, imx, netdev,
	nico, adureghello, ulfh, linux-mmc, linux-can, linux-spi, olteanv
In-Reply-To: <20260609142139.1563360-1-gerg@linux-m68k.org>

On 6/9/26 4:12 PM, Greg Ungerer wrote:
> This odd collection of patches is aimed at fixing the non-standard ColdFire
> set of readX()/writeX() IO access functions. Instead switching to using the
> asm-generic definitions in include/asm-generic/io.h. The difficulty comes
> in trying not to break any drivers with this change.
> 
> The implementation of the readX()/writeX() family of IO access functions
> is non-standard on ColdFire platforms. They either return big-endian (that
> is native endian) data, or on platforms with PCI bus support check the
> supplied address and return either big or little endian data based on that
> check. This is non-standard, they are expected to always return
> little-endian byte ordered data. Unfortunately this behavior also means
> that ioreadX()/iowroteX() and their big-endian counter parts
> ioreadXbe()/iowriteXbe() are currently broken because they are implemented
> using the readX()/writeX() functions.
> 
> Patches 1, 2 and 3 in this series are specific driver changes that can be
> made independently of the final ColdFire readX()/writeX() change.
> 
> Patch 4 is the actual switch to ColdFire building using asm-generic
> readX()/writeX(), but also contains three driver fixes that are not easily
> handled independently.
> 
> Note that I don't have access to all supported hardware needed to fully
> test all these changes. I have tested what I have, a bunch of the standard
> Freescale ColdFire eval boards, and inspected generated code for differences.
> 
> Note also that patch 3 relies on changes that are currently only in
> linux-next, and are scheduled to hit mainline during the next v7.2
> merge window. Those changes are also available in an immutable git tree
> at git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu.git
> cf-internal-io branch.

I understand that with this series you are targeting the m68K tree, am I
correct?

A possibly better option would be, after that the pre-req patches land
into Linus's tree, to share an immutable branch for this series, so that
both m68k and net-next could pull it.

/P


^ permalink raw reply

* Re: [PATCH net-next v4 13/13] net: ethernet: adi: Add a driver for the ADIN1140 MACPHY
From: Paolo Abeni @ 2026-06-13  9:26 UTC (permalink / raw)
  To: ciprian.regus
  Cc: parthiban.veerasooran, andrew+netdev, davem, edumazet, kuba,
	pabeni, horms, corbet, skhan, andrew, hkallweit1, linux, robh,
	krzk+dt, conor+dt, netdev, linux-kernel, linux-doc, devicetree
In-Reply-To: <20260609-adin1140-driver-v4-13-0753e28ee004@analog.com>

From: AI Reviewer <ai@example.com>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
Full review at: https://netdev-ai.bots.linux.dev/sashiko/
---
net: ethernet: adi: Add a driver for the ADIN1140 MACPHY

This patch adds a driver for the ADIN1140 10BASE-T1S MAC-PHY which talks
to the host over SPI using the OA TC6 protocol. It introduces a custom
mii_bus to work around two hardware issues, and exposes both rtnl link
stats and ethtool MAC stats from periodically polled hardware counters.

> diff --git a/MAINTAINERS b/MAINTAINERS
> index 50f795dfa880..c3cab8f7b9ef 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1858,6 +1858,14 @@ S:	Supported
>  W:	https://ez.analog.com/linux-software-drivers
>  F:	drivers/dma/dma-axi-dmac.c
>  
> +ANALOG DEVICES INC ETHERNET DRIVERS
> +M:	Ciprian Regus <ciprian.regus@analog.com>
> +L:	netdev@vger.kernel.org
> +S:	Maintained
> +W:	https://ez.analog.com/linux-software-drivers
> +F:	Documentation/devicetree/bindings/net/adi,ad3306.yaml
> +F:	drivers/net/ethernet/adi/adin1140.c

[Medium]
The MAINTAINERS entry references
Documentation/devicetree/bindings/net/adi,ad3306.yaml, but that file is
not added by this patch and does not appear elsewhere in the tree.

The driver also introduces two new of compatibles:

	{ .compatible = "adi,ad3306" },
	{ .compatible = "adi,adin1140" },

with no YAML schema. Should the binding document be added in this same
series so that the F: line resolves and dt_binding_check can validate
the new compatibles?

> diff --git a/drivers/net/ethernet/adi/adin1140.c b/drivers/net/ethernet/adi/adin1140.c
> new file mode 100644
> index 000000000000..306e5de6faa5
> --- /dev/null
> +++ b/drivers/net/ethernet/adi/adin1140.c

[ ... ]

> +static int adin1140_mac_filter_set(struct adin1140_priv *priv,
> +				   const u8 *addr, const u8 *mask,
> +				   u8 slot)
> +{
> +	u32 reg_address;
> +	u32 val;
> +	int ret;
> +
> +	if (slot >= ADIN1140_MAC_FILT_MAX_SLOT)
> +		return -ENOSPC;
> +
> +	reg_address = ADIN1140_MAC_ADDR_FILT_UPR_REG + 2 * slot;
> +
> +	ret = oa_tc6_write_register_mms(priv->tc6, OA_TC6_MAC_MMS1,
> +					reg_address,
> +					get_unaligned_be16(&addr[0]) |
> +					ADIN1140_MAC_ADDR_FILT_APPLY2PORT1 |
> +					ADIN1140_MAC_ADDR_FILT_TO_HOST);
> +	if (ret)
> +		return ret;
> +
> +	reg_address = ADIN1140_MAC_ADDR_FILT_LWR_REG + 2 * slot;
> +	ret = oa_tc6_write_register_mms(priv->tc6, OA_TC6_MAC_MMS1,
> +					reg_address,
> +					get_unaligned_be32(&addr[2]));
> +	if (ret)
> +		return ret;
> +
> +	/* Only the first 2 destination MAC filter slots support masking.
> +	 * For the other entries, the destination address in the received
> +	 * frame must match exactly.
> +	 */
> +	if (slot >= ADIN1140_MAC_FILT_MASK_LIMIT)
> +		return 0;
> +
> +	val = get_unaligned_be16(&mask[0]);
> +	reg_address = ADIN1140_MAC_ADDR_MASK_UPR_REG + (2 * slot);
> +
> +	ret = oa_tc6_write_register_mms(priv->tc6, OA_TC6_MAC_MMS1,
> +					reg_address, val);
> +	if (ret)
> +		return ret;
> +
> +	val = get_unaligned_be32(&mask[2]);
> +	reg_address = ADIN1140_MAC_ADDR_MASK_LWR_REG + (2 * slot);
> +
> +	return oa_tc6_write_register_mms(priv->tc6, OA_TC6_MAC_MMS1,
> +					 reg_address, val);
> +}

[Medium]
adin1140_mac_filter_set() performs up to four sequential
oa_tc6_write_register_mms() calls (filter upper, filter lower, mask
upper, mask lower) and returns at the first error without rolling back
the writes that already succeeded.

If the upper-half write of a new MAC succeeds and the lower-half write
fails, the slot is left programmed with (new high | old low). Callers
treat this as single-shot:

	ret = adin1140_mac_filter_set(priv, address->sa_data, mask,
				      ADIN1140_MAC_FILT_UC_SLOT);
	if (ret)
		return ret;

	eth_commit_mac_addr_change(netdev, addr);

so adin1140_set_mac_address() leaves netdev->dev_addr at the old value
while the hardware filter now matches a third, hybrid address. The same
applies to adin1140_rx_mode_work() which just returns on the first
error and leaves the dynamic filter table inconsistent with
netdev->uc/mc.

Should this function stage the writes (or perform a rollback / clear of
the affected slot) so a partial failure cannot leave the hardware
filter in a state that does not match the driver's view?

[ ... ]

> +static void adin1140_rx_mode_work(struct work_struct *work)
> +{
> +	struct adin1140_priv *priv = container_of(work, struct adin1140_priv,
> +						  rx_mode_work);
> +	struct netdev_hw_addr *ha;
> +	bool all_multi, promisc;
> +	u8 mask[ETH_ALEN];
> +	u8 start, end;
> +	u32 mac_addrs;
> +	u8 slot, i;
> +	int ret;
> +
> +	/* The ADIN1140 has 16 dest MAC address filter slots:
> +	 * 0 - reserved for all multicast filter.
> +	 * 1 - reserved for broadcast filter.
> +	 * 2 - reserved for the device's own unicast MAC.
> +	 * 3 -> 15 - available for other unicast/multicast filters.
> +	 */
> +
> +	mac_addrs = netdev_uc_count(priv->netdev) +
> +		    netdev_mc_count(priv->netdev);
> +
> +	if (priv->netdev->flags & IFF_PROMISC) {
> +		promisc = true;
> +		all_multi = false;
> +	} else if (priv->netdev->flags & IFF_ALLMULTI) {
> +		promisc = false;
> +		all_multi = true;
> +	} else if (mac_addrs <= ADIN1140_MAC_FILT_AVAIL) {
> +		promisc = false;
> +		all_multi = false;
> +
> +		slot = ADIN1140_MAC_FILT_UC_SLOT + 1;
> +		memset(mask, 0xFF, ETH_ALEN);
> +
> +		netdev_for_each_uc_addr(ha, priv->netdev) {
> +			ret = adin1140_mac_filter_set(priv, ha->addr, mask,
> +						      slot);
> +			if (ret)
> +				return;
> +
> +			slot++;
> +		}
> +
> +		netdev_for_each_mc_addr(ha, priv->netdev) {
> +			ret = adin1140_mac_filter_set(priv, ha->addr, mask,
> +						      slot);
> +			if (ret)
> +				return;
> +
> +			slot++;
> +		}
> +
> +		for (i = slot; i < ADIN1140_MAC_FILT_MAX_SLOT; i++) {
> +			ret = adin1140_mac_filter_clear(priv, i);
> +			if (ret)
> +				return;
> +		}
> +
> +	} else {
> +		/* The filter table is full. Enable promisc mode. */
> +		promisc = true;
> +		all_multi = false;
> +
> +		start = ADIN1140_MAC_FILT_UC_SLOT + 1;
> +		end = ADIN1140_MAC_FILT_MAX_SLOT;
> +		for (i = start; i < end; i++) {
> +			ret = adin1140_mac_filter_clear(priv, i);
> +			if (ret)
> +				return;
> +		}
> +	}
> +
> +	ret = adin1140_promiscuous_mode(priv, promisc);
> +	if (ret)
> +		return;
> +
> +	adin1140_filter_all_multicast(priv, all_multi);
> +}

[High]
This work iterates priv->netdev->uc and ->mc with no synchronization:

	netdev_for_each_uc_addr(ha, priv->netdev) {
		ret = adin1140_mac_filter_set(priv, ha->addr, mask, slot);
		...
	}

	netdev_for_each_mc_addr(ha, priv->netdev) {
		...
	}

netdev_for_each_uc_addr() and netdev_for_each_mc_addr() expand to
plain list_for_each_entry() over dev->uc.list / dev->mc.list. Callers
are required to hold netif_addr_lock_bh() (or rtnl) because dev_uc_add
/ dev_uc_del / dev_mc_add / dev_mc_del can mutate those lists from
user-space ip address/maddr changes.

Inside the loop ha->addr is then handed to adin1140_mac_filter_set(),
which performs SPI register writes that can sleep, so taking
netif_addr_lock_bh() across the iteration is not directly viable.

Can this race with a concurrent dev_uc_del() / dev_mc_del() and
dereference freed list entries (or skip / duplicate filter slots)?
Other ethernet drivers that need to issue sleeping ops while syncing
the address lists use __dev_uc_sync() / __dev_mc_sync() which copy
state under netif_addr_lock; would that pattern be more appropriate
here?

[Medium]
In the IFF_PROMISC and IFF_ALLMULTI branches, slots 3..15 are not
cleared:

	if (priv->netdev->flags & IFF_PROMISC) {
		promisc = true;
		all_multi = false;
	} else if (priv->netdev->flags & IFF_ALLMULTI) {
		promisc = false;
		all_multi = true;
	} else if (mac_addrs <= ADIN1140_MAC_FILT_AVAIL) {
		...
		for (i = slot; i < ADIN1140_MAC_FILT_MAX_SLOT; i++) {
			ret = adin1140_mac_filter_clear(priv, i);
			...
		}
	} else {
		...
		for (i = start; i < end; i++) {
			ret = adin1140_mac_filter_clear(priv, i);
			...
		}
	}

If a previous invocation populated slots 3..N with extra unicast or
multicast filters and the user then enables IFF_ALLMULTI, those
previously installed unicast filters remain active in hardware
(carrying APPLY2PORT1 | TO_HOST). Should the IFF_ALLMULTI path also
clear slots 3..15 so traffic for addresses no longer in netdev->uc/mc
is not still forwarded to the host?

[ ... ]

> +static void adin1140_stats_work(struct work_struct *work)
> +{
> +	struct delayed_work *dwork = to_delayed_work(work);
> +	u64 stat_buff[ADIN1140_STATS_CNT] = {};
> +	struct adin1140_priv *priv;
> +	u32 reg_val;
> +	int ret;
> +	u32 i;
> +
> +	priv = container_of(dwork, struct adin1140_priv, stats_work);
> +
> +	for (i = 0; i < ARRAY_SIZE(adin1140_stat_regs); i++) {
> +		ret = oa_tc6_read_register_mms(priv->tc6, OA_TC6_MAC_MMS1,
> +					       adin1140_stat_regs[i],
> +					       &reg_val);
> +		if (ret)
> +			break;
> +
> +		stat_buff[i] = reg_val;
> +	}
> +
> +	scoped_guard(spinlock, &priv->stat_lock)
> +		memcpy(&priv->stats, stat_buff, sizeof(priv->stats));
> +
> +	schedule_delayed_work(dwork, ADIN1140_STATS_CHECK_DELAY);
> +}

[Medium]
stat_buff is zero-initialized and the loop break on a read error is
followed unconditionally by:

	scoped_guard(spinlock, &priv->stat_lock)
		memcpy(&priv->stats, stat_buff, sizeof(priv->stats));

If oa_tc6_read_register_mms() fails partway through, every entry from
the failing index onwards is still zero, and that all-zero tail is
copied over the previously valid u64 counters. Since priv->stats[] is
read directly by adin1140_ndo_get_stats64(),
adin1140_get_eth_mac_stats() and adin1140_get_ethtool_stats(), a
single transient SPI/TC6 hiccup makes the rtnl_link_stats64 and
ethtool_eth_mac_stats counters drop to zero before climbing again.
Should the memcpy be skipped on error, or should partial updates be
merged into priv->stats[] only for the indices that were read
successfully?

[Medium]
The hardware counters at MMS1 0xA1..0xBA are read into u32 reg_val and
then stored as-is into the u64 stat_buff[i]:

	ret = oa_tc6_read_register_mms(priv->tc6, OA_TC6_MAC_MMS1,
				       adin1140_stat_regs[i],
				       &reg_val);
	...
	stat_buff[i] = reg_val;

priv->stats[] feeds rtnl_link_stats64 and ethtool_eth_mac_stats, both
of which document monotonic u64 counters. On 32-bit hardware register
wrap (0xFFFFFFFF -> 0) the user-visible u64 value will go backwards,
and with a 3-second poll interval a fast counter (e.g.
FramesReceivedOK on a busy 10BASE-T1S segment) can wrap entirely
between samples. Should the driver compute deltas with 32-bit wrap
handling and accumulate them into a software u64 counter rather than
overwriting?

[ ... ]

> +static void adin1140_get_ethtool_stats(struct net_device *netdev,
> +				       struct ethtool_stats *stats, u64 *data)
> +{
> +	struct adin1140_priv *priv = netdev_priv(netdev);
> +	u32 i;
> +
> +	scoped_guard(spinlock, &priv->stat_lock) {
> +		for (i = 0; i < ARRAY_SIZE(adin1140_stats); i++)
> +			data[i] = priv->stats[adin1140_stats[i].idx];
> +	}
> +}
> +
> +static void adin1140_get_ethtool_strings(struct net_device *netdev, u32 sset,
> +					 u8 *p)
> +{
> +	u32 i;
> +
> +	switch (sset) {
> +	case ETH_SS_STATS:
> +		for (i = 0; i < ARRAY_SIZE(adin1140_stats); i++)
> +			ethtool_puts(&p, adin1140_stats[i].name);
> +
> +		break;
> +	}
> +}

[Medium]
The driver implements both .ndo_get_stats64 and .get_eth_mac_stats,
yet adin1140_stats[] adds private ethtool -S strings whose values are
already exposed (or trivially derivable) through those standard uAPIs:

	{.name = "rx_unicast_frames", .idx = rx_uc_frames},
	{.name = "rx_preamble_errors", .idx = rx_preamble_errors},
	{.name = "rx_ifg_errors", .idx = rx_ifg_errors},
	{.name = "rx_addr_filter_dropped", .idx = rx_addr_filter_dropped},
	{.name = "tx_unicast_frames", .idx = tx_uc_frames},

rx_addr_filter_dropped is already aggregated into
rtnl_link_stats64.rx_dropped by this same driver:

	storage->rx_dropped = priv->stats[rx_fifo_full_dropped] +
			      priv->stats[rx_addr_filter_dropped];

rx_unicast_frames and tx_unicast_frames are derivable from
ethtool_eth_mac_stats (FramesReceivedOK minus broadcast minus
multicast, and the Xmitted equivalents) which are populated in
__adin1140_eth_mac_stats.

Per Documentation/networking/statistics.rst, should these counters be
left out of ethtool -S since standard uAPIs already cover them?
-- 
This is an AI-generated review.


^ permalink raw reply

* Re: [PATCH net-next v5 3/3] net: airoha: defer GDM3/GDM4 WAN mode and GDM2 loopback to QoS offload
From: Lorenzo Bianconi @ 2026-06-13  9:39 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: linux-arm-kernel, linux-mediatek, netdev, Madhur Agrawal,
	Alexander Lobakin
In-Reply-To: <20260611-airoha-ethtool-priv_flags-v5-3-c11de08486d1@kernel.org>

[-- Attachment #1: Type: text/plain, Size: 11446 bytes --]

Commenting on sashiko's report:
https://sashiko.dev/#/patchset/20260611-airoha-ethtool-priv_flags-v5-0-c11de08486d1%40kernel.org


[...]
>  static void airoha_dev_set_qdma(struct airoha_gdm_dev *dev)
>  {
>  	struct net_device *netdev = netdev_from_priv(dev);
> +	struct airoha_qdma *cur_qdma, *qdma;
>  	struct airoha_eth *eth = dev->eth;
>  	int ppe_id;
>  
>  	/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
> -	dev->qdma = &eth->qdma[!airoha_is_lan_gdm_dev(dev)];
> -	netdev->irq = dev->qdma->irq_banks[0].irq;
> +	qdma = &eth->qdma[!airoha_is_lan_gdm_dev(dev)];
> +	cur_qdma = airoha_qdma_deref(dev);
> +	if (netif_running(netdev))
> +		airoha_qdma_start(qdma);
> +
> +	rcu_assign_pointer(dev->qdma, qdma);
> +	netdev->irq = qdma->irq_banks[0].irq;
>  
>  	ppe_id = !airoha_is_lan_gdm_dev(dev) && airoha_ppe_is_enabled(eth, 1);
>  	airoha_ppe_set_cpu_port(dev, ppe_id, airoha_get_fe_port(dev));
> +
> +	if (!cur_qdma)
> +		return;
> +
> +	synchronize_rcu();
> +	netif_tx_wake_all_queues(netdev);
> +
> +	if (netif_running(netdev))
> +		airoha_qdma_stop(cur_qdma);
>  }

- When we switch the QDMA of a running device, airoha_qdma_stop() might
  free pending SKBs via dev_kfree_skb_any() in airoha_qdma_cleanup_tx_queue().
  Are these SKBs freed without calling netdev_tx_completed_queue() to
  update Byte Queue Limits (BQL)?
  Since the device is running, could the BQL counters leak and cause the
  TX queue to permanently hang once the limit is reached?

  - As pointed out in path 1/3, this is a pre-existing issue since we have the
    same problem running airoha_dev_stop() for a QDMA single-user device
    (airoha_qdma_cleanup_tx_queue() can run before the pending TX NAPI).
    I will fix the problem with a dedicated patch.

>  
>  static int airoha_dev_init(struct net_device *netdev)
> @@ -2180,9 +2244,9 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
>  				   struct net_device *netdev)
>  {
>  	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> -	struct airoha_qdma *qdma = dev->qdma;
>  	u32 nr_frags, tag, msg0, msg1, len;
>  	struct airoha_queue_entry *e;
> +	struct airoha_qdma *qdma;
>  	struct netdev_queue *txq;

- This is a pre-existing issue, but does the TX path modify the TCP header
  directly without ensuring it is in the linear region?

  - This issue (not introduced by this patch) has been already reported in the
    past and we already agreed that it can't occur.


>  	struct airoha_queue *q;
>  	LIST_HEAD(tx_list);
> @@ -2191,6 +2255,8 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
>  	u16 index;
>  	u8 fport;
>  

[...]

> @@ -2793,11 +2869,12 @@ static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
>  	u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
>  	int err, num_tx_queues = netdev->real_num_tx_queues;
>  	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> -	struct airoha_qdma *qdma = dev->qdma;
> +	struct airoha_qdma *qdma;
>  
>  	/* Here we need to check the requested QDMA channel is not already
>  	 * in use by another net_device running on the same QDMA block.
>  	 */
> +	qdma = airoha_qdma_deref(dev);

- This is a pre-existing issue, but does modifying real_num_tx_queues
  as a dense counter cause problems when QoS leaf queues are allocated
  with sparse IDs?

  - I have already a fix for this issue I need to post.

>  	if (test_and_set_bit(channel, qdma->qos_channel_map)) {
>  		NL_SET_ERR_MSG_MOD(opt->extack,
>  				   "qdma qos channel already in use");
> @@ -2831,7 +2908,7 @@ static int airoha_qdma_set_rx_meter(struct airoha_gdm_dev *dev,
>  				    u32 rate, u32 bucket_size,

[...]

> +
> +static int airoha_enable_qos_for_gdm34(struct net_device *netdev,
> +				       struct netlink_ext_ack *extack)
> +{
> +	struct airoha_gdm_dev *wan_dev, *dev = netdev_priv(netdev);
> +	struct airoha_gdm_port *port = dev->port;
> +	struct airoha_eth *eth = dev->eth;
> +	int err = -EBUSY;
> +
> +	if (port->id != AIROHA_GDM3_IDX &&
> +	    port->id != AIROHA_GDM4_IDX) {
> +		/* HW QoS is always supported by GDM1 and GDM2 */
> +		return 0;
> +	}
> +
> +	if (!airoha_is_lan_gdm_dev(dev)) /* Already enabled */
> +		return 0;
> +
> +	mutex_lock(&flow_offload_mutex);
> +
> +	wan_dev = airoha_get_wan_gdm_dev(eth);
> +	if (wan_dev) {
> +		if ((wan_dev->flags & AIROHA_PRIV_F_QOS) ||
> +		    wan_dev->port->id == AIROHA_GDM2_IDX) {
> +			NL_SET_ERR_MSG_MOD(extack,
> +					   "QoS configured for WAN device");
> +			goto error_unlock;
> +		}
> +		airoha_disable_qos_for_gdm34(netdev_from_priv(wan_dev));
> +	}
> +
> +	dev->flags |= AIROHA_PRIV_F_WAN;
> +	airoha_dev_set_qdma(dev);
> +	err = airoha_enable_gdm2_loopback(dev);
> +	if (err)
> +		goto error_disable_wan;
> +
> +	err = airoha_set_macaddr(dev, netdev->dev_addr);
> +	if (err)
> +		goto error_disable_loopback;
> +
> +	if (netif_running(netdev)) {
> +		u32 pse_port;
> +
> +		pse_port = airoha_ppe_is_enabled(eth, 1) ? FE_PSE_PORT_PPE2
> +							 : FE_PSE_PORT_PPE1;
> +		airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id),
> +					    pse_port);
> +	}
> +
> +	mutex_unlock(&flow_offload_mutex);
> +
> +	return 0;
> +
> +error_disable_loopback:
> +	airoha_disable_gdm2_loopback(dev);
> +error_disable_wan:
> +	dev->flags &= ~AIROHA_PRIV_F_WAN;
> +	airoha_dev_set_qdma(dev);
> +error_unlock:
> +	mutex_unlock(&flow_offload_mutex);
> +
> +	return err;
> +}

- If airoha_set_macaddr() fails and we jump to error_disable_loopback,
  the original wan_dev was preemptively demoted to LAN mode, but the error
  path doesn't restore it.
  Since the requesting device is also rolled back to LAN, does this leave
  the system entirely without a WAN device? Would this permanently break
  routing on the original WAN interface until manually reconfigured?

  - If airoha_enable_qos_for_gdm34() fails, the system will continue routing
    packets and, even if we re-promote the original interface to WAN, the user
    will need to re-apply the same configuration to offload the intended
    Qdisc on the new interface.
    Moreover, please note this corner case occurs just if the original
    interface has no Qdisc already configured on it. In the common case, the
    user has previously removed the configured Qdisc on the original interface
    and so, the roll-back process will still be partial.
    In the end, airoha_set_macaddr() can fail just if the device is not
    well-configured.
    For the reasons above, I guess it does not worth to reset the original
    interface to WAN if airoha_set_macaddr() fails.

Regards,
Lorenzo

> +
>  static int airoha_tc_htb_destroy(struct net_device *netdev)
>  {
>  	struct airoha_gdm_dev *dev = netdev_priv(netdev);
> @@ -3038,6 +3205,8 @@ static int airoha_tc_htb_destroy(struct net_device *netdev)
>  	for_each_set_bit(q, dev->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS)
>  		airoha_tc_remove_htb_queue(netdev, q);
>  
> +	dev->flags &= ~AIROHA_PRIV_F_QOS;
> +
>  	return 0;
>  }
>  
> @@ -3057,24 +3226,33 @@ static int airoha_tc_get_htb_get_leaf_queue(struct net_device *netdev,
>  	return 0;
>  }
>  
> -static int airoha_tc_setup_qdisc_htb(struct net_device *dev,
> +static int airoha_tc_setup_qdisc_htb(struct net_device *netdev,
>  				     struct tc_htb_qopt_offload *opt)
>  {
>  	switch (opt->command) {
> -	case TC_HTB_CREATE:
> +	case TC_HTB_CREATE: {
> +		struct airoha_gdm_dev *dev = netdev_priv(netdev);
> +		int err;
> +
> +		err = airoha_enable_qos_for_gdm34(netdev, opt->extack);
> +		if (err)
> +			return err;
> +
> +		dev->flags |= AIROHA_PRIV_F_QOS;
>  		break;
> +	}
>  	case TC_HTB_DESTROY:
> -		return airoha_tc_htb_destroy(dev);
> +		return airoha_tc_htb_destroy(netdev);
>  	case TC_HTB_NODE_MODIFY:
> -		return airoha_tc_htb_modify_queue(dev, opt);
> +		return airoha_tc_htb_modify_queue(netdev, opt);
>  	case TC_HTB_LEAF_ALLOC_QUEUE:
> -		return airoha_tc_htb_alloc_leaf_queue(dev, opt);
> +		return airoha_tc_htb_alloc_leaf_queue(netdev, opt);
>  	case TC_HTB_LEAF_DEL:
>  	case TC_HTB_LEAF_DEL_LAST:
>  	case TC_HTB_LEAF_DEL_LAST_FORCE:
> -		return airoha_tc_htb_delete_leaf_queue(dev, opt);
> +		return airoha_tc_htb_delete_leaf_queue(netdev, opt);
>  	case TC_HTB_LEAF_QUERY_QUEUE:
> -		return airoha_tc_get_htb_get_leaf_queue(dev, opt);
> +		return airoha_tc_get_htb_get_leaf_queue(netdev, opt);
>  	default:
>  		return -EOPNOTSUPP;
>  	}
> diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
> index 24fd8dcf7fca..d1390ffcea7c 100644
> --- a/drivers/net/ethernet/airoha/airoha_eth.h
> +++ b/drivers/net/ethernet/airoha/airoha_eth.h
> @@ -540,11 +540,12 @@ struct airoha_qdma {
>  
>  enum airoha_priv_flags {
>  	AIROHA_PRIV_F_WAN = BIT(0),
> +	AIROHA_PRIV_F_QOS = BIT(1),
>  };
>  
>  struct airoha_gdm_dev {
> +	struct airoha_qdma __rcu *qdma;
>  	struct airoha_gdm_port *port;
> -	struct airoha_qdma *qdma;
>  	struct airoha_eth *eth;
>  
>  	DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
> @@ -676,6 +677,16 @@ int airoha_get_fe_port(struct airoha_gdm_dev *dev);
>  bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
>  			     struct airoha_gdm_dev *dev);
>  
> +extern struct mutex flow_offload_mutex;
> +
> +static inline struct airoha_qdma *
> +airoha_qdma_deref(struct airoha_gdm_dev *dev)
> +{
> +	return rcu_dereference_protected(dev->qdma,
> +					 lockdep_rtnl_is_held() ||
> +					 lockdep_is_held(&flow_offload_mutex));
> +}
> +
>  void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport);
>  bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index);
>  void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
> diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
> index 91bcc55a6ac6..1d1b1a57d795 100644
> --- a/drivers/net/ethernet/airoha/airoha_ppe.c
> +++ b/drivers/net/ethernet/airoha/airoha_ppe.c
> @@ -15,7 +15,10 @@
>  #include "airoha_regs.h"
>  #include "airoha_eth.h"
>  
> -static DEFINE_MUTEX(flow_offload_mutex);
> +/* Serialize airoha_gdm_dev flags, QDMA pointer and PPE CPU port
> + * configuration.
> + */
> +DEFINE_MUTEX(flow_offload_mutex);
>  static DEFINE_SPINLOCK(ppe_lock);
>  
>  static const struct rhashtable_params airoha_flow_table_params = {
> @@ -86,8 +89,8 @@ static u32 airoha_ppe_get_timestamp(struct airoha_ppe *ppe)
>  
>  void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport)
>  {
> -	struct airoha_qdma *qdma = dev->qdma;
> -	struct airoha_eth *eth = qdma->eth;
> +	struct airoha_qdma *qdma = airoha_qdma_deref(dev);
> +	struct airoha_eth *eth = dev->eth;
>  	u8 qdma_id = qdma - &eth->qdma[0];
>  	u32 fe_cpu_port;
>  
> diff --git a/drivers/net/ethernet/airoha/airoha_regs.h b/drivers/net/ethernet/airoha/airoha_regs.h
> index 436f3c8779c1..4e17dfbcf2b8 100644
> --- a/drivers/net/ethernet/airoha/airoha_regs.h
> +++ b/drivers/net/ethernet/airoha/airoha_regs.h
> @@ -376,6 +376,7 @@
>  
>  #define REG_SRC_PORT_FC_MAP6		0x2298
>  #define FC_ID_OF_SRC_PORT_MASK(_n)	GENMASK(4 + ((_n) << 3), ((_n) << 3))
> +#define FC_MAP6_DEF_VALUE		0x1b1a1918
>  
>  #define REG_CDM5_RX_OQ1_DROP_CNT	0x29d4
>  
> 
> -- 
> 2.54.0
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH net-next v8 00/10] enic: SR-IOV V2 admin channel and MBOX protocol
From: Paolo Abeni @ 2026-06-13  9:41 UTC (permalink / raw)
  To: Simon Horman, Satish Kharat
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	netdev, linux-kernel, Sesidhar Baddela, Breno Leitao
In-Reply-To: <20260612105224.GE625020@horms.kernel.org>

On 6/12/26 12:52 PM, Simon Horman wrote:
> On Tue, Jun 09, 2026 at 09:32:26AM -0700, Satish Kharat wrote:
>> This series adds the admin channel infrastructure and mailbox (MBOX)
>> protocol needed for V2 SR-IOV support in the enic driver.
>>
>> The V2 SR-IOV design uses a direct PF-VF communication channel built on
>> dedicated WQ/RQ/CQ hardware resources and an MSI-X interrupt.
>>
>> Firmware capability and admin channel infrastructure (patches 1-4):
>>   - Probe-time firmware feature check for V2 SR-IOV support
>>   - Admin channel open/close, RQ buffer management, CQ service
>>     with MSI-X interrupt and workqueue-based polling
>>
>> MBOX protocol and VF enable (patches 5-10):
>>   - MBOX message types, core send/receive, PF and VF handlers
>>   - V2 SR-IOV enable wiring with admin channel setup
>>   - V2 VF probe with admin channel and PF registration
>>
>> Signed-off-by: Satish Kharat <satishkh@cisco.com>
> 
> Hi Satish,
> 
> There is AI-generated review of this patch-set available on both
> https://sashiko.dev and https://netdev-ai.bots.linux.dev/sashiko/
> I would appreciate it if you could look over that with a view
> to addressing any issues that directly affect this patch.

At very least the scheduling while atomic issue in patch 9/10 reported
by both sashikos looks real and should be addressed.

/P


^ permalink raw reply

* Re: [PATCH v4] rust: make `build_assert` module the home of related macros
From: Miguel Ojeda @ 2026-06-13  9:49 UTC (permalink / raw)
  To: Gary Guo
  Cc: Miguel Ojeda, a.hindborg, acourbot, airlied, aliceryhl, bjorn3_gh,
	boqun, dakr, daniel.almeida, dri-devel, driver-core,
	fujita.tomonori, linux-kernel, longman, lossin, mark.rutland,
	mingo, netdev, nova-gpu, peterz, rust-for-linux, simona, tamird,
	tmgross, will, yury.norov
In-Reply-To: <DJ65HZ2867HB.2ZK56NEAURVJO@garyguo.net>

On Thu, Jun 11, 2026 at 1:50 PM Gary Guo <gary@garyguo.net> wrote:
>
> > Good first issue?
>
> Agreed.

For future reference:

  https://github.com/Rust-for-Linux/linux/issues/1242

Cheers,
Miguel

^ permalink raw reply

* Re: [PATCH net 0/3][pull request] Intel Wired LAN Driver Updates 2026-06-09 (idpf, ixgbe, igc)
From: Paolo Abeni @ 2026-06-13  9:49 UTC (permalink / raw)
  To: Simon Horman, Tony Nguyen; +Cc: davem, kuba, edumazet, andrew+netdev, netdev
In-Reply-To: <20260612120309.GA671640@horms.kernel.org>

On 6/12/26 2:03 PM, Simon Horman wrote:
> On Tue, Jun 09, 2026 at 10:24:53AM -0700, Tony Nguyen wrote:
>> Przemyslaw adds needed padding to idpf PTP structures to match firmware
>> expectations.
>>
>> Larysa bypasses XPS configuration on XDP queues for ixgbe.
>>
>> Khai Wen corrects offset into packet buffer when handling for frame
>> preemption on igc.
> 
> Hi Tony, Przemyslaw, and KhaiWenTan,
> 
> There is AI-generated review of this patch-set available on both
> https://sashiko.dev and https://netdev-ai.bots.linux.dev/sashiko/
> 
> I would appreciate it if you could look over the AI-generated review of
> patches 1 and 3.

Going over such comments looks like pre-existing issues or things better
handled as follow-up.

/P


^ permalink raw reply

* Re: [PATCH net-next v2 1/2] netdev: expose io_uring rx_page_order order via netlink
From: Pavel Begunkov @ 2026-06-13  9:53 UTC (permalink / raw)
  To: Dragos Tatulea, Donald Hunter, Jakub Kicinski, David S. Miller,
	Eric Dumazet, Paolo Abeni, Simon Horman, Andrew Lunn, Jens Axboe
  Cc: Yael Chemla, Tariq Toukan, netdev, linux-kernel, io-uring
In-Reply-To: <20260612211709.1456966-3-dtatulea@nvidia.com>

On 6/12/26 22:17, Dragos Tatulea wrote:
> This adds observability for the io_uring zcrx rx-buf-len configuration.

It might be nicer to look it up in the queue, e.g. rxq->mp_params,
and make it a queue attribute instead of zcrx specific one. In either
case, no objections.

Acked-by: Pavel Begunkov <asml.silence@gmail.com>

-- 
Pavel Begunkov


^ permalink raw reply

* Re: [PATCH net 0/3][pull request] Intel Wired LAN Driver Updates 2026-06-09 (idpf, ixgbe, igc)
From: patchwork-bot+netdevbpf @ 2026-06-13 10:00 UTC (permalink / raw)
  To: Tony Nguyen; +Cc: davem, kuba, pabeni, edumazet, andrew+netdev, netdev
In-Reply-To: <20260609172458.4046222-1-anthony.l.nguyen@intel.com>

Hello:

This series was applied to netdev/net.git (main)
by Tony Nguyen <anthony.l.nguyen@intel.com>:

On Tue,  9 Jun 2026 10:24:53 -0700 you wrote:
> Przemyslaw adds needed padding to idpf PTP structures to match firmware
> expectations.
> 
> Larysa bypasses XPS configuration on XDP queues for ixgbe.
> 
> Khai Wen corrects offset into packet buffer when handling for frame
> preemption on igc.
> 
> [...]

Here is the summary with links:
  - [net,1/3] idpf: add padding to PTP virtchnl structures
    https://git.kernel.org/netdev/net/c/d1e8f9fd6b98
  - [net,2/3] ixgbe: do not configure xps for XDP queues
    https://git.kernel.org/netdev/net/c/7bd4355272de
  - [net,3/3] igc: skip RX timestamp header for frame preemption verification
    https://git.kernel.org/netdev/net/c/38b7a274cf84

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox