* [net-next PATCH v5 1/4] octeontx2-af: npa: cn20k: Add NPA Halo support
From: Subbaraya Sundeep @ 2026-04-09 9:53 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, sgoutham, gakula,
bbhushan2
Cc: netdev, linux-kernel, Linu Cherian, Subbaraya Sundeep
In-Reply-To: <1775728404-28451-1-git-send-email-sbhatta@marvell.com>
From: Linu Cherian <lcherian@marvell.com>
CN20K silicon implements unified aura and pool context
type called Halo for better resource usage. Add support to
handle Halo context type operations.
Signed-off-by: Linu Cherian <lcherian@marvell.com>
Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
---
.../ethernet/marvell/octeontx2/af/cn20k/npa.c | 27 +++++++
.../marvell/octeontx2/af/cn20k/struct.h | 81 +++++++++++++++++++
.../net/ethernet/marvell/octeontx2/af/mbox.h | 6 ++
.../net/ethernet/marvell/octeontx2/af/rvu.h | 2 +
.../ethernet/marvell/octeontx2/af/rvu_npa.c | 63 +++++++++++++--
.../marvell/octeontx2/af/rvu_struct.h | 1 +
6 files changed, 173 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npa.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npa.c
index fe8f926c8b75..c963f43dc7b0 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npa.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npa.c
@@ -19,3 +19,30 @@ int rvu_mbox_handler_npa_cn20k_aq_enq(struct rvu *rvu,
(struct npa_aq_enq_rsp *)rsp);
}
EXPORT_SYMBOL(rvu_mbox_handler_npa_cn20k_aq_enq);
+
+int rvu_npa_halo_hwctx_disable(struct npa_aq_enq_req *req)
+{
+ struct npa_cn20k_aq_enq_req *hreq;
+
+ hreq = (struct npa_cn20k_aq_enq_req *)req;
+
+ hreq->halo.bp_ena_0 = 0;
+ hreq->halo.bp_ena_1 = 0;
+ hreq->halo.bp_ena_2 = 0;
+ hreq->halo.bp_ena_3 = 0;
+ hreq->halo.bp_ena_4 = 0;
+ hreq->halo.bp_ena_5 = 0;
+ hreq->halo.bp_ena_6 = 0;
+ hreq->halo.bp_ena_7 = 0;
+
+ hreq->halo_mask.bp_ena_0 = 1;
+ hreq->halo_mask.bp_ena_1 = 1;
+ hreq->halo_mask.bp_ena_2 = 1;
+ hreq->halo_mask.bp_ena_3 = 1;
+ hreq->halo_mask.bp_ena_4 = 1;
+ hreq->halo_mask.bp_ena_5 = 1;
+ hreq->halo_mask.bp_ena_6 = 1;
+ hreq->halo_mask.bp_ena_7 = 1;
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/struct.h b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/struct.h
index 763f6cabd7c2..2364bafd329d 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/struct.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/struct.h
@@ -377,4 +377,85 @@ struct npa_cn20k_pool_s {
static_assert(sizeof(struct npa_cn20k_pool_s) == NIX_MAX_CTX_SIZE);
+struct npa_cn20k_halo_s {
+ u64 stack_base : 64;
+ u64 ena : 1;
+ u64 nat_align : 1;
+ u64 reserved_66_67 : 2;
+ u64 stack_caching : 1;
+ u64 reserved_69_71 : 3;
+ u64 aura_drop_ena : 1;
+ u64 reserved_73_79 : 7;
+ u64 aura_drop : 8;
+ u64 buf_offset : 12;
+ u64 reserved_100_103 : 4;
+ u64 buf_size : 12;
+ u64 reserved_116_119 : 4;
+ u64 ref_cnt_prof : 3;
+ u64 reserved_123_127 : 5;
+ u64 stack_max_pages : 32;
+ u64 stack_pages : 32;
+ u64 bp_0 : 7;
+ u64 bp_1 : 7;
+ u64 bp_2 : 7;
+ u64 bp_3 : 7;
+ u64 bp_4 : 7;
+ u64 bp_5 : 7;
+ u64 bp_6 : 7;
+ u64 bp_7 : 7;
+ u64 bp_ena_0 : 1;
+ u64 bp_ena_1 : 1;
+ u64 bp_ena_2 : 1;
+ u64 bp_ena_3 : 1;
+ u64 bp_ena_4 : 1;
+ u64 bp_ena_5 : 1;
+ u64 bp_ena_6 : 1;
+ u64 bp_ena_7 : 1;
+ u64 stack_offset : 4;
+ u64 reserved_260_263 : 4;
+ u64 shift : 6;
+ u64 reserved_270_271 : 2;
+ u64 avg_level : 8;
+ u64 avg_con : 9;
+ u64 fc_ena : 1;
+ u64 fc_stype : 2;
+ u64 fc_hyst_bits : 4;
+ u64 fc_up_crossing : 1;
+ u64 reserved_297_299 : 3;
+ u64 update_time : 16;
+ u64 reserved_316_319 : 4;
+ u64 fc_addr : 64;
+ u64 ptr_start : 64;
+ u64 ptr_end : 64;
+ u64 bpid_0 : 12;
+ u64 reserved_524_535 : 12;
+ u64 err_int : 8;
+ u64 err_int_ena : 8;
+ u64 thresh_int : 1;
+ u64 thresh_int_ena : 1;
+ u64 thresh_up : 1;
+ u64 reserved_555 : 1;
+ u64 thresh_qint_idx : 7;
+ u64 reserved_563 : 1;
+ u64 err_qint_idx : 7;
+ u64 reserved_571_575 : 5;
+ u64 thresh : 36;
+ u64 reserved_612_615 : 4;
+ u64 fc_msh_dst : 11;
+ u64 reserved_627_630 : 4;
+ u64 op_dpc_ena : 1;
+ u64 op_dpc_set : 5;
+ u64 reserved_637_637 : 1;
+ u64 stream_ctx : 1;
+ u64 unified_ctx : 1;
+ u64 reserved_640_703 : 64;
+ u64 reserved_704_767 : 64;
+ u64 reserved_768_831 : 64;
+ u64 reserved_832_895 : 64;
+ u64 reserved_896_959 : 64;
+ u64 reserved_960_1023 : 64;
+};
+
+static_assert(sizeof(struct npa_cn20k_halo_s) == NIX_MAX_CTX_SIZE);
+
#endif
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
index dc42c81c0942..4a97bd93d882 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
@@ -884,6 +884,8 @@ struct npa_cn20k_aq_enq_req {
struct npa_cn20k_aura_s aura;
/* Valid when op == WRITE/INIT and ctype == POOL */
struct npa_cn20k_pool_s pool;
+ /* Valid when op == WRITE/INIT and ctype == HALO */
+ struct npa_cn20k_halo_s halo;
};
/* Mask data when op == WRITE (1=write, 0=don't write) */
union {
@@ -891,6 +893,8 @@ struct npa_cn20k_aq_enq_req {
struct npa_cn20k_aura_s aura_mask;
/* Valid when op == WRITE and ctype == POOL */
struct npa_cn20k_pool_s pool_mask;
+ /* Valid when op == WRITE/INIT and ctype == HALO */
+ struct npa_cn20k_halo_s halo_mask;
};
};
@@ -901,6 +905,8 @@ struct npa_cn20k_aq_enq_rsp {
struct npa_cn20k_aura_s aura;
/* Valid when op == READ and ctype == POOL */
struct npa_cn20k_pool_s pool;
+ /* Valid when op == READ and ctype == HALO */
+ struct npa_cn20k_halo_s halo;
};
};
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
index a466181cf908..36a71d32b894 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
@@ -261,6 +261,7 @@ struct rvu_pfvf {
struct qmem *pool_ctx;
struct qmem *npa_qints_ctx;
unsigned long *aura_bmap;
+ unsigned long *halo_bmap; /* Aura and Halo are mutually exclusive */
unsigned long *pool_bmap;
/* NIX contexts */
@@ -1008,6 +1009,7 @@ void rvu_npa_freemem(struct rvu *rvu);
void rvu_npa_lf_teardown(struct rvu *rvu, u16 pcifunc, int npalf);
int rvu_npa_aq_enq_inst(struct rvu *rvu, struct npa_aq_enq_req *req,
struct npa_aq_enq_rsp *rsp);
+int rvu_npa_halo_hwctx_disable(struct npa_aq_enq_req *req);
/* NIX APIs */
bool is_nixlf_attached(struct rvu *rvu, u16 pcifunc);
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npa.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npa.c
index e2a33e46b48a..809386c6bcba 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npa.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npa.c
@@ -12,6 +12,11 @@
#include "rvu_reg.h"
#include "rvu.h"
+static bool npa_ctype_invalid(struct rvu *rvu, int ctype)
+{
+ return !is_cn20k(rvu->pdev) && ctype == NPA_AQ_CTYPE_HALO;
+}
+
static int npa_aq_enqueue_wait(struct rvu *rvu, struct rvu_block *block,
struct npa_aq_inst_s *inst)
{
@@ -72,13 +77,19 @@ int rvu_npa_aq_enq_inst(struct rvu *rvu, struct npa_aq_enq_req *req,
bool ena;
pfvf = rvu_get_pfvf(rvu, pcifunc);
- if (!pfvf->aura_ctx || req->aura_id >= pfvf->aura_ctx->qsize)
+ if (!pfvf->aura_ctx || req->aura_id >= pfvf->aura_ctx->qsize ||
+ npa_ctype_invalid(rvu, req->ctype))
return NPA_AF_ERR_AQ_ENQUEUE;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, pcifunc);
if (!pfvf->npalf || blkaddr < 0)
return NPA_AF_ERR_AF_LF_INVALID;
+ /* Ensure halo bitmap is exclusive to halo ctype */
+ if (is_cn20k(rvu->pdev) && req->ctype != NPA_AQ_CTYPE_HALO &&
+ test_bit(req->aura_id, pfvf->halo_bmap))
+ return NPA_AF_ERR_AQ_ENQUEUE;
+
block = &hw->block[blkaddr];
aq = block->aq;
if (!aq) {
@@ -119,7 +130,7 @@ int rvu_npa_aq_enq_inst(struct rvu *rvu, struct npa_aq_enq_req *req,
memcpy(mask, &req->aura_mask,
sizeof(struct npa_aura_s));
memcpy(ctx, &req->aura, sizeof(struct npa_aura_s));
- } else {
+ } else { /* Applies to pool and halo since size is same */
memcpy(mask, &req->pool_mask,
sizeof(struct npa_pool_s));
memcpy(ctx, &req->pool, sizeof(struct npa_pool_s));
@@ -135,7 +146,7 @@ int rvu_npa_aq_enq_inst(struct rvu *rvu, struct npa_aq_enq_req *req,
req->aura.pool_addr = pfvf->pool_ctx->iova +
(req->aura.pool_addr * pfvf->pool_ctx->entry_sz);
memcpy(ctx, &req->aura, sizeof(struct npa_aura_s));
- } else { /* POOL's context */
+ } else { /* Applies to pool and halo since size is same */
memcpy(ctx, &req->pool, sizeof(struct npa_pool_s));
}
break;
@@ -176,6 +187,20 @@ int rvu_npa_aq_enq_inst(struct rvu *rvu, struct npa_aq_enq_req *req,
}
}
+ if (req->ctype == NPA_AQ_CTYPE_HALO) {
+ if (req->op == NPA_AQ_INSTOP_INIT && req->aura.ena)
+ __set_bit(req->aura_id, pfvf->halo_bmap);
+ if (req->op == NPA_AQ_INSTOP_WRITE) {
+ ena = (req->aura.ena & req->aura_mask.ena) |
+ (test_bit(req->aura_id, pfvf->halo_bmap) &
+ ~req->aura_mask.ena);
+ if (ena)
+ __set_bit(req->aura_id, pfvf->halo_bmap);
+ else
+ __clear_bit(req->aura_id, pfvf->halo_bmap);
+ }
+ }
+
/* Set pool bitmap if pool hw context is enabled */
if (req->ctype == NPA_AQ_CTYPE_POOL) {
if (req->op == NPA_AQ_INSTOP_INIT && req->pool.ena)
@@ -198,7 +223,7 @@ int rvu_npa_aq_enq_inst(struct rvu *rvu, struct npa_aq_enq_req *req,
if (req->ctype == NPA_AQ_CTYPE_AURA)
memcpy(&rsp->aura, ctx,
sizeof(struct npa_aura_s));
- else
+ else /* Applies to pool and halo since size is same */
memcpy(&rsp->pool, ctx,
sizeof(struct npa_pool_s));
}
@@ -210,12 +235,14 @@ int rvu_npa_aq_enq_inst(struct rvu *rvu, struct npa_aq_enq_req *req,
static int npa_lf_hwctx_disable(struct rvu *rvu, struct hwctx_disable_req *req)
{
struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
+ const char *context = "Unknown";
struct npa_aq_enq_req aq_req;
unsigned long *bmap;
int id, cnt = 0;
int err = 0, rc;
- if (!pfvf->pool_ctx || !pfvf->aura_ctx)
+ if (!pfvf->pool_ctx || !pfvf->aura_ctx ||
+ npa_ctype_invalid(rvu, req->ctype))
return NPA_AF_ERR_AQ_ENQUEUE;
memset(&aq_req, 0, sizeof(struct npa_aq_enq_req));
@@ -226,6 +253,7 @@ static int npa_lf_hwctx_disable(struct rvu *rvu, struct hwctx_disable_req *req)
aq_req.pool_mask.ena = 1;
cnt = pfvf->pool_ctx->qsize;
bmap = pfvf->pool_bmap;
+ context = "Pool";
} else if (req->ctype == NPA_AQ_CTYPE_AURA) {
aq_req.aura.ena = 0;
aq_req.aura_mask.ena = 1;
@@ -233,6 +261,14 @@ static int npa_lf_hwctx_disable(struct rvu *rvu, struct hwctx_disable_req *req)
aq_req.aura_mask.bp_ena = 1;
cnt = pfvf->aura_ctx->qsize;
bmap = pfvf->aura_bmap;
+ context = "Aura";
+ } else if (req->ctype == NPA_AQ_CTYPE_HALO) {
+ aq_req.aura.ena = 0;
+ aq_req.aura_mask.ena = 1;
+ rvu_npa_halo_hwctx_disable(&aq_req);
+ cnt = pfvf->aura_ctx->qsize;
+ bmap = pfvf->halo_bmap;
+ context = "Halo";
}
aq_req.ctype = req->ctype;
@@ -246,8 +282,7 @@ static int npa_lf_hwctx_disable(struct rvu *rvu, struct hwctx_disable_req *req)
if (rc) {
err = rc;
dev_err(rvu->dev, "Failed to disable %s:%d context\n",
- (req->ctype == NPA_AQ_CTYPE_AURA) ?
- "Aura" : "Pool", id);
+ context, id);
}
}
@@ -311,6 +346,9 @@ static void npa_ctx_free(struct rvu *rvu, struct rvu_pfvf *pfvf)
kfree(pfvf->aura_bmap);
pfvf->aura_bmap = NULL;
+ kfree(pfvf->halo_bmap);
+ pfvf->halo_bmap = NULL;
+
qmem_free(rvu->dev, pfvf->aura_ctx);
pfvf->aura_ctx = NULL;
@@ -374,6 +412,13 @@ int rvu_mbox_handler_npa_lf_alloc(struct rvu *rvu,
if (!pfvf->aura_bmap)
goto free_mem;
+ if (is_cn20k(rvu->pdev)) {
+ pfvf->halo_bmap = kcalloc(NPA_AURA_COUNT(req->aura_sz),
+ sizeof(long), GFP_KERNEL);
+ if (!pfvf->halo_bmap)
+ goto free_mem;
+ }
+
/* Alloc memory for pool HW contexts */
hwctx_size = 1UL << ((ctx_cfg >> 4) & 0xF);
err = qmem_alloc(rvu->dev, &pfvf->pool_ctx, req->nr_pools, hwctx_size);
@@ -562,6 +607,10 @@ void rvu_npa_lf_teardown(struct rvu *rvu, u16 pcifunc, int npalf)
ctx_req.ctype = NPA_AQ_CTYPE_AURA;
npa_lf_hwctx_disable(rvu, &ctx_req);
+ /* Disable all Halos */
+ ctx_req.ctype = NPA_AQ_CTYPE_HALO;
+ npa_lf_hwctx_disable(rvu, &ctx_req);
+
npa_ctx_free(rvu, pfvf);
}
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_struct.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu_struct.h
index 8e868f815de1..d37cf2cf0fee 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_struct.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_struct.h
@@ -130,6 +130,7 @@ enum npa_aq_comp {
enum npa_aq_ctype {
NPA_AQ_CTYPE_AURA = 0x0,
NPA_AQ_CTYPE_POOL = 0x1,
+ NPA_AQ_CTYPE_HALO = 0x2,
};
/* NPA admin queue instruction opcodes */
--
2.48.1
^ permalink raw reply related
* [net-next PATCH v5 2/4] octeontx2-af: npa: cn20k: Add DPC support
From: Subbaraya Sundeep @ 2026-04-09 9:53 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, sgoutham, gakula,
bbhushan2
Cc: netdev, linux-kernel, Linu Cherian, Subbaraya Sundeep
In-Reply-To: <1775728404-28451-1-git-send-email-sbhatta@marvell.com>
From: Linu Cherian <lcherian@marvell.com>
CN20k introduces 32 diagnostic and performance
counters that are shared across all NPA LFs.
Counters being shared, each PF driver need to request
for a counter with the required configuration to the AF,
so that a counter can be allocated and mapped to the
respective LF with the requested configuration.
Add new mbox messages, npa_dpc_alloc/free to handle this.
Also ensure all the LF to DPC counter mappings are cleared
at the time of LF free/teardown.
Signed-off-by: Linu Cherian <lcherian@marvell.com>
Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
---
.../ethernet/marvell/octeontx2/af/cn20k/api.h | 6 +
.../ethernet/marvell/octeontx2/af/cn20k/npa.c | 129 ++++++++++++++++++
.../ethernet/marvell/octeontx2/af/cn20k/reg.h | 7 +
.../net/ethernet/marvell/octeontx2/af/mbox.h | 19 +++
.../net/ethernet/marvell/octeontx2/af/rvu.h | 3 +
.../ethernet/marvell/octeontx2/af/rvu_npa.c | 14 +-
6 files changed, 177 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/api.h b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/api.h
index 4285b5d6a6a2..b13e7628f767 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/api.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/api.h
@@ -29,4 +29,10 @@ int cn20k_mbox_setup(struct otx2_mbox *mbox, struct pci_dev *pdev,
void *reg_base, int direction, int ndevs);
void cn20k_rvu_enable_afvf_intr(struct rvu *rvu, int vfs);
void cn20k_rvu_disable_afvf_intr(struct rvu *rvu, int vfs);
+
+int npa_cn20k_dpc_alloc(struct rvu *rvu, struct npa_cn20k_dpc_alloc_req *req,
+ struct npa_cn20k_dpc_alloc_rsp *rsp);
+int npa_cn20k_dpc_free(struct rvu *rvu, struct npa_cn20k_dpc_free_req *req);
+void npa_cn20k_dpc_free_all(struct rvu *rvu, u16 pcifunc);
+
#endif /* CN20K_API_H */
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npa.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npa.c
index c963f43dc7b0..24a710f4f5fc 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npa.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npa.c
@@ -8,6 +8,8 @@
#include <linux/module.h>
#include <linux/pci.h>
+#include "cn20k/api.h"
+#include "cn20k/reg.h"
#include "struct.h"
#include "../rvu.h"
@@ -46,3 +48,130 @@ int rvu_npa_halo_hwctx_disable(struct npa_aq_enq_req *req)
return 0;
}
+
+int npa_cn20k_dpc_alloc(struct rvu *rvu, struct npa_cn20k_dpc_alloc_req *req,
+ struct npa_cn20k_dpc_alloc_rsp *rsp)
+{
+ struct rvu_hwinfo *hw = rvu->hw;
+ u16 pcifunc = req->hdr.pcifunc;
+ int cntr, lf, blkaddr, ridx;
+ struct rvu_block *block;
+ struct rvu_pfvf *pfvf;
+ u64 val, lfmask;
+
+ pfvf = rvu_get_pfvf(rvu, pcifunc);
+
+ blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
+ if (!pfvf->npalf || blkaddr < 0)
+ return NPA_AF_ERR_AF_LF_INVALID;
+
+ block = &hw->block[blkaddr];
+ lf = rvu_get_lf(rvu, block, pcifunc, 0);
+ if (lf < 0)
+ return NPA_AF_ERR_AF_LF_INVALID;
+
+ mutex_lock(&rvu->rsrc_lock);
+
+ /* allocate a new counter */
+ cntr = rvu_alloc_rsrc(&rvu->npa_dpc);
+ if (cntr < 0) {
+ mutex_unlock(&rvu->rsrc_lock);
+ return cntr;
+ }
+
+ rsp->cntr_id = cntr;
+
+ /* DPC counter config */
+ rvu_write64(rvu, blkaddr, NPA_AF_DPCX_CFG(cntr), req->dpc_conf);
+
+ /* 0 to 63 lfs -> idx 0, 64 - 127 lfs -> idx 1 */
+ ridx = lf >> 6;
+ lfmask = BIT_ULL(ridx ? lf - NPA_DPC_LFS_PER_REG : lf);
+
+ ridx = 2 * cntr + ridx;
+ /* Give permission for LF access */
+ val = rvu_read64(rvu, blkaddr, NPA_AF_DPC_PERMITX(ridx));
+ val |= lfmask;
+ rvu_write64(rvu, blkaddr, NPA_AF_DPC_PERMITX(ridx), val);
+
+ mutex_unlock(&rvu->rsrc_lock);
+
+ return 0;
+}
+
+int rvu_mbox_handler_npa_cn20k_dpc_alloc(struct rvu *rvu,
+ struct npa_cn20k_dpc_alloc_req *req,
+ struct npa_cn20k_dpc_alloc_rsp *rsp)
+{
+ return npa_cn20k_dpc_alloc(rvu, req, rsp);
+}
+
+int npa_cn20k_dpc_free(struct rvu *rvu, struct npa_cn20k_dpc_free_req *req)
+{
+ struct rvu_hwinfo *hw = rvu->hw;
+ u16 pcifunc = req->hdr.pcifunc;
+ int cntr, lf, blkaddr, ridx;
+ struct rvu_block *block;
+ struct rvu_pfvf *pfvf;
+ u64 val, lfmask;
+
+ pfvf = rvu_get_pfvf(rvu, pcifunc);
+
+ blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
+ if (!pfvf->npalf || blkaddr < 0)
+ return NPA_AF_ERR_AF_LF_INVALID;
+
+ block = &hw->block[blkaddr];
+ lf = rvu_get_lf(rvu, block, pcifunc, 0);
+ if (lf < 0)
+ return NPA_AF_ERR_AF_LF_INVALID;
+
+ if (req->cntr_id >= NPA_DPC_MAX)
+ return NPA_AF_ERR_PARAM;
+
+ mutex_lock(&rvu->rsrc_lock);
+
+ /* 0 to 63 lfs -> idx 0, 64 - 127 lfs -> idx 1 */
+ ridx = lf >> 6;
+ lfmask = BIT_ULL(ridx ? lf - NPA_DPC_LFS_PER_REG : lf);
+ cntr = req->cntr_id;
+
+ ridx = 2 * cntr + ridx;
+
+ val = rvu_read64(rvu, blkaddr, NPA_AF_DPC_PERMITX(ridx));
+ /* Check if the counter is allotted to this LF */
+ if (!(val & lfmask)) {
+ mutex_unlock(&rvu->rsrc_lock);
+ return 0;
+ }
+
+ /* Revert permission */
+ val &= ~lfmask;
+ rvu_write64(rvu, blkaddr, NPA_AF_DPC_PERMITX(ridx), val);
+
+ /* Free this counter */
+ rvu_free_rsrc(&rvu->npa_dpc, req->cntr_id);
+
+ mutex_unlock(&rvu->rsrc_lock);
+
+ return 0;
+}
+
+void npa_cn20k_dpc_free_all(struct rvu *rvu, u16 pcifunc)
+{
+ struct npa_cn20k_dpc_free_req req;
+ int i;
+
+ req.hdr.pcifunc = pcifunc;
+ for (i = 0; i < NPA_DPC_MAX; i++) {
+ req.cntr_id = i;
+ npa_cn20k_dpc_free(rvu, &req);
+ }
+}
+
+int rvu_mbox_handler_npa_cn20k_dpc_free(struct rvu *rvu,
+ struct npa_cn20k_dpc_free_req *req,
+ struct msg_rsp *rsp)
+{
+ return npa_cn20k_dpc_free(rvu, req);
+}
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/reg.h b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/reg.h
index 8bfaa507ee50..9b49e376878e 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/reg.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/reg.h
@@ -143,4 +143,11 @@
offset = (0xb000000ull | (a) << 4 | (b) << 20); \
offset; })
+/* NPA Registers */
+#define NPA_AF_DPCX_CFG(a) (0x800 | (a) << 6)
+#define NPA_AF_DPC_PERMITX(a) (0x1000 | (a) << 3)
+
+#define NPA_DPC_MAX 32
+#define NPA_DPC_LFS_PER_REG 64
+
#endif /* RVU_MBOX_REG_H */
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
index 4a97bd93d882..b29ec26b66b7 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
@@ -213,6 +213,10 @@ M(NPA_AQ_ENQ, 0x402, npa_aq_enq, npa_aq_enq_req, npa_aq_enq_rsp) \
M(NPA_HWCTX_DISABLE, 0x403, npa_hwctx_disable, hwctx_disable_req, msg_rsp)\
M(NPA_CN20K_AQ_ENQ, 0x404, npa_cn20k_aq_enq, npa_cn20k_aq_enq_req, \
npa_cn20k_aq_enq_rsp) \
+M(NPA_CN20K_DPC_ALLOC, 0x405, npa_cn20k_dpc_alloc, npa_cn20k_dpc_alloc_req, \
+ npa_cn20k_dpc_alloc_rsp) \
+M(NPA_CN20K_DPC_FREE, 0x406, npa_cn20k_dpc_free, npa_cn20k_dpc_free_req, \
+ msg_rsp) \
/* SSO/SSOW mbox IDs (range 0x600 - 0x7FF) */ \
/* TIM mbox IDs (range 0x800 - 0x9FF) */ \
/* CPT mbox IDs (range 0xA00 - 0xBFF) */ \
@@ -910,6 +914,21 @@ struct npa_cn20k_aq_enq_rsp {
};
};
+struct npa_cn20k_dpc_alloc_req {
+ struct mbox_msghdr hdr;
+ u16 dpc_conf;
+};
+
+struct npa_cn20k_dpc_alloc_rsp {
+ struct mbox_msghdr hdr;
+ u8 cntr_id;
+};
+
+struct npa_cn20k_dpc_free_req {
+ struct mbox_msghdr hdr;
+ u8 cntr_id;
+};
+
/* Disable all contexts of type 'ctype' */
struct hwctx_disable_req {
struct mbox_msghdr hdr;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
index 36a71d32b894..0299fa1bd3bc 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
@@ -663,6 +663,9 @@ struct rvu {
/* CPT interrupt lock */
spinlock_t cpt_intr_lock;
+ /* NPA */
+ struct rsrc_bmap npa_dpc;
+
struct mutex mbox_lock; /* Serialize mbox up and down msgs */
u16 rep_pcifunc;
bool altaf_ready;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npa.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npa.c
index 809386c6bcba..f7916ac79c69 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npa.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npa.c
@@ -8,6 +8,8 @@
#include <linux/module.h>
#include <linux/pci.h>
+#include "cn20k/api.h"
+#include "cn20k/reg.h"
#include "rvu_struct.h"
#include "rvu_reg.h"
#include "rvu.h"
@@ -504,6 +506,8 @@ int rvu_mbox_handler_npa_lf_free(struct rvu *rvu, struct msg_req *req,
return NPA_AF_ERR_LF_RESET;
}
+ if (is_cn20k(rvu->pdev))
+ npa_cn20k_dpc_free_all(rvu, pcifunc);
npa_ctx_free(rvu, pfvf);
return 0;
@@ -569,12 +573,17 @@ static int npa_aq_init(struct rvu *rvu, struct rvu_block *block)
int rvu_npa_init(struct rvu *rvu)
{
struct rvu_hwinfo *hw = rvu->hw;
- int blkaddr;
+ int err, blkaddr;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
if (blkaddr < 0)
return 0;
+ rvu->npa_dpc.max = NPA_DPC_MAX;
+ err = rvu_alloc_bitmap(&rvu->npa_dpc);
+ if (err)
+ return err;
+
/* Initialize admin queue */
return npa_aq_init(rvu, &hw->block[blkaddr]);
}
@@ -591,6 +600,7 @@ void rvu_npa_freemem(struct rvu *rvu)
block = &hw->block[blkaddr];
rvu_aq_free(rvu, block->aq);
+ kfree(rvu->npa_dpc.bmap);
}
void rvu_npa_lf_teardown(struct rvu *rvu, u16 pcifunc, int npalf)
@@ -611,6 +621,8 @@ void rvu_npa_lf_teardown(struct rvu *rvu, u16 pcifunc, int npalf)
ctx_req.ctype = NPA_AQ_CTYPE_HALO;
npa_lf_hwctx_disable(rvu, &ctx_req);
+ if (is_cn20k(rvu->pdev))
+ npa_cn20k_dpc_free_all(rvu, pcifunc);
npa_ctx_free(rvu, pfvf);
}
--
2.48.1
^ permalink raw reply related
* [net-next PATCH v5 3/4] octeontx2-af: npa: cn20k: Add debugfs for Halo
From: Subbaraya Sundeep @ 2026-04-09 9:53 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, sgoutham, gakula,
bbhushan2
Cc: netdev, linux-kernel, Linu Cherian, Subbaraya Sundeep
In-Reply-To: <1775728404-28451-1-git-send-email-sbhatta@marvell.com>
From: Linu Cherian <lcherian@marvell.com>
Similar to other hardware contexts add debugfs support for
unified Halo context.
Sample output on cn20k::
/sys/kernel/debug/cn20k/npa # cat halo_ctx
======halo : 2=======
W0: Stack base ffffff790000
W1: ena 1
W1: nat_align 0
W1: stack_caching 1
W1: aura drop ena 0
W1: aura drop 0
W1: buf_offset 0
W1: buf_size 32
W1: ref_cnt_prof 0
W2: stack_max_pages 13
W2: stack_pages 11
W3: bp_0 0
W3: bp_1 0
W3: bp_2 0
snip ..
Signed-off-by: Linu Cherian <lcherian@marvell.com>
Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
---
.../marvell/octeontx2/af/cn20k/debugfs.c | 60 ++++++++++++++++
.../marvell/octeontx2/af/cn20k/debugfs.h | 2 +
.../marvell/octeontx2/af/rvu_debugfs.c | 71 ++++++++++++++++---
3 files changed, 125 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.c
index 3debf2fae1a4..c0cfd3a39c23 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.c
@@ -489,3 +489,63 @@ void print_npa_cn20k_pool_ctx(struct seq_file *m,
pool->thresh_qint_idx, pool->err_qint_idx);
seq_printf(m, "W8: fc_msh_dst\t\t%d\n", pool->fc_msh_dst);
}
+
+void print_npa_cn20k_halo_ctx(struct seq_file *m, struct npa_aq_enq_rsp *rsp)
+{
+ struct npa_cn20k_aq_enq_rsp *cn20k_rsp;
+ struct npa_cn20k_halo_s *halo;
+
+ cn20k_rsp = (struct npa_cn20k_aq_enq_rsp *)rsp;
+ halo = &cn20k_rsp->halo;
+
+ seq_printf(m, "W0: Stack base\t\t%llx\n", halo->stack_base);
+
+ seq_printf(m, "W1: ena \t\t%d\nW1: nat_align \t\t%d\n",
+ halo->ena, halo->nat_align);
+ seq_printf(m, "W1: stack_caching\t%d\n",
+ halo->stack_caching);
+ seq_printf(m, "W1: aura drop ena\t%d\n", halo->aura_drop_ena);
+ seq_printf(m, "W1: aura drop\t\t%d\n", halo->aura_drop);
+ seq_printf(m, "W1: buf_offset\t\t%d\nW1: buf_size\t\t%d\n",
+ halo->buf_offset, halo->buf_size);
+ seq_printf(m, "W1: ref_cnt_prof\t\t%d\n", halo->ref_cnt_prof);
+ seq_printf(m, "W2: stack_max_pages \t%d\nW2: stack_pages\t\t%d\n",
+ halo->stack_max_pages, halo->stack_pages);
+ seq_printf(m, "W3: bp_0\t\t%d\nW3: bp_1\t\t%d\nW3: bp_2\t\t%d\n",
+ halo->bp_0, halo->bp_1, halo->bp_2);
+ seq_printf(m, "W3: bp_3\t\t%d\nW3: bp_4\t\t%d\nW3: bp_5\t\t%d\n",
+ halo->bp_3, halo->bp_4, halo->bp_5);
+ seq_printf(m, "W3: bp_6\t\t%d\nW3: bp_7\t\t%d\nW3: bp_ena_0\t\t%d\n",
+ halo->bp_6, halo->bp_7, halo->bp_ena_0);
+ seq_printf(m, "W3: bp_ena_1\t\t%d\nW3: bp_ena_2\t\t%d\n",
+ halo->bp_ena_1, halo->bp_ena_2);
+ seq_printf(m, "W3: bp_ena_3\t\t%d\nW3: bp_ena_4\t\t%d\n",
+ halo->bp_ena_3, halo->bp_ena_4);
+ seq_printf(m, "W3: bp_ena_5\t\t%d\nW3: bp_ena_6\t\t%d\n",
+ halo->bp_ena_5, halo->bp_ena_6);
+ seq_printf(m, "W3: bp_ena_7\t\t%d\n", halo->bp_ena_7);
+ seq_printf(m, "W4: stack_offset\t%d\nW4: shift\t\t%d\nW4: avg_level\t\t%d\n",
+ halo->stack_offset, halo->shift, halo->avg_level);
+ seq_printf(m, "W4: avg_con \t\t%d\nW4: fc_ena\t\t%d\nW4: fc_stype\t\t%d\n",
+ halo->avg_con, halo->fc_ena, halo->fc_stype);
+ seq_printf(m, "W4: fc_hyst_bits\t%d\nW4: fc_up_crossing\t%d\n",
+ halo->fc_hyst_bits, halo->fc_up_crossing);
+ seq_printf(m, "W4: update_time\t\t%d\n", halo->update_time);
+ seq_printf(m, "W5: fc_addr\t\t%llx\n", halo->fc_addr);
+ seq_printf(m, "W6: ptr_start\t\t%llx\n", halo->ptr_start);
+ seq_printf(m, "W7: ptr_end\t\t%llx\n", halo->ptr_end);
+ seq_printf(m, "W8: bpid_0\t\t%d\n", halo->bpid_0);
+ seq_printf(m, "W8: err_int \t\t%d\nW8: err_int_ena\t\t%d\n",
+ halo->err_int, halo->err_int_ena);
+ seq_printf(m, "W8: thresh_int\t\t%d\nW8: thresh_int_ena \t%d\n",
+ halo->thresh_int, halo->thresh_int_ena);
+ seq_printf(m, "W8: thresh_up\t\t%d\nW8: thresh_qint_idx\t%d\n",
+ halo->thresh_up, halo->thresh_qint_idx);
+ seq_printf(m, "W8: err_qint_idx \t%d\n", halo->err_qint_idx);
+ seq_printf(m, "W9: thresh\t\t%llu\n", (u64)halo->thresh);
+ seq_printf(m, "W9: fc_msh_dst\t\t%d\n", halo->fc_msh_dst);
+ seq_printf(m, "W9: op_dpc_ena\t\t%d\nW9: op_dpc_set\t\t%d\n",
+ halo->op_dpc_ena, halo->op_dpc_set);
+ seq_printf(m, "W9: stream_ctx\t\t%d\nW9: unified_ctx\t\t%d\n",
+ halo->stream_ctx, halo->unified_ctx);
+}
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.h b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.h
index 0c5f05883666..7e00c7499e35 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/debugfs.h
@@ -27,5 +27,7 @@ void print_npa_cn20k_aura_ctx(struct seq_file *m,
struct npa_cn20k_aq_enq_rsp *rsp);
void print_npa_cn20k_pool_ctx(struct seq_file *m,
struct npa_cn20k_aq_enq_rsp *rsp);
+void print_npa_cn20k_halo_ctx(struct seq_file *m,
+ struct npa_aq_enq_rsp *rsp);
#endif
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
index fa461489acdd..0ac59103b4a4 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
@@ -968,6 +968,9 @@ static void print_npa_qsize(struct seq_file *m, struct rvu_pfvf *pfvf)
seq_printf(m, "Aura count : %d\n", pfvf->aura_ctx->qsize);
seq_printf(m, "Aura context ena/dis bitmap : %*pb\n",
pfvf->aura_ctx->qsize, pfvf->aura_bmap);
+ if (pfvf->halo_bmap)
+ seq_printf(m, "Halo context ena/dis bitmap : %*pb\n",
+ pfvf->aura_ctx->qsize, pfvf->halo_bmap);
}
if (!pfvf->pool_ctx) {
@@ -1195,6 +1198,20 @@ static void print_npa_pool_ctx(struct seq_file *m, struct npa_aq_enq_rsp *rsp)
seq_printf(m, "W8: fc_msh_dst\t\t%d\n", pool->fc_msh_dst);
}
+static const char *npa_ctype_str(int ctype)
+{
+ switch (ctype) {
+ case NPA_AQ_CTYPE_AURA:
+ return "aura";
+ case NPA_AQ_CTYPE_HALO:
+ return "halo";
+ case NPA_AQ_CTYPE_POOL:
+ return "pool";
+ default:
+ return "unknown";
+ }
+}
+
/* Reads aura/pool's ctx from admin queue */
static int rvu_dbg_npa_ctx_display(struct seq_file *m, void *unused, int ctype)
{
@@ -1211,6 +1228,7 @@ static int rvu_dbg_npa_ctx_display(struct seq_file *m, void *unused, int ctype)
switch (ctype) {
case NPA_AQ_CTYPE_AURA:
+ case NPA_AQ_CTYPE_HALO:
npalf = rvu->rvu_dbg.npa_aura_ctx.lf;
id = rvu->rvu_dbg.npa_aura_ctx.id;
all = rvu->rvu_dbg.npa_aura_ctx.all;
@@ -1235,6 +1253,9 @@ static int rvu_dbg_npa_ctx_display(struct seq_file *m, void *unused, int ctype)
} else if (ctype == NPA_AQ_CTYPE_POOL && !pfvf->pool_ctx) {
seq_puts(m, "Pool context is not initialized\n");
return -EINVAL;
+ } else if (ctype == NPA_AQ_CTYPE_HALO && !pfvf->aura_ctx) {
+ seq_puts(m, "Halo context is not initialized\n");
+ return -EINVAL;
}
memset(&aq_req, 0, sizeof(struct npa_aq_enq_req));
@@ -1244,6 +1265,9 @@ static int rvu_dbg_npa_ctx_display(struct seq_file *m, void *unused, int ctype)
if (ctype == NPA_AQ_CTYPE_AURA) {
max_id = pfvf->aura_ctx->qsize;
print_npa_ctx = print_npa_aura_ctx;
+ } else if (ctype == NPA_AQ_CTYPE_HALO) {
+ max_id = pfvf->aura_ctx->qsize;
+ print_npa_ctx = print_npa_cn20k_halo_ctx;
} else {
max_id = pfvf->pool_ctx->qsize;
print_npa_ctx = print_npa_pool_ctx;
@@ -1251,8 +1275,7 @@ static int rvu_dbg_npa_ctx_display(struct seq_file *m, void *unused, int ctype)
if (id < 0 || id >= max_id) {
seq_printf(m, "Invalid %s, valid range is 0-%d\n",
- (ctype == NPA_AQ_CTYPE_AURA) ? "aura" : "pool",
- max_id - 1);
+ npa_ctype_str(ctype), max_id - 1);
return -EINVAL;
}
@@ -1265,12 +1288,19 @@ static int rvu_dbg_npa_ctx_display(struct seq_file *m, void *unused, int ctype)
aq_req.aura_id = aura;
/* Skip if queue is uninitialized */
+ if (ctype == NPA_AQ_CTYPE_AURA &&
+ !test_bit(aura, pfvf->aura_bmap))
+ continue;
+
+ if (ctype == NPA_AQ_CTYPE_HALO &&
+ !test_bit(aura, pfvf->halo_bmap))
+ continue;
+
if (ctype == NPA_AQ_CTYPE_POOL && !test_bit(aura, pfvf->pool_bmap))
continue;
- seq_printf(m, "======%s : %d=======\n",
- (ctype == NPA_AQ_CTYPE_AURA) ? "AURA" : "POOL",
- aq_req.aura_id);
+ seq_printf(m, "======%s : %d=======\n", npa_ctype_str(ctype),
+ aq_req.aura_id);
rc = rvu_npa_aq_enq_inst(rvu, &aq_req, &rsp);
if (rc) {
seq_puts(m, "Failed to read context\n");
@@ -1299,6 +1329,12 @@ static int write_npa_ctx(struct rvu *rvu, bool all,
return -EINVAL;
}
max_id = pfvf->aura_ctx->qsize;
+ } else if (ctype == NPA_AQ_CTYPE_HALO) {
+ if (!pfvf->aura_ctx) {
+ dev_warn(rvu->dev, "Halo context is not initialized\n");
+ return -EINVAL;
+ }
+ max_id = pfvf->aura_ctx->qsize;
} else if (ctype == NPA_AQ_CTYPE_POOL) {
if (!pfvf->pool_ctx) {
dev_warn(rvu->dev, "Pool context is not initialized\n");
@@ -1309,13 +1345,14 @@ static int write_npa_ctx(struct rvu *rvu, bool all,
if (id < 0 || id >= max_id) {
dev_warn(rvu->dev, "Invalid %s, valid range is 0-%d\n",
- (ctype == NPA_AQ_CTYPE_AURA) ? "aura" : "pool",
+ npa_ctype_str(ctype),
max_id - 1);
return -EINVAL;
}
switch (ctype) {
case NPA_AQ_CTYPE_AURA:
+ case NPA_AQ_CTYPE_HALO:
rvu->rvu_dbg.npa_aura_ctx.lf = npalf;
rvu->rvu_dbg.npa_aura_ctx.id = id;
rvu->rvu_dbg.npa_aura_ctx.all = all;
@@ -1374,12 +1411,12 @@ static ssize_t rvu_dbg_npa_ctx_write(struct file *filp,
const char __user *buffer,
size_t count, loff_t *ppos, int ctype)
{
- char *cmd_buf, *ctype_string = (ctype == NPA_AQ_CTYPE_AURA) ?
- "aura" : "pool";
+ const char *ctype_string = npa_ctype_str(ctype);
struct seq_file *seqfp = filp->private_data;
struct rvu *rvu = seqfp->private;
int npalf, id = 0, ret;
bool all = false;
+ char *cmd_buf;
if ((*ppos != 0) || !count)
return -EINVAL;
@@ -1417,6 +1454,21 @@ static int rvu_dbg_npa_aura_ctx_display(struct seq_file *filp, void *unused)
RVU_DEBUG_SEQ_FOPS(npa_aura_ctx, npa_aura_ctx_display, npa_aura_ctx_write);
+static ssize_t rvu_dbg_npa_halo_ctx_write(struct file *filp,
+ const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ return rvu_dbg_npa_ctx_write(filp, buffer, count, ppos,
+ NPA_AQ_CTYPE_HALO);
+}
+
+static int rvu_dbg_npa_halo_ctx_display(struct seq_file *filp, void *unused)
+{
+ return rvu_dbg_npa_ctx_display(filp, unused, NPA_AQ_CTYPE_HALO);
+}
+
+RVU_DEBUG_SEQ_FOPS(npa_halo_ctx, npa_halo_ctx_display, npa_halo_ctx_write);
+
static ssize_t rvu_dbg_npa_pool_ctx_write(struct file *filp,
const char __user *buffer,
size_t count, loff_t *ppos)
@@ -2798,6 +2850,9 @@ static void rvu_dbg_npa_init(struct rvu *rvu)
&rvu_dbg_npa_qsize_fops);
debugfs_create_file("aura_ctx", 0600, rvu->rvu_dbg.npa, rvu,
&rvu_dbg_npa_aura_ctx_fops);
+ if (is_cn20k(rvu->pdev))
+ debugfs_create_file("halo_ctx", 0600, rvu->rvu_dbg.npa, rvu,
+ &rvu_dbg_npa_halo_ctx_fops);
debugfs_create_file("pool_ctx", 0600, rvu->rvu_dbg.npa, rvu,
&rvu_dbg_npa_pool_ctx_fops);
--
2.48.1
^ permalink raw reply related
* [net-next PATCH v5 4/4] octeontx2-pf: cn20k: Use unified Halo context
From: Subbaraya Sundeep @ 2026-04-09 9:53 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, sgoutham, gakula,
bbhushan2
Cc: netdev, linux-kernel, Subbaraya Sundeep
In-Reply-To: <1775728404-28451-1-git-send-email-sbhatta@marvell.com>
Use unified Halo context present in CN20K hardware for
octeontx2 netdevs instead of aura and pool contexts.
Note that with this halo context in place RQ backpressure
is not being configured and the same will be supported
later.
Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
---
.../ethernet/marvell/octeontx2/nic/cn20k.c | 215 +++++++++---------
.../ethernet/marvell/octeontx2/nic/cn20k.h | 3 +
.../marvell/octeontx2/nic/otx2_common.h | 3 +
.../ethernet/marvell/octeontx2/nic/otx2_pf.c | 8 +
4 files changed, 126 insertions(+), 103 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn20k.c b/drivers/net/ethernet/marvell/octeontx2/nic/cn20k.c
index a5a8f4558717..f513e9ffc2dd 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/cn20k.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn20k.c
@@ -242,15 +242,6 @@ int cn20k_register_pfvf_mbox_intr(struct otx2_nic *pf, int numvfs)
#define RQ_BP_LVL_AURA (255 - ((85 * 256) / 100)) /* BP when 85% is full */
-static u8 cn20k_aura_bpid_idx(struct otx2_nic *pfvf, int aura_id)
-{
-#ifdef CONFIG_DCB
- return pfvf->queue_to_pfc_map[aura_id];
-#else
- return 0;
-#endif
-}
-
static int cn20k_tc_get_entry_index(struct otx2_flow_config *flow_cfg,
struct otx2_tc_flow *node)
{
@@ -517,84 +508,7 @@ int cn20k_tc_alloc_entry(struct otx2_nic *nic,
return 0;
}
-static int cn20k_aura_aq_init(struct otx2_nic *pfvf, int aura_id,
- int pool_id, int numptrs)
-{
- struct npa_cn20k_aq_enq_req *aq;
- struct otx2_pool *pool;
- u8 bpid_idx;
- int err;
-
- pool = &pfvf->qset.pool[pool_id];
-
- /* Allocate memory for HW to update Aura count.
- * Alloc one cache line, so that it fits all FC_STYPE modes.
- */
- if (!pool->fc_addr) {
- err = qmem_alloc(pfvf->dev, &pool->fc_addr, 1, OTX2_ALIGN);
- if (err)
- return err;
- }
-
- /* Initialize this aura's context via AF */
- aq = otx2_mbox_alloc_msg_npa_cn20k_aq_enq(&pfvf->mbox);
- if (!aq) {
- /* Shared mbox memory buffer is full, flush it and retry */
- err = otx2_sync_mbox_msg(&pfvf->mbox);
- if (err)
- return err;
- aq = otx2_mbox_alloc_msg_npa_cn20k_aq_enq(&pfvf->mbox);
- if (!aq)
- return -ENOMEM;
- }
-
- aq->aura_id = aura_id;
-
- /* Will be filled by AF with correct pool context address */
- aq->aura.pool_addr = pool_id;
- aq->aura.pool_caching = 1;
- aq->aura.shift = ilog2(numptrs) - 8;
- aq->aura.count = numptrs;
- aq->aura.limit = numptrs;
- aq->aura.avg_level = 255;
- aq->aura.ena = 1;
- aq->aura.fc_ena = 1;
- aq->aura.fc_addr = pool->fc_addr->iova;
- aq->aura.fc_hyst_bits = 0; /* Store count on all updates */
-
- /* Enable backpressure for RQ aura */
- if (aura_id < pfvf->hw.rqpool_cnt && !is_otx2_lbkvf(pfvf->pdev)) {
- aq->aura.bp_ena = 0;
- /* If NIX1 LF is attached then specify NIX1_RX.
- *
- * Below NPA_AURA_S[BP_ENA] is set according to the
- * NPA_BPINTF_E enumeration given as:
- * 0x0 + a*0x1 where 'a' is 0 for NIX0_RX and 1 for NIX1_RX so
- * NIX0_RX is 0x0 + 0*0x1 = 0
- * NIX1_RX is 0x0 + 1*0x1 = 1
- * But in HRM it is given that
- * "NPA_AURA_S[BP_ENA](w1[33:32]) - Enable aura backpressure to
- * NIX-RX based on [BP] level. One bit per NIX-RX; index
- * enumerated by NPA_BPINTF_E."
- */
- if (pfvf->nix_blkaddr == BLKADDR_NIX1)
- aq->aura.bp_ena = 1;
-
- bpid_idx = cn20k_aura_bpid_idx(pfvf, aura_id);
- aq->aura.bpid = pfvf->bpid[bpid_idx];
-
- /* Set backpressure level for RQ's Aura */
- aq->aura.bp = RQ_BP_LVL_AURA;
- }
-
- /* Fill AQ info */
- aq->ctype = NPA_AQ_CTYPE_AURA;
- aq->op = NPA_AQ_INSTOP_INIT;
-
- return 0;
-}
-
-static int cn20k_pool_aq_init(struct otx2_nic *pfvf, u16 pool_id,
+static int cn20k_halo_aq_init(struct otx2_nic *pfvf, u16 pool_id,
int stack_pages, int numptrs, int buf_size,
int type)
{
@@ -610,36 +524,57 @@ static int cn20k_pool_aq_init(struct otx2_nic *pfvf, u16 pool_id,
if (err)
return err;
+ /* Allocate memory for HW to update Aura count.
+ * Alloc one cache line, so that it fits all FC_STYPE modes.
+ */
+ if (!pool->fc_addr) {
+ err = qmem_alloc(pfvf->dev, &pool->fc_addr, 1, OTX2_ALIGN);
+ if (err) {
+ qmem_free(pfvf->dev, pool->stack);
+ return err;
+ }
+ }
+
pool->rbsize = buf_size;
- /* Initialize this pool's context via AF */
+ /* Initialize this aura's context via AF */
aq = otx2_mbox_alloc_msg_npa_cn20k_aq_enq(&pfvf->mbox);
if (!aq) {
/* Shared mbox memory buffer is full, flush it and retry */
err = otx2_sync_mbox_msg(&pfvf->mbox);
- if (err) {
- qmem_free(pfvf->dev, pool->stack);
- return err;
- }
+ if (err)
+ goto free_mem;
aq = otx2_mbox_alloc_msg_npa_cn20k_aq_enq(&pfvf->mbox);
if (!aq) {
- qmem_free(pfvf->dev, pool->stack);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto free_mem;
}
}
aq->aura_id = pool_id;
- aq->pool.stack_base = pool->stack->iova;
- aq->pool.stack_caching = 1;
- aq->pool.ena = 1;
- aq->pool.buf_size = buf_size / 128;
- aq->pool.stack_max_pages = stack_pages;
- aq->pool.shift = ilog2(numptrs) - 8;
- aq->pool.ptr_start = 0;
- aq->pool.ptr_end = ~0ULL;
+
+ aq->halo.stack_base = pool->stack->iova;
+ aq->halo.stack_caching = 1;
+ aq->halo.ena = 1;
+ aq->halo.buf_size = buf_size / 128;
+ aq->halo.stack_max_pages = stack_pages;
+ aq->halo.shift = ilog2(numptrs) - 8;
+ aq->halo.ptr_start = 0;
+ aq->halo.ptr_end = ~0ULL;
+
+ aq->halo.avg_level = 255;
+ aq->halo.fc_ena = 1;
+ aq->halo.fc_addr = pool->fc_addr->iova;
+ aq->halo.fc_hyst_bits = 0; /* Store count on all updates */
+
+ if (pfvf->npa_dpc_valid) {
+ aq->halo.op_dpc_ena = 1;
+ aq->halo.op_dpc_set = pfvf->npa_dpc;
+ }
+ aq->halo.unified_ctx = 1;
/* Fill AQ info */
- aq->ctype = NPA_AQ_CTYPE_POOL;
+ aq->ctype = NPA_AQ_CTYPE_HALO;
aq->op = NPA_AQ_INSTOP_INIT;
if (type != AURA_NIX_RQ) {
@@ -661,6 +596,80 @@ static int cn20k_pool_aq_init(struct otx2_nic *pfvf, u16 pool_id,
}
return 0;
+
+free_mem:
+ qmem_free(pfvf->dev, pool->stack);
+ qmem_free(pfvf->dev, pool->fc_addr);
+ return err;
+}
+
+static int cn20k_aura_aq_init(struct otx2_nic *pfvf, int aura_id,
+ int pool_id, int numptrs)
+{
+ return 0;
+}
+
+static int cn20k_pool_aq_init(struct otx2_nic *pfvf, u16 pool_id,
+ int stack_pages, int numptrs, int buf_size,
+ int type)
+{
+ return cn20k_halo_aq_init(pfvf, pool_id, stack_pages,
+ numptrs, buf_size, type);
+}
+
+int cn20k_npa_alloc_dpc(struct otx2_nic *nic)
+{
+ struct npa_cn20k_dpc_alloc_req *req;
+ struct npa_cn20k_dpc_alloc_rsp *rsp;
+ int err;
+
+ req = otx2_mbox_alloc_msg_npa_cn20k_dpc_alloc(&nic->mbox);
+ if (!req)
+ return -ENOMEM;
+
+ /* Count successful ALLOC requests only */
+ req->dpc_conf = 1ULL << 4;
+
+ err = otx2_sync_mbox_msg(&nic->mbox);
+ if (err)
+ return err;
+
+ rsp = (struct npa_cn20k_dpc_alloc_rsp *)otx2_mbox_get_rsp(&nic->mbox.mbox,
+ 0, &req->hdr);
+ if (IS_ERR(rsp))
+ return PTR_ERR(rsp);
+
+ nic->npa_dpc = rsp->cntr_id;
+ nic->npa_dpc_valid = true;
+
+ return 0;
+}
+
+int cn20k_npa_free_dpc(struct otx2_nic *nic)
+{
+ struct npa_cn20k_dpc_free_req *req;
+ int err;
+
+ if (!nic->npa_dpc_valid)
+ return 0;
+
+ mutex_lock(&nic->mbox.lock);
+
+ req = otx2_mbox_alloc_msg_npa_cn20k_dpc_free(&nic->mbox);
+ if (!req) {
+ mutex_unlock(&nic->mbox.lock);
+ return -ENOMEM;
+ }
+
+ req->cntr_id = nic->npa_dpc;
+
+ err = otx2_sync_mbox_msg(&nic->mbox);
+
+ nic->npa_dpc_valid = false;
+
+ mutex_unlock(&nic->mbox.lock);
+
+ return err;
}
static int cn20k_sq_aq_init(void *dev, u16 qidx, u8 chan_offset, u16 sqb_aura)
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn20k.h b/drivers/net/ethernet/marvell/octeontx2/nic/cn20k.h
index b5e527f6d7eb..16a69d84ea79 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/cn20k.h
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn20k.h
@@ -28,4 +28,7 @@ int cn20k_tc_alloc_entry(struct otx2_nic *nic,
struct otx2_tc_flow *new_node,
struct npc_install_flow_req *dummy);
int cn20k_tc_free_mcam_entry(struct otx2_nic *nic, u16 entry);
+int cn20k_npa_alloc_dpc(struct otx2_nic *nic);
+int cn20k_npa_free_dpc(struct otx2_nic *nic);
+
#endif /* CN20K_H */
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
index eecee612b7b2..f997dfc0fedd 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
@@ -592,6 +592,9 @@ struct otx2_nic {
struct cn10k_ipsec ipsec;
/* af_xdp zero-copy */
unsigned long *af_xdp_zc_qidx;
+
+ bool npa_dpc_valid;
+ u8 npa_dpc; /* NPA DPC counter id */
};
static inline bool is_otx2_lbkvf(struct pci_dev *pdev)
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
index ee623476e5ff..2b5fe67d297c 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
@@ -1651,6 +1651,9 @@ int otx2_init_hw_resources(struct otx2_nic *pf)
if (!is_otx2_lbkvf(pf->pdev))
otx2_nix_config_bp(pf, true);
+ if (is_cn20k(pf->pdev))
+ cn20k_npa_alloc_dpc(pf);
+
/* Init Auras and pools used by NIX RQ, for free buffer ptrs */
err = otx2_rq_aura_pool_init(pf);
if (err) {
@@ -1726,6 +1729,8 @@ int otx2_init_hw_resources(struct otx2_nic *pf)
otx2_ctx_disable(mbox, NPA_AQ_CTYPE_AURA, true);
otx2_aura_pool_free(pf);
err_free_nix_lf:
+ if (pf->npa_dpc_valid)
+ cn20k_npa_free_dpc(pf);
mutex_lock(&mbox->lock);
free_req = otx2_mbox_alloc_msg_nix_lf_free(mbox);
if (free_req) {
@@ -1790,6 +1795,9 @@ void otx2_free_hw_resources(struct otx2_nic *pf)
otx2_free_sq_res(pf);
+ if (is_cn20k(pf->pdev))
+ cn20k_npa_free_dpc(pf);
+
/* Free RQ buffer pointers*/
otx2_free_aura_ptr(pf, AURA_NIX_RQ);
--
2.48.1
^ permalink raw reply related
* RE: [net-next,v3,01/13] net: renesas: rswitch: improve port change mode functions
From: Michael Dege @ 2026-04-09 9:55 UTC (permalink / raw)
To: Paolo Abeni
Cc: paul@pbarker.dev, niklas.soderlund, kuba@kernel.org,
Yoshihiro Shimoda, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, edumazet@google.com,
linux-renesas-soc@vger.kernel.org, andrew+netdev@lunn.ch,
davem@davemloft.net
In-Reply-To: <20260402125912.234434-1-pabeni@redhat.com>
Hello Paolo,
Thank you for your review.
> -----Original Message-----
> From: Paolo Abeni <pabeni@redhat.com>
> Sent: Thursday, April 2, 2026 2:59 PM
> To: Michael Dege <michael.dege@renesas.com>
> Cc: paul@pbarker.dev; niklas.soderlund <niklas.soderlund@ragnatech.se>; kuba@kernel.org; Yoshihiro
> Shimoda <yoshihiro.shimoda.uh@renesas.com>; netdev@vger.kernel.org; linux-kernel@vger.kernel.org;
> edumazet@google.com; pabeni@redhat.com; linux-renesas-soc@vger.kernel.org; andrew+netdev@lunn.ch;
> davem@davemloft.net
> Subject: Re: [net-next,v3,01/13] net: renesas: rswitch: improve port change mode functions
>
> This is an AI-generated review of your patch. The human sending this email has considered the AI
> review valid, or at least plausible.
>
> For local reproduction steps see
> https://netdev-ai.bots.linux.dev/ai-
> local.html&data=05%7C02%7Cmichael.dege%40renesas.com%7C4f84d222a25841bd46eb08de90b7abdd%7C53d82571da19
> 47e49cb4625a166a4a2a%7C0%7C0%7C639107315837152138%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYi
> OiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=DbF%2FVyoOLfJSYrnI
> ceiszOHcbvGrEtenm%2Fk%2Fah%2FIrys%3D&reserved=0
> ---
> net: renesas: rswitch: improve port change mode functions
>
> For ETHA and GWCA ports every mode change from operational to configuration and vice-versa requires to
> change the mode to "disable"
> first. This was done by calling the function twice. Let the change_mode function take care of this
> required step in a single call.
>
> > diff --git a/drivers/net/ethernet/renesas/rswitch_main.c
> > b/drivers/net/ethernet/renesas/rswitch_main.c
> > index 6fe964816322..f6d1e610e7fa 100644
> > --- a/drivers/net/ethernet/renesas/rswitch_main.c
> > +++ b/drivers/net/ethernet/renesas/rswitch_main.c
> > @@ -176,14 +176,19 @@ static int rswitch_gwca_change_mode(struct rswitch_private *priv,
> > if (!rswitch_agent_clock_is_enabled(priv->addr, priv->gwca.index))
> > rswitch_agent_clock_ctrl(priv->addr, priv->gwca.index, 1);
> >
> > - iowrite32(mode, priv->addr + GWMC);
> > + iowrite32(GWMC_OPC_DISABLE, priv->addr + GWMC);
> >
> > - ret = rswitch_reg_wait(priv->addr, GWMS, GWMS_OPS_MASK, mode);
> > + ret = rswitch_reg_wait(priv->addr, GWMS, GWMS_OPS_MASK,
> > +GWMC_OPC_DISABLE);
> >
> > - if (mode == GWMC_OPC_DISABLE)
> > + if (mode == GWMC_OPC_DISABLE) {
> > rswitch_agent_clock_ctrl(priv->addr, priv->gwca.index, 0);
> >
> > - return ret;
> > + return ret;
> > + }
> > +
> > + iowrite32(mode, priv->addr + GWMC);
> > +
> > + return rswitch_reg_wait(priv->addr, GWMS, GWMS_OPS_MASK, mode);
>
> Should the error from the initial DISABLE transition be checked before proceeding? When mode !=
> GWMC_OPC_DISABLE, this code stores the result of
> rswitch_reg_wait() for the DISABLE transition in 'ret' but never checks it.
> If the hardware fails to reach DISABLE state, the function silently proceeds to write the target mode.
>
> Before this patch, callers explicitly checked the error after calling rswitch_gwca_change_mode(priv,
> GWMC_OPC_DISABLE):
>
> rswitch_gwca_hw_init() and rswitch_gwca_hw_deinit():
> err = rswitch_gwca_change_mode(priv, GWMC_OPC_DISABLE);
> if (err < 0)
> return err;
>
> This patch removes those caller-side checks but doesn't replicate the error checking inside
> rswitch_gwca_change_mode(). If the first rswitch_reg_wait() returns -ETIMEDOUT, should the function
> return that error before attempting to write the target mode?
I have fixed this and will provide a new version of the patches.
Best regards,
Michael
>
> > }
> >
> > static int rswitch_gwca_mcast_table_reset(struct rswitch_private
> > *priv) @@ -682,9 +687,6 @@ static int rswitch_gwca_hw_init(struct rswitch_private *priv)
> > unsigned int i;
> > int err;
> >
> > - err = rswitch_gwca_change_mode(priv, GWMC_OPC_DISABLE);
> > - if (err < 0)
> > - return err;
> > err = rswitch_gwca_change_mode(priv, GWMC_OPC_CONFIG);
> > if (err < 0)
> > return err;
>
> [ ... ]
>
> > @@ -717,9 +719,6 @@ static int rswitch_gwca_hw_init(struct rswitch_private *priv)
> > return err;
> > }
> >
> > - err = rswitch_gwca_change_mode(priv, GWMC_OPC_DISABLE);
> > - if (err < 0)
> > - return err;
> > return rswitch_gwca_change_mode(priv, GWMC_OPC_OPERATION); }
> >
> > @@ -727,9 +726,6 @@ static int rswitch_gwca_hw_deinit(struct
> > rswitch_private *priv) {
> > int err;
> >
> > - err = rswitch_gwca_change_mode(priv, GWMC_OPC_DISABLE);
> > - if (err < 0)
> > - return err;
> > err = rswitch_gwca_change_mode(priv, GWMC_OPC_RESET);
> > if (err < 0)
> > return err;
>
> [ ... ]
>
> > @@ -1116,14 +1112,18 @@ static int rswitch_etha_change_mode(struct rswitch_etha *etha,
> > if (!rswitch_agent_clock_is_enabled(etha->coma_addr, etha->index))
> > rswitch_agent_clock_ctrl(etha->coma_addr, etha->index, 1);
> >
> > - iowrite32(mode, etha->addr + EAMC);
> > -
> > - ret = rswitch_reg_wait(etha->addr, EAMS, EAMS_OPS_MASK, mode);
> > + iowrite32(EAMC_OPC_DISABLE, etha->addr + EAMC);
> > + ret = rswitch_reg_wait(etha->addr, EAMS, EAMS_OPS_MASK,
> > +EAMC_OPC_DISABLE);
> >
> > - if (mode == EAMC_OPC_DISABLE)
> > + if (mode == EAMC_OPC_DISABLE) {
> > rswitch_agent_clock_ctrl(etha->coma_addr, etha->index, 0);
> >
> > - return ret;
> > + return ret;
> > + }
> > +
> > + iowrite32(mode, etha->addr + EAMC);
> > +
> > + return rswitch_reg_wait(etha->addr, EAMS, EAMS_OPS_MASK, mode);
>
> Same pattern here in rswitch_etha_change_mode(). When mode != EAMC_OPC_DISABLE, the return value from
> rswitch_reg_wait() for the intermediate DISABLE transition is stored in 'ret' but never checked.
>
> Before this patch, rswitch_etha_hw_init() explicitly called rswitch_etha_change_mode(etha,
> EAMC_OPC_DISABLE) with error checking before calling it with EAMC_OPC_CONFIG. This patch removes that
> caller-side check but doesn't replicate it inside the function. Should there be a check like 'if (ret
> < 0) return ret;' after the first rswitch_reg_wait()?
>
> > }
> >
> > static void rswitch_etha_read_mac_address(struct rswitch_etha *etha)
>
> [ ... ]
^ permalink raw reply
* [PATCH net v2 0/2] net: phylink: fix PHY reinitialization on resume
From: Ovidiu Panait @ 2026-04-09 9:56 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni,
biju.das.jz
Cc: netdev, linux-kernel, linux-renesas-soc, Ovidiu Panait
When mac_managed_pm flag is set, mdio_bus_phy_resume() is skipped,
so phy_init_hw(), which performs soft_reset and config_init, is not
called during resume.
This is inconsistent with the non-mac_managed_pm path, where
mdio_bus_phy_resume() calls phy_init_hw() before phy_resume()
on every resume.
This series adds phy_init_hw() to the phylink resume path to ensure
consistent PHY state regardless of whether mac_managed_pm is set,
and removes a now-redundant workaround in the KSZ9131 PHY driver.
v2:
- Moved phy_init_hw() from ksz9131_resume() to phylink resume path, as
suggested by Russell.
v1: https://lore.kernel.org/all/20260403111738.37749-1-ovidiu.panait.rb@renesas.com/#t
Ovidiu Panait (2):
net: phylink: call phy_init_hw() in phylink resume path
net: phy: micrel: remove ksz9131_resume()
drivers/net/phy/micrel.c | 10 +---------
drivers/net/phy/phylink.c | 9 ++++++++-
2 files changed, 9 insertions(+), 10 deletions(-)
--
2.34.1
^ permalink raw reply
* [PATCH net v2 1/2] net: phylink: call phy_init_hw() in phylink resume path
From: Ovidiu Panait @ 2026-04-09 9:56 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni,
biju.das.jz
Cc: netdev, linux-kernel, linux-renesas-soc, Ovidiu Panait
In-Reply-To: <20260409095633.70973-1-ovidiu.panait.rb@renesas.com>
When mac_managed_pm flag is set, mdio_bus_phy_resume() is skipped,
so phy_init_hw(), which performs soft_reset and config_init, is not
called during resume.
This is inconsistent with the non-mac_managed_pm path, where
mdio_bus_phy_resume() calls phy_init_hw() before phy_resume()
on every resume.
Add phy_init_hw() calls in both phylink_prepare_resume() and
phylink_resume(), to ensure that the PHY state is the same as
when the PHY is resumed via the MDIO bus.
Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
---
drivers/net/phy/phylink.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 087ac63f9193..c302126009f6 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -2669,8 +2669,10 @@ void phylink_prepare_resume(struct phylink *pl)
* then resume the PHY. Note that 802.3 allows PHYs 500ms before
* the clock meets requirements. We do not implement this delay.
*/
- if (pl->config->mac_requires_rxc && phydev && phydev->suspended)
+ if (pl->config->mac_requires_rxc && phydev && phydev->suspended) {
+ phy_init_hw(phydev);
phy_resume(phydev);
+ }
}
EXPORT_SYMBOL_GPL(phylink_prepare_resume);
@@ -2683,6 +2685,8 @@ EXPORT_SYMBOL_GPL(phylink_prepare_resume);
*/
void phylink_resume(struct phylink *pl)
{
+ struct phy_device *phydev = pl->phydev;
+
ASSERT_RTNL();
if (phylink_phy_pm_speed_ctrl(pl))
@@ -2712,6 +2716,9 @@ void phylink_resume(struct phylink *pl)
/* Re-enable and re-resolve the link parameters */
phylink_enable_and_run_resolve(pl, PHYLINK_DISABLE_MAC_WOL);
} else {
+ if (phydev && phydev->suspended)
+ phy_init_hw(phydev);
+
phylink_start(pl);
}
}
--
2.34.1
^ permalink raw reply related
* [PATCH net v2 2/2] net: phy: micrel: remove ksz9131_resume()
From: Ovidiu Panait @ 2026-04-09 9:56 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni,
biju.das.jz
Cc: netdev, linux-kernel, linux-renesas-soc, Ovidiu Panait
In-Reply-To: <20260409095633.70973-1-ovidiu.panait.rb@renesas.com>
ksz9131_resume() was added to restore RGMII delays on resume for platforms
where the PHY loses power during suspend to RAM. However, for s2idle, the
PHY stays in Software Power-Down (SPD) during resume. In that case,
ksz9131_config_rgmii_delay() accesses MMD registers before kszphy_resume()
clears BMCR_PDOWN. The KSZ9131 datasheet states that during SPD, access to
the MMD registers is restricted:
- Only access to the standard registers (0 through 31) is supported.
- Access to MMD address spaces other than MMD address space 1 is
possible if the spd_clock_gate_override bit is set.
- Access to MMD address space 1 is not possible.
Additionally, only RGMII delays were restored, while other settings
from ksz9131_config_init() were not.
Now that the preceding commit ("net: phylink: call phy_init_hw() in
phylink resume path") performs a phy_init_hw() during phylink resume,
ksz9131_resume() is no longer needed.
Remove it and use kszphy_resume() directly.
Fixes: f25a7eaa897f ("net: phy: micrel: Add ksz9131_resume()")
Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
---
drivers/net/phy/micrel.c | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 2aa1dedd21b8..f2513109865a 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -6014,14 +6014,6 @@ static int lan8841_suspend(struct phy_device *phydev)
return kszphy_generic_suspend(phydev);
}
-static int ksz9131_resume(struct phy_device *phydev)
-{
- if (phydev->suspended && phy_interface_is_rgmii(phydev))
- ksz9131_config_rgmii_delay(phydev);
-
- return kszphy_resume(phydev);
-}
-
#define LAN8842_PTP_GPIO_NUM 16
static int lan8842_ptp_probe_once(struct phy_device *phydev)
@@ -6929,7 +6921,7 @@ static struct phy_driver ksphy_driver[] = {
.get_strings = kszphy_get_strings,
.get_stats = kszphy_get_stats,
.suspend = kszphy_suspend,
- .resume = ksz9131_resume,
+ .resume = kszphy_resume,
.cable_test_start = ksz9x31_cable_test_start,
.cable_test_get_status = ksz9x31_cable_test_get_status,
.get_features = ksz9477_get_features,
--
2.34.1
^ permalink raw reply related
* RE: [Intel-wired-lan] [PATCH iwl-net v2] iavf: fix wrong VLAN mask for legacy Rx descriptors L2TAG2
From: Romanowski, Rafal @ 2026-04-09 10:02 UTC (permalink / raw)
To: Keller, Jacob E, Oros, Petr, netdev@vger.kernel.org
Cc: Paul Menzel, Kitszel, Przemyslaw, Eric Dumazet,
linux-kernel@vger.kernel.org, Loktionov, Aleksandr, Andrew Lunn,
Nguyen, Anthony L, Mateusz Polchlopek, Jakub Kicinski,
Paolo Abeni, David S. Miller, intel-wired-lan@lists.osuosl.org
In-Reply-To: <734bbc85-2209-4b6c-913e-e3637532e315@intel.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of Jacob
> Keller
> Sent: Tuesday, March 24, 2026 12:07 AM
> To: Oros, Petr <poros@redhat.com>; netdev@vger.kernel.org
> Cc: Paul Menzel <pmenzel@molgen.mpg.de>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; Eric Dumazet <edumazet@google.com>; linux-
> kernel@vger.kernel.org; Loktionov, Aleksandr <aleksandr.loktionov@intel.com>;
> Andrew Lunn <andrew+netdev@lunn.ch>; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; Mateusz Polchlopek
> <mateusz.polchlopek@intel.com>; Jakub Kicinski <kuba@kernel.org>; Paolo
> Abeni <pabeni@redhat.com>; David S. Miller <davem@davemloft.net>; intel-
> wired-lan@lists.osuosl.org
> Subject: Re: [Intel-wired-lan] [PATCH iwl-net v2] iavf: fix wrong VLAN mask for
> legacy Rx descriptors L2TAG2
>
> On 3/23/2026 3:15 AM, Petr Oros wrote:
> > The reproducer requires legacy Rx descriptors. On modern ice + iavf
> > with full PTP support, flex descriptors are always negotiated and the
> > buggy legacy path is never reached. Flex descriptors require all of:
> > - CONFIG_PTP_1588_CLOCK enabled
> > - VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC granted by PF
> > - PTP capabilities negotiated (VIRTCHNL_VF_CAP_PTP)
> > - VIRTCHNL_1588_PTP_CAP_RX_TSTAMP supported
> > - VIRTCHNL_RXDID_2_FLEX_SQ_NIC present in DDP profile
> >
> > If any condition is not met, iavf_select_rx_desc_format() falls back
> > to legacy descriptors (RXDID=1) and the wrong L2TAG2 mask is hit.
> >
>
> > Fixes: 2dc8e7c36d80 ("iavf: refactor iavf_clean_rx_irq to support
> > legacy and flex descriptors")
>
> Sure enough, this commit changed the legacy version to:
> +/* Stripped S-TAG VLAN from the receive packet */
> +#define IAVF_RXD_LEGACY_L2TAG2_M GENMASK_ULL(63, 32)
>
> I guess since we basically always negotiated flexible descriptors after this that we
> never caught it.
>
> Thanks for the fix.
>
> Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
>
> Regards,
> Jake
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH RFC iwl-next 1/4] iavf: rename IAVF_VLAN_IS_NEW to IAVF_VLAN_ADDING
From: Romanowski, Rafal @ 2026-04-09 10:10 UTC (permalink / raw)
To: Loktionov, Aleksandr, Oros, Petr, netdev@vger.kernel.org
Cc: Kitszel, Przemyslaw, Eric Dumazet, linux-kernel@vger.kernel.org,
Andrew Lunn, Nguyen, Anthony L, intel-wired-lan@lists.osuosl.org,
Keller, Jacob E, Jakub Kicinski, Paolo Abeni, David S. Miller
In-Reply-To: <IA3PR11MB89861519B35EE57D5D03969DE540A@IA3PR11MB8986.namprd11.prod.outlook.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of
> Loktionov, Aleksandr
> Sent: Monday, March 16, 2026 12:35 PM
> To: Oros, Petr <poros@redhat.com>; netdev@vger.kernel.org
> Cc: Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>; Eric Dumazet
> <edumazet@google.com>; linux-kernel@vger.kernel.org; Andrew Lunn
> <andrew+netdev@lunn.ch>; Nguyen, Anthony L <anthony.l.nguyen@intel.com>;
> intel-wired-lan@lists.osuosl.org; Keller, Jacob E <jacob.e.keller@intel.com>;
> Jakub Kicinski <kuba@kernel.org>; Paolo Abeni <pabeni@redhat.com>; David S.
> Miller <davem@davemloft.net>
> Subject: Re: [Intel-wired-lan] [PATCH RFC iwl-next 1/4] iavf: rename
> IAVF_VLAN_IS_NEW to IAVF_VLAN_ADDING
>
>
>
> > -----Original Message-----
> > From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> > Of Petr Oros
> > Sent: Monday, March 2, 2026 12:40 PM
> > To: netdev@vger.kernel.org
> > Cc: Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>; Eric Dumazet
> > <edumazet@google.com>; linux-kernel@vger.kernel.org; Andrew Lunn
> > <andrew+netdev@lunn.ch>; Nguyen, Anthony L
> > <anthony.l.nguyen@intel.com>; intel-wired-lan@lists.osuosl.org;
> > Keller, Jacob E <jacob.e.keller@intel.com>; Jakub Kicinski
> > <kuba@kernel.org>; Paolo Abeni <pabeni@redhat.com>; David S. Miller
> > <davem@davemloft.net>
> > Subject: [Intel-wired-lan] [PATCH RFC iwl-next 1/4] iavf: rename
> > IAVF_VLAN_IS_NEW to IAVF_VLAN_ADDING
> >
> > Rename the IAVF_VLAN_IS_NEW state to IAVF_VLAN_ADDING to better
> > describe what the state represents: an ADD request has been sent to
> > the PF and is waiting for a response.
> >
> > This is a pure rename with no behavioral change, preparing for a
> > cleanup of the VLAN filter state machine.
> >
> > Signed-off-by: Petr Oros <poros@redhat.com>
> > ---
> > drivers/net/ethernet/intel/iavf/iavf.h | 2 +-
> > drivers/net/ethernet/intel/iavf/iavf_virtchnl.c | 8 ++++----
> > 2 files changed, 5 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/intel/iavf/iavf.h
> > b/drivers/net/ethernet/intel/iavf/iavf.h
> > index a87e0c6d4017ad..8e6db72828ae14 100644
> > --- a/drivers/net/ethernet/intel/iavf/iavf.h
> > +++ b/drivers/net/ethernet/intel/iavf/iavf.h
> > @@ -158,7 +158,7 @@ struct iavf_vlan { enum iavf_vlan_state_t {
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH iwl-next 2/4] iavf: stop removing VLAN filters from PF on interface down
From: Romanowski, Rafal @ 2026-04-09 10:10 UTC (permalink / raw)
To: Oros, Petr, netdev@vger.kernel.org
Cc: Kitszel, Przemyslaw, Eric Dumazet, linux-kernel@vger.kernel.org,
Andrew Lunn, Nguyen, Anthony L, intel-wired-lan@lists.osuosl.org,
Keller, Jacob E, Jakub Kicinski, Paolo Abeni, David S. Miller
In-Reply-To: <20260316104209.1285962-3-poros@redhat.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of Petr
> Oros
> Sent: Monday, March 16, 2026 11:42 AM
> To: netdev@vger.kernel.org
> Cc: Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>; Eric Dumazet
> <edumazet@google.com>; linux-kernel@vger.kernel.org; Andrew Lunn
> <andrew+netdev@lunn.ch>; Nguyen, Anthony L <anthony.l.nguyen@intel.com>;
> intel-wired-lan@lists.osuosl.org; Keller, Jacob E <jacob.e.keller@intel.com>;
> Jakub Kicinski <kuba@kernel.org>; Paolo Abeni <pabeni@redhat.com>; David S.
> Miller <davem@davemloft.net>
> Subject: [Intel-wired-lan] [PATCH iwl-next 2/4] iavf: stop removing VLAN filters
> from PF on interface down
>
> When a VF goes down, the driver currently sends DEL_VLAN to the PF for every
> VLAN filter (ACTIVE -> DISABLE -> send DEL -> INACTIVE), then re-adds them all
> on UP (INACTIVE -> ADD -> send ADD -> ADDING -> ACTIVE). This round-trip is
> unnecessary because:
>
> 1. The PF disables the VF's queues via VIRTCHNL_OP_DISABLE_QUEUES,
> which already prevents all RX/TX traffic regardless of VLAN filter
> state.
>
> 2. The VLAN filters remaining in PF HW while the VF is down is
> harmless - packets matching those filters have nowhere to go with
> queues disabled.
>
> 3. The DEL+ADD cycle during down/up creates race windows where the
> VLAN filter list is incomplete. With spoofcheck enabled, the PF
> enables TX VLAN filtering on the first non-zero VLAN add, blocking
> traffic for any VLANs not yet re-added.
>
> Remove the entire DISABLE/INACTIVE state machinery:
> - Remove IAVF_VLAN_DISABLE and IAVF_VLAN_INACTIVE enum values
> - Remove iavf_restore_filters() and its call from iavf_open()
> - Remove VLAN filter handling from iavf_clear_mac_vlan_filters(),
> rename it to iavf_clear_mac_filters()
> - Remove DEL_VLAN_FILTER scheduling from iavf_down()
> - Remove all DISABLE/INACTIVE handling from iavf_del_vlans()
>
> VLAN filters now stay ACTIVE across down/up cycles. Only explicit user removal
> (ndo_vlan_rx_kill_vid) or PF/VF reset triggers VLAN filter deletion/re-addition.
>
> Signed-off-by: Petr Oros <poros@redhat.com>
> ---
> drivers/net/ethernet/intel/iavf/iavf.h | 6 +--
> drivers/net/ethernet/intel/iavf/iavf_main.c | 39 ++-----------------
> .../net/ethernet/intel/iavf/iavf_virtchnl.c | 33 +++-------------
> 3 files changed, 12 insertions(+), 66 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/iavf/iavf.h
> b/drivers/net/ethernet/intel/iavf/iavf.h
> index 8e6db72828ae14..1ad00690622c8e 100644
> --- a/drivers/net/ethernet/intel/iavf/iavf.h
> +++ b/drivers/net/ethernet/intel/iavf/iavf.h
> @@ -159,10 +159,8 @@ enum iavf_vlan_state_t {
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
^ permalink raw reply
* Re: [TEST] nft_tproxy_udp.sh flaky after Fedora 44 upgrade
From: Florian Westphal @ 2026-04-09 10:11 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: netdev@vger.kernel.org
In-Reply-To: <20260408152432.24b8ad0d@kernel.org>
Jakub Kicinski <kuba@kernel.org> wrote:
> When you have a sec -- we upgraded the NIPA systems to Fedora 44
> over the weekend, and nft_tproxy_udp.sh has gotten quite flaky:
> https://netdev.bots.linux.dev/contest.html?test=nft-tproxy-udp-sh
>
> One thing that we hit immediately is this, in case tproxy test
> uses socat:
>
> commit e65d8b6f3092398efd7c74e722cb7a516d9a0d6d
> Date: Sat Apr 4 16:01:03 2026 -0700
>
> selftests: drv-net: adjust to socat changes
>
> socat v1.8.1.0 now defaults to shut-null, it sends an extra
> 0-length UDP packet when sender disconnects. This breaks
> our tests which expect the exact packet sequence.
>
> Add shut-none which was the old default where necessary.
Thanks for the pointer, I will try to get to this later today.
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH iwl-next 3/4] iavf: wait for PF confirmation before removing VLAN filters
From: Romanowski, Rafal @ 2026-04-09 10:11 UTC (permalink / raw)
To: Oros, Petr, netdev@vger.kernel.org
Cc: Kitszel, Przemyslaw, Eric Dumazet, linux-kernel@vger.kernel.org,
Andrew Lunn, Nguyen, Anthony L, intel-wired-lan@lists.osuosl.org,
Keller, Jacob E, Jakub Kicinski, Paolo Abeni, David S. Miller
In-Reply-To: <20260316104209.1285962-4-poros@redhat.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of Petr
> Oros
> Sent: Monday, March 16, 2026 11:42 AM
> To: netdev@vger.kernel.org
> Cc: Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>; Eric Dumazet
> <edumazet@google.com>; linux-kernel@vger.kernel.org; Andrew Lunn
> <andrew+netdev@lunn.ch>; Nguyen, Anthony L <anthony.l.nguyen@intel.com>;
> intel-wired-lan@lists.osuosl.org; Keller, Jacob E <jacob.e.keller@intel.com>;
> Jakub Kicinski <kuba@kernel.org>; Paolo Abeni <pabeni@redhat.com>; David S.
> Miller <davem@davemloft.net>
> Subject: [Intel-wired-lan] [PATCH iwl-next 3/4] iavf: wait for PF confirmation
> before removing VLAN filters
>
> The VLAN filter DELETE path was asymmetric with the ADD path: ADD waits for
> PF confirmation (ADD -> ADDING -> ACTIVE), but DELETE immediately frees the
> filter struct after sending the DEL message without waiting for the PF response.
>
> This is problematic because:
> - If the PF rejects the DEL, the filter remains in HW but the driver
> has already freed the tracking structure, losing sync.
> - Race conditions between DEL pending and other operations
> (add, reset) cannot be properly resolved if the filter struct
> is already gone.
>
> Add IAVF_VLAN_REMOVING state to make the DELETE path symmetric:
>
> REMOVE -> REMOVING (send DEL) -> PF confirms -> kfree
> -> PF rejects -> ACTIVE
>
> In iavf_del_vlans(), transition filters from REMOVE to REMOVING instead of
> immediately freeing them. The new DEL completion handler in
> iavf_virtchnl_completion() frees filters on success or reverts them to ACTIVE on
> error.
>
> Update iavf_add_vlan() to handle the REMOVING state: if a DEL is pending and
> the user re-adds the same VLAN, queue it for ADD so it gets re-programmed after
> the PF processes the DEL.
>
> The !VLAN_FILTERING_ALLOWED early-exit path still frees filters directly since no
> PF message is sent in that case.
>
> Signed-off-by: Petr Oros <poros@redhat.com>
> ---
> drivers/net/ethernet/intel/iavf/iavf.h | 1 +
> drivers/net/ethernet/intel/iavf/iavf_main.c | 9 +++--
> .../net/ethernet/intel/iavf/iavf_virtchnl.c | 37 +++++++++++++------
> 3 files changed, 32 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/iavf/iavf.h
> b/drivers/net/ethernet/intel/iavf/iavf.h
> index 1ad00690622c8e..f9ad814d18b1da 100644
> --- a/drivers/net/ethernet/intel/iavf/iavf.h
> +++ b/drivers/net/ethernet/intel/iavf/iavf.h
> @@ -161,6 +161,7 @@ enum iavf_vlan_state_t {
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
^ permalink raw reply
* [PATCH net-next] tcp: return a drop_reason from tcp_add_backlog()
From: Eric Dumazet @ 2026-04-09 10:11 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Neal Cardwell, Kuniyuki Iwashima, netdev,
eric.dumazet, Eric Dumazet
Part of a stack canary removal from tcp_v{4,6}_rcv().
Return a drop_reason instead of a boolean, so that we no longer
have to pass the address of a local variable.
$ scripts/bloat-o-meter -t vmlinux.old vmlinux.new
add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-37 (-37)
Function old new delta
tcp_v6_rcv 3133 3129 -4
tcp_v4_rcv 3206 3202 -4
tcp_add_backlog 1281 1252 -29
Total: Before=25567186, After=25567149, chg -0.00%
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/net/tcp.h | 3 +--
net/ipv4/tcp_ipv4.c | 21 +++++++++------------
net/ipv6/tcp_ipv6.c | 3 ++-
3 files changed, 12 insertions(+), 15 deletions(-)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 6156d1d068e142f696ec9dfff63e3aaebb0171bc..fce4b653c23ec790f561d577fcd6160d3d92e3c0 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1680,8 +1680,7 @@ static inline bool tcp_checksum_complete(struct sk_buff *skb)
__skb_checksum_complete(skb);
}
-bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb,
- enum skb_drop_reason *reason);
+enum skb_drop_reason tcp_add_backlog(struct sock *sk, struct sk_buff *skb);
static inline int tcp_filter(struct sock *sk, struct sk_buff *skb,
enum skb_drop_reason *reason)
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 69ab236072e7142d5ca9d0703d99f02c1e17c738..c9bbbf32364827d341b4c1fd77617031b0739c50 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1900,8 +1900,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
}
EXPORT_SYMBOL(tcp_v4_do_rcv);
-bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb,
- enum skb_drop_reason *reason)
+enum skb_drop_reason tcp_add_backlog(struct sock *sk, struct sk_buff *skb)
{
u32 tail_gso_size, tail_gso_segs;
struct skb_shared_info *shinfo;
@@ -1929,10 +1928,9 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb,
if (unlikely(tcp_checksum_complete(skb))) {
bh_unlock_sock(sk);
trace_tcp_bad_csum(skb);
- *reason = SKB_DROP_REASON_TCP_CSUM;
__TCP_INC_STATS(sock_net(sk), TCP_MIB_CSUMERRORS);
__TCP_INC_STATS(sock_net(sk), TCP_MIB_INERRS);
- return true;
+ return SKB_DROP_REASON_TCP_CSUM;
}
/* Attempt coalescing to last skb in backlog, even if we are
@@ -2006,7 +2004,7 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb,
__NET_INC_STATS(sock_net(sk),
LINUX_MIB_TCPBACKLOGCOALESCE);
kfree_skb_partial(skb, fragstolen);
- return false;
+ return SKB_NOT_DROPPED_YET;
}
__skb_push(skb, hdrlen);
@@ -2031,15 +2029,13 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb,
if (unlikely(err)) {
bh_unlock_sock(sk);
if (err == -ENOMEM) {
- *reason = SKB_DROP_REASON_PFMEMALLOC;
__NET_INC_STATS(sock_net(sk), LINUX_MIB_PFMEMALLOCDROP);
- } else {
- *reason = SKB_DROP_REASON_SOCKET_BACKLOG;
- __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPBACKLOGDROP);
+ return SKB_DROP_REASON_PFMEMALLOC;
}
- return true;
+ __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPBACKLOGDROP);
+ return SKB_DROP_REASON_SOCKET_BACKLOG;
}
- return false;
+ return SKB_NOT_DROPPED_YET;
}
static void tcp_v4_restore_cb(struct sk_buff *skb)
@@ -2247,7 +2243,8 @@ int tcp_v4_rcv(struct sk_buff *skb)
if (!sock_owned_by_user(sk)) {
ret = tcp_v4_do_rcv(sk, skb);
} else {
- if (tcp_add_backlog(sk, skb, &drop_reason))
+ drop_reason = tcp_add_backlog(sk, skb);
+ if (drop_reason)
goto discard_and_relse;
}
bh_unlock_sock(sk);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 8dc3874e8b9252da60f21ad77a5ca834532e650a..1d37826e8480f203846e963418cfe2085131adfa 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1877,7 +1877,8 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
if (!sock_owned_by_user(sk)) {
ret = tcp_v6_do_rcv(sk, skb);
} else {
- if (tcp_add_backlog(sk, skb, &drop_reason))
+ drop_reason = tcp_add_backlog(sk, skb);
+ if (drop_reason)
goto discard_and_relse;
}
bh_unlock_sock(sk);
--
2.53.0.1213.gd9a14994de-goog
^ permalink raw reply related
* Re: [PATCH nf] netfilter: nft_fwd_netdev: use recursion counter in neigh egress path
From: Weiming Shi @ 2026-04-09 10:11 UTC (permalink / raw)
To: Florian Westphal
Cc: Pablo Neira Ayuso, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Phil Sutter, Simon Horman, netfilter-devel, coreteam,
netdev, Xiang Mei
In-Reply-To: <add2ajF5YGqd4MxZ@strlen.de>
On 26-04-09 11:50, Florian Westphal wrote:
> Weiming Shi <bestswngs@gmail.com> wrote:
> > Fixes: f87b9464d152 ("netfilter: nft_fwd_netdev: Support egress hook")
> > Reported-by: Xiang Mei <xmei5@asu.edu>
> > Signed-off-by: Weiming Shi <bestswngs@gmail.com>
> > ---
> > include/net/netfilter/nf_dup_netdev.h | 4 ++++
> > net/netfilter/nf_dup_netdev.c | 18 ++++++++++++++++++
> > net/netfilter/nft_fwd_netdev.c | 7 +++++++
> > 3 files changed, 29 insertions(+)
> >
> > diff --git a/include/net/netfilter/nf_dup_netdev.h b/include/net/netfilter/nf_dup_netdev.h
> > index b175d271aec9..17362f76d1d1 100644
> > --- a/include/net/netfilter/nf_dup_netdev.h
> > +++ b/include/net/netfilter/nf_dup_netdev.h
> > @@ -7,6 +7,10 @@
> > void nf_dup_netdev_egress(const struct nft_pktinfo *pkt, int oif);
> > void nf_fwd_netdev_egress(const struct nft_pktinfo *pkt, int oif);
> >
> > +bool nf_dup_netdev_has_recursed(void);
> > +void nf_dup_netdev_recursion_inc(void);
> > +void nf_dup_netdev_recursion_dec(void);
> > +
> > struct nft_offload_ctx;
> > struct nft_flow_rule;
> >
> > diff --git a/net/netfilter/nf_dup_netdev.c b/net/netfilter/nf_dup_netdev.c
> > index fab8b9011098..e2fe8bb6fe0d 100644
> > --- a/net/netfilter/nf_dup_netdev.c
> > +++ b/net/netfilter/nf_dup_netdev.c
> > @@ -29,6 +29,24 @@ static u8 *nf_get_nf_dup_skb_recursion(void)
> >
> > #endif
> >
> > +bool nf_dup_netdev_has_recursed(void)
> > +{
> > + return *nf_get_nf_dup_skb_recursion() > NF_RECURSION_LIMIT;
> > +}
> > +EXPORT_SYMBOL_GPL(nf_dup_netdev_has_recursed);
>
> I think thats a bit too heavy-handed.
> nf_get_nf_dup_skb_recursion() fetches from pcpu counter or current->.
>
> Can you move nf_get_nf_dup_skb_recursion to a shared header file
> and make it inline instead of having a function call?
>
Thanks for the review. I will send the patch for version v2 as you suggested.
Weiming Shi
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH iwl-next 4/4] iavf: harden VLAN filter state machine race handling
From: Romanowski, Rafal @ 2026-04-09 10:12 UTC (permalink / raw)
To: Loktionov, Aleksandr, Oros, Petr, netdev@vger.kernel.org
Cc: Kitszel, Przemyslaw, Eric Dumazet, linux-kernel@vger.kernel.org,
Andrew Lunn, Nguyen, Anthony L, intel-wired-lan@lists.osuosl.org,
Keller, Jacob E, Jakub Kicinski, Paolo Abeni, David S. Miller
In-Reply-To: <IA3PR11MB8986FA7536046A7AE5C98D96E540A@IA3PR11MB8986.namprd11.prod.outlook.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of
> Loktionov, Aleksandr
> Sent: Monday, March 16, 2026 12:38 PM
> To: Oros, Petr <poros@redhat.com>; netdev@vger.kernel.org
> Cc: Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>; Eric Dumazet
> <edumazet@google.com>; linux-kernel@vger.kernel.org; Andrew Lunn
> <andrew+netdev@lunn.ch>; Nguyen, Anthony L <anthony.l.nguyen@intel.com>;
> intel-wired-lan@lists.osuosl.org; Keller, Jacob E <jacob.e.keller@intel.com>;
> Jakub Kicinski <kuba@kernel.org>; Paolo Abeni <pabeni@redhat.com>; David S.
> Miller <davem@davemloft.net>
> Subject: Re: [Intel-wired-lan] [PATCH iwl-next 4/4] iavf: harden VLAN filter state
> machine race handling
>
>
>
> > -----Original Message-----
> > From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> > Of Petr Oros
> > Sent: Monday, March 16, 2026 11:42 AM
> > To: netdev@vger.kernel.org
> > Cc: Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>; Eric Dumazet
> > <edumazet@google.com>; linux-kernel@vger.kernel.org; Andrew Lunn
> > <andrew+netdev@lunn.ch>; Nguyen, Anthony L
> > <anthony.l.nguyen@intel.com>; intel-wired-lan@lists.osuosl.org;
> > Keller, Jacob E <jacob.e.keller@intel.com>; Jakub Kicinski
> > <kuba@kernel.org>; Paolo Abeni <pabeni@redhat.com>; David S. Miller
> > <davem@davemloft.net>
> > Subject: [Intel-wired-lan] [PATCH iwl-next 4/4] iavf: harden VLAN
> > filter state machine race handling
> >
> > Address remaining race windows in the VLAN filter state machine that
> > were identified during cross-state analysis of ADD and DEL paths.
> >
> > 1. Add VIRTCHNL_OP_ADD_VLAN to the success completion handler.
> >
> > The V1 ADD_VLAN opcode had no success handler -- filters sent via
> > V1
> > stayed in ADDING state permanently. Add a fallthrough case so V1
> > filters also transition ADDING -> ACTIVE on PF confirmation.
> >
> > Critically, add an `if (v_retval) break` guard: the error switch
> > in iavf_virtchnl_completion() does NOT return after handling
> > errors,
> > it falls through to the success switch. Without this guard, a
> > PF-rejected ADD would incorrectly mark ADDING filters as ACTIVE,
> > creating a driver/HW mismatch where the driver believes the filter
> > is installed but the PF never accepted it.
> >
> > For V2, this is harmless: iavf_vlan_add_reject() in the error
> > block already kfree'd all ADDING filters, so the success handler
> > finds nothing to transition.
> >
> > 2. Skip DEL on filters already in REMOVING state.
> >
> > In iavf_del_vlan(), if a filter is in IAVF_VLAN_REMOVING (DEL
> > already sent to PF, waiting for response), do not overwrite to
> > REMOVE and schedule a redundant DEL. The pending DEL's
> > completion handler will either kfree the filter (PF confirms)
> > or revert to ACTIVE (PF rejects).
> >
> > Without this, the sequence DEL(pending) -> user-del -> second DEL
> > could result in PF returning an error for the second DEL (filter
> > already gone), causing the completion handler to incorrectly revert
> > a deleted filter back to ACTIVE.
> >
> > Signed-off-by: Petr Oros <poros@redhat.com>
> > ---
> > drivers/net/ethernet/intel/iavf/iavf_main.c | 5 ++++-
> > drivers/net/ethernet/intel/iavf/iavf_virtchnl.c | 4 ++++
> > 2 files changed, 8 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c
> > b/drivers/net/ethernet/intel/iavf/iavf_main.c
> > index 89e5aae20d5573..1ffc0ce3f35602 100644
> > --- a/drivers/net/ethernet/intel/iavf/iavf_main.c
> > +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
> > @@ -816,11 +816,14 @@ static void iavf_del_vlan(struct iavf_adapter
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
^ permalink raw reply
* RE: [PATCH net v2 2/2] net: phy: micrel: remove ksz9131_resume()
From: Biju Das @ 2026-04-09 10:13 UTC (permalink / raw)
To: Ovidiu Panait, andrew@lunn.ch, hkallweit1@gmail.com,
linux@armlinux.org.uk, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-renesas-soc@vger.kernel.org, Ovidiu Panait
In-Reply-To: <20260409095633.70973-3-ovidiu.panait.rb@renesas.com>
Hi Ovidu,
Thanks for the patch.
> -----Original Message-----
> From: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
> Sent: 09 April 2026 10:57
> Subject: [PATCH net v2 2/2] net: phy: micrel: remove ksz9131_resume()
>
> ksz9131_resume() was added to restore RGMII delays on resume for platforms where the PHY loses power
> during suspend to RAM. However, for s2idle, the PHY stays in Software Power-Down (SPD) during resume.
> In that case,
> ksz9131_config_rgmii_delay() accesses MMD registers before kszphy_resume() clears BMCR_PDOWN. The
> KSZ9131 datasheet states that during SPD, access to the MMD registers is restricted:
>
> - Only access to the standard registers (0 through 31) is supported.
> - Access to MMD address spaces other than MMD address space 1 is
> possible if the spd_clock_gate_override bit is set.
> - Access to MMD address space 1 is not possible.
>
> Additionally, only RGMII delays were restored, while other settings from ksz9131_config_init() were
> not.
>
> Now that the preceding commit ("net: phylink: call phy_init_hw() in phylink resume path") performs a
> phy_init_hw() during phylink resume,
> ksz9131_resume() is no longer needed.
>
> Remove it and use kszphy_resume() directly.
How to avoid code duplication in this case?
For eg: phy_init_hw() makes the phy out of SPD state
and kszphy_resume() unconditionally makes the phy out of SPD state again.
¬ kszphy_generic_resume
¬ genphy_resume
Cheers,
Biju
>
> Fixes: f25a7eaa897f ("net: phy: micrel: Add ksz9131_resume()")
> Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
> ---
> drivers/net/phy/micrel.c | 10 +---------
> 1 file changed, 1 insertion(+), 9 deletions(-)
>
> diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 2aa1dedd21b8..f2513109865a
> 100644
> --- a/drivers/net/phy/micrel.c
> +++ b/drivers/net/phy/micrel.c
> @@ -6014,14 +6014,6 @@ static int lan8841_suspend(struct phy_device *phydev)
> return kszphy_generic_suspend(phydev); }
>
> -static int ksz9131_resume(struct phy_device *phydev) -{
> - if (phydev->suspended && phy_interface_is_rgmii(phydev))
> - ksz9131_config_rgmii_delay(phydev);
> -
> - return kszphy_resume(phydev);
> -}
> -
> #define LAN8842_PTP_GPIO_NUM 16
>
> static int lan8842_ptp_probe_once(struct phy_device *phydev) @@ -6929,7 +6921,7 @@ static struct
> phy_driver ksphy_driver[] = {
> .get_strings = kszphy_get_strings,
> .get_stats = kszphy_get_stats,
> .suspend = kszphy_suspend,
> - .resume = ksz9131_resume,
> + .resume = kszphy_resume,
> .cable_test_start = ksz9x31_cable_test_start,
> .cable_test_get_status = ksz9x31_cable_test_get_status,
> .get_features = ksz9477_get_features,
> --
> 2.34.1
^ permalink raw reply
* RE: [PATCH net] net: phy: micrel: Fix MMD register access during SPD in ksz9131_resume()
From: Ovidiu Panait @ 2026-04-09 10:13 UTC (permalink / raw)
To: geert
Cc: andrew@lunn.ch, hkallweit1@gmail.com, linux@armlinux.org.uk,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, Biju Das, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
Niklas Söderlund
In-Reply-To: <CAMuHMdWQiRpCVMuimOMo4Mz2EAG+gbnKyXY7oSXh7mL_fkdGSQ@mail.gmail.com>
Hi Geert,
>
> Hi Ovidiu,
>
> On Fri, 3 Apr 2026 at 13:18, Ovidiu Panait <ovidiu.panait.rb@renesas.com>
> wrote:
> > During system suspend, phy_suspend() puts the PHY into Software Power-
> Down
> > (SPD) by setting the BMCR_PDOWN bit in MII_BMCR. According to the
> KSZ9131
> > datasheet, MMD register access is restricted during SPD:
> >
> > - Only access to the standard registers (0 through 31) is supported.
> > - Access to MMD address spaces other than MMD address space 1 is
> > possible if the spd_clock_gate_override bit is set.
> > - Access to MMD address space 1 is not possible.
> >
> > However, ksz9131_resume() calls ksz9131_config_rgmii_delay() before
> > kszphy_resume() clears BMCR_PDOWN. This means MMD registers are accessed
> > while the PHY is still in SPD, contrary to the datasheet.
> >
> > Additionally, on platforms where the PHY loses power during suspend
> > (e.g. RZ/G3E), all settings from ksz9131_config_init(), not just the
> > RGMII delays, are lost and need to be restored. When the MAC driver
> > sets mac_managed_pm (e.g. stmmac), mdio_bus_phy_resume() is skipped,
> > so phy_init_hw() (which calls config_init to restore all PHY settings)
> > is never invoked during resume.
> >
> > Fix this by replacing the RGMII delay restoration with a call to
> > phy_init_hw(), which takes the PHY out of SPD and performs full
> > reinitialization.
> >
> > Fixes: f25a7eaa897f ("net: phy: micrel: Add ksz9131_resume()")
> > Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
>
> Thanks for your patch!
>
> > --- a/drivers/net/phy/micrel.c
> > +++ b/drivers/net/phy/micrel.c
> > @@ -6016,8 +6016,13 @@ static int lan8841_suspend(struct phy_device
> *phydev)
> >
> > static int ksz9131_resume(struct phy_device *phydev)
> > {
> > - if (phydev->suspended && phy_interface_is_rgmii(phydev))
> > - ksz9131_config_rgmii_delay(phydev);
> > + int ret;
> > +
> > + if (phydev->suspended) {
> > + ret = phy_init_hw(phydev);
> > + if (ret)
> > + return ret;
> > + }
> >
> > return kszphy_resume(phydev);
> > }
>
> This function is now no longer KSZ9131-specific.
> I am wondering if this should be done for other Micrel PHYs, too,
> e.g. by moving the phy_init_hw() call into kszphy_resume()?
>
> Ethernet after resume has always been flaky on Salvator-X with KSZ9031
> and R-Car M3-W ES1.0 (this seems to be specific to R-Car M3-W, as
> boards with R-Car H3 or M3-N do not seem to suffer from this; don't
> ask me why).
>
> I have just tried:
>
> - .resume = kszphy_resume,
> + .resume = ksz9131_resume,
>
> in the KSZ9031 entry, and ... surprise! Ethernet on R-Car M3-W now
> works much better after resume!
>
I checked the dts for the Salvator-X board and it seems that it uses
the RAVB MAC. The driver for RAVB sets the mac_managed_pm flag, which
means that the MAC driver is handling the suspend/resume of the PHY.
In this case, as Russell pointed out in [1], the MAC driver should be
the one issuing phy_init_hw() before calling phy_resume(). I sent a
fix for the phylink resume path ([2]), to align it with the MDIO bus
resume path, but the RAVB driver doesn't seem to be using phylink,
it calls phy_start() directly.
Based on this, I think the fix should be to add a phy_init_hw() call
in the RAVB driver, on the resume path, rather than in the PHY driver.
[1] https://lore.kernel.org/all/ac_Udvtrj0Bl-6wl@shell.armlinux.org.uk/
[2] https://lore.kernel.org/all/20260409095633.70973-2-ovidiu.panait.rb@renesas.com/
Thanks,
Ovidiu
^ permalink raw reply
* Re: [PATCH net-next v7 2/2] r8152: Add support for the RTL8157 hardware
From: Paolo Abeni @ 2026-04-09 10:16 UTC (permalink / raw)
To: Birger Koblitz, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski
Cc: linux-usb, netdev, linux-kernel, Chih Kai Hsu
In-Reply-To: <20260404-rtl8157_next-v7-2-039121318f23@birger-koblitz.de>
On 4/4/26 9:57 AM, Birger Koblitz wrote:
> @@ -6534,8 +6842,11 @@ static void rtl8156_up(struct r8152 *tp)
> ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3,
> PLA_MCU_SPDWN_EN);
>
> - ocp_word_clr_bits(tp, MCU_TYPE_USB, USB_SPEED_OPTION,
> - RG_PWRDN_EN | ALL_SPEED_OFF);
> + ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, PLA_MCU_SPDWN_EN);
AI review notes that the above leads to 2 consecutive:
ocp_word_clr_bits(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, PLA_MCU_SPDWN_EN);
with slightly different formatting, likely C&P error?!?
I think this is better handled with a follow-up, if needed, as I don't
see any possible issue out of it.
Other AI comments look not relevant.
/P
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH iwl-next 1/4] iavf: rename IAVF_VLAN_IS_NEW to IAVF_VLAN_ADDING
From: Romanowski, Rafal @ 2026-04-09 10:16 UTC (permalink / raw)
To: Oros, Petr, netdev@vger.kernel.org
Cc: Kitszel, Przemyslaw, Eric Dumazet, linux-kernel@vger.kernel.org,
Andrew Lunn, Nguyen, Anthony L, intel-wired-lan@lists.osuosl.org,
Keller, Jacob E, Jakub Kicinski, Paolo Abeni, David S. Miller
In-Reply-To: <20260316104209.1285962-2-poros@redhat.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of Petr
> Oros
> Sent: Monday, March 16, 2026 11:42 AM
> To: netdev@vger.kernel.org
> Cc: Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>; Eric Dumazet
> <edumazet@google.com>; linux-kernel@vger.kernel.org; Andrew Lunn
> <andrew+netdev@lunn.ch>; Nguyen, Anthony L <anthony.l.nguyen@intel.com>;
> intel-wired-lan@lists.osuosl.org; Keller, Jacob E <jacob.e.keller@intel.com>;
> Jakub Kicinski <kuba@kernel.org>; Paolo Abeni <pabeni@redhat.com>; David S.
> Miller <davem@davemloft.net>
> Subject: [Intel-wired-lan] [PATCH iwl-next 1/4] iavf: rename IAVF_VLAN_IS_NEW
> to IAVF_VLAN_ADDING
>
> Rename the IAVF_VLAN_IS_NEW state to IAVF_VLAN_ADDING to better describe
> what the state represents: an ADD request has been sent to the PF and is waiting
> for a response.
>
> This is a pure rename with no behavioral change, preparing for a cleanup of the
> VLAN filter state machine.
>
> Signed-off-by: Petr Oros <poros@redhat.com>
> ---
> drivers/net/ethernet/intel/iavf/iavf.h | 2 +-
> drivers/net/ethernet/intel/iavf/iavf_virtchnl.c | 8 ++++----
> 2 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/iavf/iavf.h
> b/drivers/net/ethernet/intel/iavf/iavf.h
> index a87e0c6d4017ad..8e6db72828ae14 100644
> --- a/drivers/net/ethernet/intel/iavf/iavf.h
> +++ b/drivers/net/ethernet/intel/iavf/iavf.h
> @@ -158,7 +158,7 @@ struct iavf_vlan {
> enum iavf_vlan_state_t {
> IAVF_VLAN_INVALID,
> IAVF_VLAN_ADD, /* filter needs to be added */
> - IAVF_VLAN_IS_NEW, /* filter is new, wait for PF answer */
> + IAVF_VLAN_ADDING, /* ADD sent to PF, waiting for response */
> IAVF_VLAN_ACTIVE, /* filter is accepted by PF */
> IAVF_VLAN_DISABLE, /* filter needs to be deleted by PF, then marked
> INACTIVE */
> IAVF_VLAN_INACTIVE, /* filter is inactive, we are in IFF_DOWN */
> diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
> b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
> index 88156082a41da6..5114934fe81fa6 100644
> --- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
> +++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
> @@ -746,7 +746,7 @@ static void iavf_vlan_add_reject(struct iavf_adapter
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
^ permalink raw reply
* Re: [PATCH] nfc: nci: fix OOB heap read in nci_core_init_rsp_packet_v2()
From: Simon Horman @ 2026-04-09 10:17 UTC (permalink / raw)
To: Lekë Hapçiu
Cc: netdev, gregkh, linux-nfc, davem, kuba, Lekë Hapçiu
In-Reply-To: <20260404180049.1304711-1-snowwlake@icloud.com>
On Sat, Apr 04, 2026 at 08:00:49PM +0200, Lekë Hapçiu wrote:
> From: Lekë Hapçiu <framemain@outlook.com>
>
> nci_core_init_rsp_packet_v2() walks the chip-supplied
> supported_rf_interfaces[] flexible array using a plain pointer
> with no bounds check. Each iteration advances supported_rf_interface
> by (1 + 1 + rf_extension_cnt) bytes, where rf_extension_cnt comes
> directly from the chip. A hostile NCI v2 chip can set
> rf_extension_cnt=255 per entry and num_supported_rf_interfaces=4,
> driving the pointer up to ~1028 bytes past the end of the skb into
> adjacent kernel heap.
>
> Add two guards per loop iteration:
> - check that at least 2 bytes remain before reading the interface
> byte and extension count byte;
> - check that sufficient bytes remain for the declared extension
> block before advancing over it.
>
> Also add an upfront sizeof(*rsp) check so that accessing the fixed
> header fields (nfcc_features, max_logical_connections, ...) is safe
> before the loop is reached.
>
> Fixes: bcd684aace34 ("net/nfc/nci: Support NCI 2.x initial sequence")
> Signed-off-by: Lekë Hapçiu <framemain@outlook.com>
I believe that my review of "[PATCH] nfc: nci: fix OOB heap read in
nci_core_init_rsp_packet_v1()" is relevant here.
- https://lore.kernel.org/all/20260408190505.GK469338@kernel.org/
I would appreciate it if you could create a v2 patchset, including
an updated version of this patch and that one.
Thanks!
--
pw-bot: changes-requested
^ permalink raw reply
* [PATCH iwl-net v5] ice: fix missing dpll notifications for SW pins
From: Petr Oros @ 2026-04-09 10:25 UTC (permalink / raw)
To: netdev
Cc: Petr Oros, Tony Nguyen, Przemek Kitszel, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Arkadiusz Kubalewski, intel-wired-lan, linux-kernel
The SMA/U.FL pin redesign (commit 2dd5d03c77e2 ("ice: redesign dpll
sma/u.fl pins control")) introduced software-controlled pins that wrap
backing CGU input/output pins, but never updated the notification and
data paths to propagate pin events to these SW wrappers.
The periodic work sends dpll_pin_change_ntf() only for direct CGU input
pins. SW pins that wrap these inputs never receive change or phase
offset notifications, so userspace consumers such as synce4l monitoring
SMA pins via dpll netlink never learn about state transitions or phase
offset updates. Similarly, ice_dpll_phase_offset_get() reads the SW
pin's own phase_offset field which is never updated; the PPS monitor
writes to the backing CGU input's field instead.
On top of that, when SMA or U.FL pin state changes via PCA9575 GPIO
write, the paired pin's state also changes because they share physical
signal paths, but no notification is sent for the peer pin.
Fix by introducing ice_dpll_pin_ntf(), a wrapper around
dpll_pin_change_ntf() that also notifies any registered SMA/U.FL pin
whose backing CGU input matches. Replace all direct
dpll_pin_change_ntf() calls in the periodic notification paths with
this wrapper. Fix ice_dpll_phase_offset_get() to return the backing
CGU input's phase_offset for input-direction SW pins. Add
ice_dpll_sw_pin_notify_peer() to send a notification for the paired
SW pin after PCA9575 writes in ice_dpll_sma_direction_set() and
ice_dpll_ufl_pin_state_set().
Fixes: 2dd5d03c77e2 ("ice: redesign dpll sma/u.fl pins control")
Signed-off-by: Petr Oros <poros@redhat.com>
---
v5:
- add ice_dpll_sw_pin_notify_peer() for SMA/U.FL peer notification
when PCA9575 routing changes affect the paired pin (reported by
Intel test: SMA state change did not log U.FL status change in
subscribe monitor)
v4: https://lore.kernel.org/all/20260319205256.998876-1-poros@redhat.com/
v3: https://lore.kernel.org/all/20260220140700.2910174-1-poros@redhat.com/
v2: https://lore.kernel.org/all/20260219131500.2271897-1-poros@redhat.com/
v1: https://lore.kernel.org/all/20260218211414.1411163-1-poros@redhat.com/
---
drivers/net/ethernet/intel/ice/ice_dpll.c | 74 +++++++++++++++++++----
1 file changed, 63 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
index 3f8cd5b8298b57..d817f17dcf1951 100644
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
@@ -1154,6 +1154,30 @@ ice_dpll_input_state_get(const struct dpll_pin *pin, void *pin_priv,
extack, ICE_DPLL_PIN_TYPE_INPUT);
}
+/**
+ * ice_dpll_sw_pin_notify_peer - notify the paired SW pin after a state change
+ * @d: pointer to dplls struct
+ * @changed: the SW pin that was explicitly changed (already notified by dpll core)
+ *
+ * SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1 and
+ * SMA2/U.FL2). When one pin's routing changes via the PCA9575 GPIO
+ * expander, the paired pin's state may also change. Send a change
+ * notification for the peer pin so userspace consumers monitoring the
+ * peer via dpll netlink learn about the update.
+ *
+ * Context: Can be called under pf->dplls.lock, dpll_pin_change_ntf() is safe.
+ */
+static void ice_dpll_sw_pin_notify_peer(struct ice_dplls *d,
+ struct ice_dpll_pin *changed)
+{
+ struct ice_dpll_pin *peer;
+
+ peer = (changed >= d->sma && changed < d->sma + ICE_DPLL_PIN_SW_NUM) ?
+ &d->ufl[changed->idx] : &d->sma[changed->idx];
+ if (peer->pin)
+ dpll_pin_change_ntf(peer->pin);
+}
+
/**
* ice_dpll_sma_direction_set - set direction of SMA pin
* @p: pointer to a pin
@@ -1233,6 +1257,8 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p,
ret = ice_dpll_pin_state_update(p->pf, target,
type, extack);
}
+ if (!ret)
+ ice_dpll_sw_pin_notify_peer(d, p);
return ret;
}
@@ -1334,6 +1360,7 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
extack);
if (ret)
goto unlock;
+ ice_dpll_sw_pin_notify_peer(&pf->dplls, p);
if (enable)
ret = ice_dpll_pin_enable(hw, target, d->dpll_idx, type, extack);
@@ -1963,7 +1990,10 @@ ice_dpll_phase_offset_get(const struct dpll_pin *pin, void *pin_priv,
d->active_input == p->input->pin))
*phase_offset = d->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR;
else if (d->phase_offset_monitor_period)
- *phase_offset = p->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR;
+ *phase_offset = (p->input &&
+ p->direction == DPLL_PIN_DIRECTION_INPUT ?
+ p->input->phase_offset :
+ p->phase_offset) * ICE_DPLL_PHASE_OFFSET_FACTOR;
else
*phase_offset = 0;
mutex_unlock(&pf->dplls.lock);
@@ -2657,6 +2687,27 @@ static u64 ice_generate_clock_id(struct ice_pf *pf)
return pci_get_dsn(pf->pdev);
}
+/**
+ * ice_dpll_pin_ntf - notify pin change including any SW pin wrappers
+ * @dplls: pointer to dplls struct
+ * @pin: the dpll_pin that changed
+ *
+ * Send a change notification for @pin and for any registered SMA/U.FL pin
+ * whose backing CGU input matches @pin.
+ */
+static void ice_dpll_pin_ntf(struct ice_dplls *dplls, struct dpll_pin *pin)
+{
+ dpll_pin_change_ntf(pin);
+ for (int i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) {
+ if (dplls->sma[i].pin && dplls->sma[i].input &&
+ dplls->sma[i].input->pin == pin)
+ dpll_pin_change_ntf(dplls->sma[i].pin);
+ if (dplls->ufl[i].pin && dplls->ufl[i].input &&
+ dplls->ufl[i].input->pin == pin)
+ dpll_pin_change_ntf(dplls->ufl[i].pin);
+ }
+}
+
/**
* ice_dpll_notify_changes - notify dpll subsystem about changes
* @d: pointer do dpll
@@ -2665,6 +2716,7 @@ static u64 ice_generate_clock_id(struct ice_pf *pf)
*/
static void ice_dpll_notify_changes(struct ice_dpll *d)
{
+ struct ice_dplls *dplls = &d->pf->dplls;
bool pin_notified = false;
if (d->prev_dpll_state != d->dpll_state) {
@@ -2673,17 +2725,17 @@ static void ice_dpll_notify_changes(struct ice_dpll *d)
}
if (d->prev_input != d->active_input) {
if (d->prev_input)
- dpll_pin_change_ntf(d->prev_input);
+ ice_dpll_pin_ntf(dplls, d->prev_input);
d->prev_input = d->active_input;
if (d->active_input) {
- dpll_pin_change_ntf(d->active_input);
+ ice_dpll_pin_ntf(dplls, d->active_input);
pin_notified = true;
}
}
if (d->prev_phase_offset != d->phase_offset) {
d->prev_phase_offset = d->phase_offset;
if (!pin_notified && d->active_input)
- dpll_pin_change_ntf(d->active_input);
+ ice_dpll_pin_ntf(dplls, d->active_input);
}
}
@@ -2712,6 +2764,7 @@ static bool ice_dpll_is_pps_phase_monitor(struct ice_pf *pf)
/**
* ice_dpll_pins_notify_mask - notify dpll subsystem about bulk pin changes
+ * @dplls: pointer to dplls struct
* @pins: array of ice_dpll_pin pointers registered within dpll subsystem
* @pin_num: number of pins
* @phase_offset_ntf_mask: bitmask of pin indexes to notify
@@ -2721,15 +2774,14 @@ static bool ice_dpll_is_pps_phase_monitor(struct ice_pf *pf)
*
* Context: Must be called while pf->dplls.lock is released.
*/
-static void ice_dpll_pins_notify_mask(struct ice_dpll_pin *pins,
+static void ice_dpll_pins_notify_mask(struct ice_dplls *dplls,
+ struct ice_dpll_pin *pins,
u8 pin_num,
u32 phase_offset_ntf_mask)
{
- int i = 0;
-
- for (i = 0; i < pin_num; i++)
- if (phase_offset_ntf_mask & (1 << i))
- dpll_pin_change_ntf(pins[i].pin);
+ for (int i = 0; i < pin_num; i++)
+ if (phase_offset_ntf_mask & BIT(i))
+ ice_dpll_pin_ntf(dplls, pins[i].pin);
}
/**
@@ -2905,7 +2957,7 @@ static void ice_dpll_periodic_work(struct kthread_work *work)
ice_dpll_notify_changes(de);
ice_dpll_notify_changes(dp);
if (phase_offset_ntf)
- ice_dpll_pins_notify_mask(d->inputs, d->num_inputs,
+ ice_dpll_pins_notify_mask(d, d->inputs, d->num_inputs,
phase_offset_ntf);
resched:
--
2.52.0
^ permalink raw reply related
* Re: [PATCH net v2 2/2] net: phy: micrel: remove ksz9131_resume()
From: Russell King (Oracle) @ 2026-04-09 10:29 UTC (permalink / raw)
To: Biju Das
Cc: Ovidiu Panait, andrew@lunn.ch, hkallweit1@gmail.com,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org
In-Reply-To: <TY3PR01MB11346A0F047F1F7296B8F4FCA86582@TY3PR01MB11346.jpnprd01.prod.outlook.com>
On Thu, Apr 09, 2026 at 10:13:10AM +0000, Biju Das wrote:
> Hi Ovidu,
>
> Thanks for the patch.
>
> > -----Original Message-----
> > From: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
> > Sent: 09 April 2026 10:57
> > Subject: [PATCH net v2 2/2] net: phy: micrel: remove ksz9131_resume()
> >
> > ksz9131_resume() was added to restore RGMII delays on resume for platforms where the PHY loses power
> > during suspend to RAM. However, for s2idle, the PHY stays in Software Power-Down (SPD) during resume.
> > In that case,
> > ksz9131_config_rgmii_delay() accesses MMD registers before kszphy_resume() clears BMCR_PDOWN. The
> > KSZ9131 datasheet states that during SPD, access to the MMD registers is restricted:
> >
> > - Only access to the standard registers (0 through 31) is supported.
> > - Access to MMD address spaces other than MMD address space 1 is
> > possible if the spd_clock_gate_override bit is set.
> > - Access to MMD address space 1 is not possible.
> >
> > Additionally, only RGMII delays were restored, while other settings from ksz9131_config_init() were
> > not.
> >
> > Now that the preceding commit ("net: phylink: call phy_init_hw() in phylink resume path") performs a
> > phy_init_hw() during phylink resume,
> > ksz9131_resume() is no longer needed.
> >
> > Remove it and use kszphy_resume() directly.
>
> How to avoid code duplication in this case?
>
> For eg: phy_init_hw() makes the phy out of SPD state
>
> and kszphy_resume() unconditionally makes the phy out of SPD state again.
> ¬ kszphy_generic_resume
> ¬ genphy_resume
My question would be... if we mandate that phy_init_hw() must be called
before phy_resume() by MAC drivers, then how much of kszphy_resume()
becomes redundant?
Given that populating drv->soft_reset() with genphy_soft_reset() means
the PDOWN bit will be cleared, genphy_resume() becomes redundant.
phy_init_hw() will also call drv->config_intr(), so that doesn't need
to be done either.
It will also call drv->config_init(), which will call
kszphy_config_reset().
So most of kszphy_resume() becomes unnecessary. I think the only thing
that remains would be the call to kszphy_enable_clk() - and is it fine
to call that after phy_init_hw() ?
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply
* Re: [PATCH net-next v7 0/2] r8152: Add support for the RTL8157 5Gbit USB Ethernet chip
From: patchwork-bot+netdevbpf @ 2026-04-09 10:30 UTC (permalink / raw)
To: Birger Koblitz
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, linux-usb, netdev,
linux-kernel, hsu.chih.kai
In-Reply-To: <20260404-rtl8157_next-v7-0-039121318f23@birger-koblitz.de>
Hello:
This series was applied to netdev/net-next.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Sat, 04 Apr 2026 09:57:41 +0200 you wrote:
> Add support for the RTL8157, which is a 5GBit USB-Ethernet adapter
> chip in the RTL815x family of chips.
>
> The RTL8157 uses a different frame descriptor format, and different
> SRAM/ADV access methods, plus offers 5GBit/s Ethernet, so support for these
> features is added in addition to chip initialization and configuration.
>
> [...]
Here is the summary with links:
- [net-next,v7,1/2] r8152: Add support for 5Gbit Link Speeds and EEE
https://git.kernel.org/netdev/net-next/c/ebe5fd2ed20a
- [net-next,v7,2/2] r8152: Add support for the RTL8157 hardware
https://git.kernel.org/netdev/net-next/c/fd3c7d080df5
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net v2 1/2] net: phylink: call phy_init_hw() in phylink resume path
From: Russell King (Oracle) @ 2026-04-09 10:42 UTC (permalink / raw)
To: Ovidiu Panait
Cc: andrew, hkallweit1, davem, edumazet, kuba, pabeni, biju.das.jz,
netdev, linux-kernel, linux-renesas-soc
In-Reply-To: <20260409095633.70973-2-ovidiu.panait.rb@renesas.com>
On Thu, Apr 09, 2026 at 09:56:32AM +0000, Ovidiu Panait wrote:
> When mac_managed_pm flag is set, mdio_bus_phy_resume() is skipped,
> so phy_init_hw(), which performs soft_reset and config_init, is not
> called during resume.
>
> This is inconsistent with the non-mac_managed_pm path, where
> mdio_bus_phy_resume() calls phy_init_hw() before phy_resume()
> on every resume.
>
> Add phy_init_hw() calls in both phylink_prepare_resume() and
> phylink_resume(), to ensure that the PHY state is the same as
> when the PHY is resumed via the MDIO bus.
>
> Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
> ---
> drivers/net/phy/phylink.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
> index 087ac63f9193..c302126009f6 100644
> --- a/drivers/net/phy/phylink.c
> +++ b/drivers/net/phy/phylink.c
> @@ -2669,8 +2669,10 @@ void phylink_prepare_resume(struct phylink *pl)
> * then resume the PHY. Note that 802.3 allows PHYs 500ms before
> * the clock meets requirements. We do not implement this delay.
> */
> - if (pl->config->mac_requires_rxc && phydev && phydev->suspended)
> + if (pl->config->mac_requires_rxc && phydev && phydev->suspended) {
> + phy_init_hw(phydev);
> phy_resume(phydev);
I'm going to make an alternative suggestion - should we combine
phy_init_hw() and phy_resume() to ensure that all MAC drivers that
call phy_resume() correctly initialise the PHY first?
Looking at the callers of phy_resume():
- drivers/net/ethernet/nxp/lpc_eth.c - calls phy_resume() from
lpc_eth_open() but no call to phy_init_hw(). Not used in
suspend/resume paths, so presumably uses the built-in phylib
handling that does call phy_init_hw() before phy_resume().
- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c - suspends
and then immediately resumes the PHY before enabling loopback. Seems
like a PHY workaround that should've been handled in the PHY driver.
Suspends the PHY when loopback is disabled (which looks buggy.)
- drivers/net/ethernet/hisilicon/hns/hns_ethtool.c - resumes the PHY
when enabling loopback and suspends the PHY when loopback is
disabled. (what if the netdev is already up? Also looks buggy to me.)
- drivers/net/ethernet/broadcom/genet/bcmgenet.c - bcmgenet_resume()
calls phy_init_hw() before a conditional call to phy_resume(). I
don't see a matching call to phy_suspend(). If the bcmgenet device
may wakeup the system, then wouldn't the PHY configuration be
preserved over suspend/resume making the call to phy_init_hw() also
unnecessary if device_may_wakeup(d) returns true?
- drivers/net/ethernet/broadcom/bcmsysport.c - no call to phy_init_hw()
before phy_resume().
- drivers/net/ethernet/realtek/r8169_main.c - calls phy_init_hw()
immediately before phy_resume().
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox