Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next 00/15] net: enetc: Prepare for ENETC v4 VF support
@ 2026-05-11  8:07 Wei Fang
  2026-05-11  8:07 ` [PATCH net-next 01/15] net: enetc: switch VF primary MAC setter to PF ops for commonization Wei Fang
                   ` (14 more replies)
  0 siblings, 15 replies; 18+ messages in thread
From: Wei Fang @ 2026-05-11  8:07 UTC (permalink / raw)
  To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
	davem, edumazet, kuba, pabeni
  Cc: imx, netdev, linux-kernel

This patch series refactors and extends the ENETC driver infrastructure
to prepare for upcoming ENETC v4 Virtual Function (VF) support. The main
focus is on code commonization, improved VF-PF communication, and dynamic
resource allocation.

The ENETC IP has evolved across different revisions, and the existing
driver architecture was primarily designed around v1 hardware. To support
v4 VFs efficiently, we need to share common code between PF drivers of
different IP versions while maintaining compatibility.

Key changes in this series:

1. VF-PF Messaging Infrastructure:
   - Convert mailbox messages to new formats
   - Use read_poll_timeout() for simplifying VF mailbox polling
   - Avoid mailbox timeouts during SR-IOV teardown
   - Add support for IP minor revision query via messaging

2. Code Commonization:
   - Relocate SR-IOV configuration helpers to common PF code
   - Move VF message handlers to dedicated enetc_msg.c
   - Integrate enetc_msg.c into enetc-pf-common driver
   - Switch VF primary MAC setter to PF ops for sharing

3. CBDR (Control Buffer Descriptor Ring) Improvements:
   - Align v1 CBDR API with v4 for VF driver sharing
   - Add CBDR setup/teardown hooks to enetc_si_ops

4. Dynamic Resource Management:
   - Dynamically allocate rxmsg based on actual VF count
   - Generate MR interrupt mask based on enabled VFs
   - Refactor MR interrupt enable/disable helpers
   - Use MADDR_TYPE constant for MAC filter array sizing

5. Generic SR-IOV Initialization:
   - Add generic helper to initialize SR-IOV resources

This refactoring lays the groundwork for cleanly integrating ENETC v4 VF
support in subsequent patch series, allowing code reuse between v1 and v4
PF drivers while maintaining a clean separation of version-specific
logic.

Wei Fang (15):
  net: enetc: switch VF primary MAC setter to PF ops for commonization
  net: enetc: move VF message handlers to enetc_msg.c
  net: enetc: avoid VF->PF mailbox timeout during SR-IOV teardown
  net: enetc: relocate SR-IOV configuration helper for common PF support
  net: enetc: integrate enetc_msg.c into enetc-pf-common driver
  net: enetc: use read_poll_timeout() for VF mailbox polling
  net: enetc: convert mailbox messages to new formats
  net: enetc: add VF-PF messaging support for IP minor revision query
  net: enetc: align v1 CBDR API with v4 for VF driver sharing
  net: enetc: add CBDR setup/teardown hooks to enetc_si_ops for VF
    support
  net: enetc: add generic helper to initialize SR-IOV resources
  net: enetc: use MADDR_TYPE for MAC filter array size
  net: enetc: dynamically allocate rxmsg based on VF count
  net: enetc: refactor MR interrupt enable/disable helpers
  net: enetc: generate MR interrupt mask based on the number of enabled
    VFs

 drivers/net/ethernet/freescale/enetc/Kconfig  |   2 +
 drivers/net/ethernet/freescale/enetc/Makefile |   2 +-
 drivers/net/ethernet/freescale/enetc/enetc.h  |  22 +-
 .../net/ethernet/freescale/enetc/enetc4_pf.c  |   4 -
 .../net/ethernet/freescale/enetc/enetc_cbdr.c |  16 +-
 .../net/ethernet/freescale/enetc/enetc_hw.h   |   4 +-
 .../ethernet/freescale/enetc/enetc_mailbox.h  | 177 ++++++++++++++
 .../net/ethernet/freescale/enetc/enetc_msg.c  | 217 ++++++++++++++++--
 .../net/ethernet/freescale/enetc/enetc_pf.c   | 109 +--------
 .../net/ethernet/freescale/enetc/enetc_pf.h   |  10 +-
 .../freescale/enetc/enetc_pf_common.c         |  24 ++
 .../freescale/enetc/enetc_pf_common.h         |  10 +
 .../net/ethernet/freescale/enetc/enetc_vf.c   | 162 ++++++++++---
 13 files changed, 559 insertions(+), 200 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_mailbox.h

-- 
2.34.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH net-next 01/15] net: enetc: switch VF primary MAC setter to PF ops for commonization
  2026-05-11  8:07 [PATCH net-next 00/15] net: enetc: Prepare for ENETC v4 VF support Wei Fang
@ 2026-05-11  8:07 ` Wei Fang
  2026-05-11 15:41   ` Vladimir Oltean
  2026-05-11  8:07 ` [PATCH net-next 02/15] net: enetc: move VF message handlers to enetc_msg.c Wei Fang
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 18+ messages in thread
From: Wei Fang @ 2026-05-11  8:07 UTC (permalink / raw)
  To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
	davem, edumazet, kuba, pabeni
  Cc: imx, netdev, linux-kernel

Use pf->ops->set_si_primary_mac() instead of direct call to
enetc_pf_set_primary_mac_addr() in preparation for moving
enetc_msg_pf_set_vf_primary_mac_addr() to enetc-pf-common.

This enables both ENETC v1 and v4 PF drivers to share the VF MAC
configuration interface. No functional change.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 drivers/net/ethernet/freescale/enetc/enetc_pf.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index a12fd54a475f..9063255d8ca5 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -497,7 +497,7 @@ static u16 enetc_msg_pf_set_vf_primary_mac_addr(struct enetc_pf *pf,
 		dev_warn(dev, "Attempt to override PF set mac addr for VF%d\n",
 			 vf_id);
 	else
-		enetc_pf_set_primary_mac_addr(&pf->si->hw, vf_id + 1, addr);
+		pf->ops->set_si_primary_mac(&pf->si->hw, vf_id + 1, addr);
 
 	return ENETC_MSG_CMD_STATUS_OK;
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next 02/15] net: enetc: move VF message handlers to enetc_msg.c
  2026-05-11  8:07 [PATCH net-next 00/15] net: enetc: Prepare for ENETC v4 VF support Wei Fang
  2026-05-11  8:07 ` [PATCH net-next 01/15] net: enetc: switch VF primary MAC setter to PF ops for commonization Wei Fang
@ 2026-05-11  8:07 ` Wei Fang
  2026-05-11  8:07 ` [PATCH net-next 03/15] net: enetc: avoid VF->PF mailbox timeout during SR-IOV teardown Wei Fang
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Wei Fang @ 2026-05-11  8:07 UTC (permalink / raw)
  To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
	davem, edumazet, kuba, pabeni
  Cc: imx, netdev, linux-kernel

Move enetc_msg_pf_set_vf_primary_mac_addr() and enetc_msg_handle_rxmsg()
to enetc_msg.c to consolidate VF mailbox message handling logic.

Make enetc_msg_handle_rxmsg() static since it's only called from
enetc_msg_task() within the same file.

This prepares for integrating enetc_msg.c into the enetc-pf-common
driver to be shared between ENETC v1 and v4 PF drivers.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 .../net/ethernet/freescale/enetc/enetc_msg.c  | 47 +++++++++++++++++++
 .../net/ethernet/freescale/enetc/enetc_pf.c   | 47 -------------------
 .../net/ethernet/freescale/enetc/enetc_pf.h   |  1 -
 3 files changed, 47 insertions(+), 48 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc_msg.c b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
index 40d22ebe9224..81d1b87055a3 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_msg.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
@@ -28,6 +28,53 @@ static irqreturn_t enetc_msg_psi_msix(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+/* Messaging */
+static u16 enetc_msg_pf_set_vf_primary_mac_addr(struct enetc_pf *pf,
+						int vf_id)
+{
+	struct enetc_vf_state *vf_state = &pf->vf_state[vf_id];
+	struct enetc_msg_swbd *msg = &pf->rxmsg[vf_id];
+	struct enetc_msg_cmd_set_primary_mac *cmd;
+	struct device *dev = &pf->si->pdev->dev;
+	u16 cmd_id;
+	char *addr;
+
+	cmd = (struct enetc_msg_cmd_set_primary_mac *)msg->vaddr;
+	cmd_id = cmd->header.id;
+	if (cmd_id != ENETC_MSG_CMD_MNG_ADD)
+		return ENETC_MSG_CMD_STATUS_FAIL;
+
+	addr = cmd->mac.sa_data;
+	if (vf_state->flags & ENETC_VF_FLAG_PF_SET_MAC)
+		dev_warn(dev, "Attempt to override PF set mac addr for VF%d\n",
+			 vf_id);
+	else
+		pf->ops->set_si_primary_mac(&pf->si->hw, vf_id + 1, addr);
+
+	return ENETC_MSG_CMD_STATUS_OK;
+}
+
+static void enetc_msg_handle_rxmsg(struct enetc_pf *pf, int vf_id, u16 *status)
+{
+	struct enetc_msg_swbd *msg = &pf->rxmsg[vf_id];
+	struct device *dev = &pf->si->pdev->dev;
+	struct enetc_msg_cmd_header *cmd_hdr;
+	u16 cmd_type;
+
+	*status = ENETC_MSG_CMD_STATUS_OK;
+	cmd_hdr = (struct enetc_msg_cmd_header *)msg->vaddr;
+	cmd_type = cmd_hdr->type;
+
+	switch (cmd_type) {
+	case ENETC_MSG_CMD_MNG_MAC:
+		*status = enetc_msg_pf_set_vf_primary_mac_addr(pf, vf_id);
+		break;
+	default:
+		dev_err(dev, "command not supported (cmd_type: 0x%x)\n",
+			cmd_type);
+	}
+}
+
 static void enetc_msg_task(struct work_struct *work)
 {
 	struct enetc_pf *pf = container_of(work, struct enetc_pf, msg_task);
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index 9063255d8ca5..b1620dc00146 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -476,53 +476,6 @@ static void enetc_configure_port(struct enetc_pf *pf)
 	enetc_port_wr(hw, ENETC_PMR, ENETC_PMR_EN);
 }
 
-/* Messaging */
-static u16 enetc_msg_pf_set_vf_primary_mac_addr(struct enetc_pf *pf,
-						int vf_id)
-{
-	struct enetc_vf_state *vf_state = &pf->vf_state[vf_id];
-	struct enetc_msg_swbd *msg = &pf->rxmsg[vf_id];
-	struct enetc_msg_cmd_set_primary_mac *cmd;
-	struct device *dev = &pf->si->pdev->dev;
-	u16 cmd_id;
-	char *addr;
-
-	cmd = (struct enetc_msg_cmd_set_primary_mac *)msg->vaddr;
-	cmd_id = cmd->header.id;
-	if (cmd_id != ENETC_MSG_CMD_MNG_ADD)
-		return ENETC_MSG_CMD_STATUS_FAIL;
-
-	addr = cmd->mac.sa_data;
-	if (vf_state->flags & ENETC_VF_FLAG_PF_SET_MAC)
-		dev_warn(dev, "Attempt to override PF set mac addr for VF%d\n",
-			 vf_id);
-	else
-		pf->ops->set_si_primary_mac(&pf->si->hw, vf_id + 1, addr);
-
-	return ENETC_MSG_CMD_STATUS_OK;
-}
-
-void enetc_msg_handle_rxmsg(struct enetc_pf *pf, int vf_id, u16 *status)
-{
-	struct enetc_msg_swbd *msg = &pf->rxmsg[vf_id];
-	struct device *dev = &pf->si->pdev->dev;
-	struct enetc_msg_cmd_header *cmd_hdr;
-	u16 cmd_type;
-
-	*status = ENETC_MSG_CMD_STATUS_OK;
-	cmd_hdr = (struct enetc_msg_cmd_header *)msg->vaddr;
-	cmd_type = cmd_hdr->type;
-
-	switch (cmd_type) {
-	case ENETC_MSG_CMD_MNG_MAC:
-		*status = enetc_msg_pf_set_vf_primary_mac_addr(pf, vf_id);
-		break;
-	default:
-		dev_err(dev, "command not supported (cmd_type: 0x%x)\n",
-			cmd_type);
-	}
-}
-
 #ifdef CONFIG_PCI_IOV
 static int enetc_sriov_configure(struct pci_dev *pdev, int num_vfs)
 {
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.h b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
index ae407e9e9ee7..84f8b58a18f2 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
@@ -70,4 +70,3 @@ struct enetc_pf {
 
 int enetc_msg_psi_init(struct enetc_pf *pf);
 void enetc_msg_psi_free(struct enetc_pf *pf);
-void enetc_msg_handle_rxmsg(struct enetc_pf *pf, int mbox_id, u16 *status);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next 03/15] net: enetc: avoid VF->PF mailbox timeout during SR-IOV teardown
  2026-05-11  8:07 [PATCH net-next 00/15] net: enetc: Prepare for ENETC v4 VF support Wei Fang
  2026-05-11  8:07 ` [PATCH net-next 01/15] net: enetc: switch VF primary MAC setter to PF ops for commonization Wei Fang
  2026-05-11  8:07 ` [PATCH net-next 02/15] net: enetc: move VF message handlers to enetc_msg.c Wei Fang
@ 2026-05-11  8:07 ` Wei Fang
  2026-05-11  8:07 ` [PATCH net-next 04/15] net: enetc: relocate SR-IOV configuration helper for common PF support Wei Fang
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Wei Fang @ 2026-05-11  8:07 UTC (permalink / raw)
  To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
	davem, edumazet, kuba, pabeni
  Cc: imx, netdev, linux-kernel

During SR-IOV teardown, enetc_msg_psi_free() disables the MR interrupt
before pci_disable_sriov() removes the VFs. If a VF sends a mailbox
message during this window, the PF cannot receive it, causing the VF to
timeout waiting for a reply.

Since the timeout occurs during SR-IOV teardown when the VF is about to
be removed anyway, it has no functional impact on operation. However,
more messages will be added in the future, some visible error logs may
confuse users. So fix it by calling pci_disable_sriov() first to remove
all VFs, then safely clean up the mailbox resources. This eliminates the
race window where VFs could send messages to an unresponsive PF.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 drivers/net/ethernet/freescale/enetc/enetc_pf.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index b1620dc00146..3ebc48c3fdf3 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -484,9 +484,9 @@ static int enetc_sriov_configure(struct pci_dev *pdev, int num_vfs)
 	int err;
 
 	if (!num_vfs) {
+		pci_disable_sriov(pdev);
 		enetc_msg_psi_free(pf);
 		pf->num_vfs = 0;
-		pci_disable_sriov(pdev);
 	} else {
 		pf->num_vfs = num_vfs;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next 04/15] net: enetc: relocate SR-IOV configuration helper for common PF support
  2026-05-11  8:07 [PATCH net-next 00/15] net: enetc: Prepare for ENETC v4 VF support Wei Fang
                   ` (2 preceding siblings ...)
  2026-05-11  8:07 ` [PATCH net-next 03/15] net: enetc: avoid VF->PF mailbox timeout during SR-IOV teardown Wei Fang
@ 2026-05-11  8:07 ` Wei Fang
  2026-05-11  8:07 ` [PATCH net-next 05/15] net: enetc: integrate enetc_msg.c into enetc-pf-common driver Wei Fang
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Wei Fang @ 2026-05-11  8:07 UTC (permalink / raw)
  To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
	davem, edumazet, kuba, pabeni
  Cc: imx, netdev, linux-kernel

Move enetc_sriov_configure() from enetc_pf.c to enetc_msg.c to prepare
for integrating enetc_msg.c into the enetc-pf-common driver, where it
will be shared between ENETC v1 and v4 PF drivers.

Since enetc_msg_psi_init() and enetc_msg_psi_free() are now only called
from enetc_sriov_configure() within the same file, make them static.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 .../net/ethernet/freescale/enetc/enetc_msg.c  | 40 ++++++++++++++++++-
 .../net/ethernet/freescale/enetc/enetc_pf.c   | 40 -------------------
 .../net/ethernet/freescale/enetc/enetc_pf.h   | 10 ++++-
 3 files changed, 46 insertions(+), 44 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc_msg.c b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
index 81d1b87055a3..6f7927f40bea 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_msg.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
@@ -151,7 +151,7 @@ static void enetc_msg_free_mbx(struct enetc_si *si, int idx)
 	enetc_wr(hw, ENETC_PSIVMSGRCVAR1(idx), 0);
 }
 
-int enetc_msg_psi_init(struct enetc_pf *pf)
+static int enetc_msg_psi_init(struct enetc_pf *pf)
 {
 	struct enetc_si *si = pf->si;
 	int vector, i, err;
@@ -193,7 +193,7 @@ int enetc_msg_psi_init(struct enetc_pf *pf)
 	return err;
 }
 
-void enetc_msg_psi_free(struct enetc_pf *pf)
+static void enetc_msg_psi_free(struct enetc_pf *pf)
 {
 	struct enetc_si *si = pf->si;
 	int i;
@@ -209,3 +209,39 @@ void enetc_msg_psi_free(struct enetc_pf *pf)
 	/* de-register message passing interrupt handler */
 	free_irq(pci_irq_vector(si->pdev, ENETC_SI_INT_IDX), si);
 }
+
+int enetc_sriov_configure(struct pci_dev *pdev, int num_vfs)
+{
+	struct enetc_si *si = pci_get_drvdata(pdev);
+	struct enetc_pf *pf = enetc_si_priv(si);
+	int err;
+
+	if (!num_vfs) {
+		pci_disable_sriov(pdev);
+		enetc_msg_psi_free(pf);
+		pf->num_vfs = 0;
+	} else {
+		pf->num_vfs = num_vfs;
+
+		err = enetc_msg_psi_init(pf);
+		if (err) {
+			dev_err(&pdev->dev, "enetc_msg_psi_init (%d)\n", err);
+			goto err_msg_psi;
+		}
+
+		err = pci_enable_sriov(pdev, num_vfs);
+		if (err) {
+			dev_err(&pdev->dev, "pci_enable_sriov err %d\n", err);
+			goto err_en_sriov;
+		}
+	}
+
+	return num_vfs;
+
+err_en_sriov:
+	enetc_msg_psi_free(pf);
+err_msg_psi:
+	pf->num_vfs = 0;
+
+	return err;
+}
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index 3ebc48c3fdf3..fea5cb6a1662 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -476,46 +476,6 @@ static void enetc_configure_port(struct enetc_pf *pf)
 	enetc_port_wr(hw, ENETC_PMR, ENETC_PMR_EN);
 }
 
-#ifdef CONFIG_PCI_IOV
-static int enetc_sriov_configure(struct pci_dev *pdev, int num_vfs)
-{
-	struct enetc_si *si = pci_get_drvdata(pdev);
-	struct enetc_pf *pf = enetc_si_priv(si);
-	int err;
-
-	if (!num_vfs) {
-		pci_disable_sriov(pdev);
-		enetc_msg_psi_free(pf);
-		pf->num_vfs = 0;
-	} else {
-		pf->num_vfs = num_vfs;
-
-		err = enetc_msg_psi_init(pf);
-		if (err) {
-			dev_err(&pdev->dev, "enetc_msg_psi_init (%d)\n", err);
-			goto err_msg_psi;
-		}
-
-		err = pci_enable_sriov(pdev, num_vfs);
-		if (err) {
-			dev_err(&pdev->dev, "pci_enable_sriov err %d\n", err);
-			goto err_en_sriov;
-		}
-	}
-
-	return num_vfs;
-
-err_en_sriov:
-	enetc_msg_psi_free(pf);
-err_msg_psi:
-	pf->num_vfs = 0;
-
-	return err;
-}
-#else
-#define enetc_sriov_configure(pdev, num_vfs)	(void)0
-#endif
-
 static int enetc_pf_set_features(struct net_device *ndev,
 				 netdev_features_t features)
 {
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.h b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
index 84f8b58a18f2..44cfb7bdd7e8 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
@@ -68,5 +68,11 @@ struct enetc_pf {
 #define phylink_to_enetc_pf(config) \
 	container_of((config), struct enetc_pf, phylink_config)
 
-int enetc_msg_psi_init(struct enetc_pf *pf);
-void enetc_msg_psi_free(struct enetc_pf *pf);
+#if IS_ENABLED(CONFIG_PCI_IOV)
+int enetc_sriov_configure(struct pci_dev *pdev, int num_vfs);
+#else
+static inline int enetc_sriov_configure(struct pci_dev *pdev, int num_vfs)
+{
+	return 0;
+}
+#endif
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next 05/15] net: enetc: integrate enetc_msg.c into enetc-pf-common driver
  2026-05-11  8:07 [PATCH net-next 00/15] net: enetc: Prepare for ENETC v4 VF support Wei Fang
                   ` (3 preceding siblings ...)
  2026-05-11  8:07 ` [PATCH net-next 04/15] net: enetc: relocate SR-IOV configuration helper for common PF support Wei Fang
@ 2026-05-11  8:07 ` Wei Fang
  2026-05-11  8:07 ` [PATCH net-next 06/15] net: enetc: use read_poll_timeout() for VF mailbox polling Wei Fang
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Wei Fang @ 2026-05-11  8:07 UTC (permalink / raw)
  To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
	davem, edumazet, kuba, pabeni
  Cc: imx, netdev, linux-kernel

Move enetc_msg.c from the fsl-enetc driver to the nxp-enetc-pf-common
driver so that SR-IOV mailbox handling can be shared between ENETC v1
and v4 PF drivers.

Changes:
- Move enetc_msg.o compilation from fsl-enetc to nxp-enetc-pf-common
- Export enetc_sriov_configure() with EXPORT_SYMBOL_GPL for use by
  both PF drivers
- Move enetc_sriov_configure() declaration from enetc_pf.h to
  enetc_pf_common.h
- Update enetc_msg.c to include enetc_pf_common.h instead of enetc_pf.h

The fsl-enetc driver now depends on nxp-enetc-pf-common for SR-IOV
functionality.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 drivers/net/ethernet/freescale/enetc/Makefile          | 2 +-
 drivers/net/ethernet/freescale/enetc/enetc_msg.c       | 3 ++-
 drivers/net/ethernet/freescale/enetc/enetc_pf.h        | 9 ---------
 drivers/net/ethernet/freescale/enetc/enetc_pf_common.h | 9 +++++++++
 4 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/Makefile b/drivers/net/ethernet/freescale/enetc/Makefile
index f1c5ad45fd76..10ab6694c314 100644
--- a/drivers/net/ethernet/freescale/enetc/Makefile
+++ b/drivers/net/ethernet/freescale/enetc/Makefile
@@ -5,13 +5,13 @@ fsl-enetc-core-y := enetc.o enetc_cbdr.o enetc_ethtool.o
 
 obj-$(CONFIG_NXP_ENETC_PF_COMMON) += nxp-enetc-pf-common.o
 nxp-enetc-pf-common-y := enetc_pf_common.o
+nxp-enetc-pf-common-$(CONFIG_PCI_IOV) += enetc_msg.o
 
 obj-$(CONFIG_NXP_NETC_LIB) += nxp-netc-lib.o
 nxp-netc-lib-y := ntmp.o
 
 obj-$(CONFIG_FSL_ENETC) += fsl-enetc.o
 fsl-enetc-y := enetc_pf.o
-fsl-enetc-$(CONFIG_PCI_IOV) += enetc_msg.o
 fsl-enetc-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o
 
 obj-$(CONFIG_NXP_ENETC4) += nxp-enetc4.o
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_msg.c b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
index 6f7927f40bea..a137fa1e6f20 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_msg.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /* Copyright 2017-2019 NXP */
 
-#include "enetc_pf.h"
+#include "enetc_pf_common.h"
 
 static void enetc_msg_disable_mr_int(struct enetc_hw *hw)
 {
@@ -245,3 +245,4 @@ int enetc_sriov_configure(struct pci_dev *pdev, int num_vfs)
 
 	return err;
 }
+EXPORT_SYMBOL_GPL(enetc_sriov_configure);
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.h b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
index 44cfb7bdd7e8..731d56bad5fc 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
@@ -67,12 +67,3 @@ struct enetc_pf {
 
 #define phylink_to_enetc_pf(config) \
 	container_of((config), struct enetc_pf, phylink_config)
-
-#if IS_ENABLED(CONFIG_PCI_IOV)
-int enetc_sriov_configure(struct pci_dev *pdev, int num_vfs);
-#else
-static inline int enetc_sriov_configure(struct pci_dev *pdev, int num_vfs)
-{
-	return 0;
-}
-#endif
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
index 96d4840a3107..548323d29f36 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
@@ -20,3 +20,12 @@ static inline u16 enetc_get_ip_revision(struct enetc_hw *hw)
 {
 	return enetc_global_rd(hw, ENETC_G_EIPBRR0) & EIPBRR0_REVISION;
 }
+
+#if IS_ENABLED(CONFIG_PCI_IOV)
+int enetc_sriov_configure(struct pci_dev *pdev, int num_vfs);
+#else
+static inline int enetc_sriov_configure(struct pci_dev *pdev, int num_vfs)
+{
+	return 0;
+}
+#endif
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next 06/15] net: enetc: use read_poll_timeout() for VF mailbox polling
  2026-05-11  8:07 [PATCH net-next 00/15] net: enetc: Prepare for ENETC v4 VF support Wei Fang
                   ` (4 preceding siblings ...)
  2026-05-11  8:07 ` [PATCH net-next 05/15] net: enetc: integrate enetc_msg.c into enetc-pf-common driver Wei Fang
@ 2026-05-11  8:07 ` Wei Fang
  2026-05-11  8:07 ` [PATCH net-next 07/15] net: enetc: convert mailbox messages to new formats Wei Fang
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Wei Fang @ 2026-05-11  8:07 UTC (permalink / raw)
  To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
	davem, edumazet, kuba, pabeni
  Cc: imx, netdev, linux-kernel

Replace the manual do-while polling loop in enetc_msg_vsi_send() with
the standard read_poll_timeout() helper to simplify the code.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 .../net/ethernet/freescale/enetc/enetc_vf.c    | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
index df8e95cc47d0..669eb939e33c 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
@@ -28,8 +28,8 @@ static void enetc_msg_dma_free(struct device *dev, struct enetc_msg_swbd *msg)
 static int enetc_msg_vsi_send(struct enetc_si *si, struct enetc_msg_swbd *msg)
 {
 	struct device *dev = &si->pdev->dev;
-	int timeout = 100;
 	u32 vsimsgsr;
+	int err;
 
 	/* The VSI mailbox may be busy if last message was not yet processed
 	 * by PSI. So need to check the mailbox status before sending.
@@ -48,19 +48,13 @@ static int enetc_msg_vsi_send(struct enetc_si *si, struct enetc_msg_swbd *msg)
 	enetc_msg_dma_free(dev, &si->msg);
 	si->msg = *msg;
 	enetc_msg_vsi_write_msg(&si->hw, msg);
-
-	do {
-		vsimsgsr = enetc_rd(&si->hw, ENETC_VSIMSGSR);
-		if (!(vsimsgsr & ENETC_VSIMSGSR_MB))
-			break;
-
-		usleep_range(1000, 2000);
-	} while (--timeout);
-
-	if (!timeout) {
+	err = read_poll_timeout(enetc_rd, vsimsgsr,
+				!(vsimsgsr & ENETC_VSIMSGSR_MB),
+				1000, 200000, false, &si->hw, ENETC_VSIMSGSR);
+	if (err) {
 		dev_err(dev, "VSI mailbox timeout\n");
 
-		return -ETIMEDOUT;
+		return err;
 	}
 
 	/* check for message delivery error */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next 07/15] net: enetc: convert mailbox messages to new formats
  2026-05-11  8:07 [PATCH net-next 00/15] net: enetc: Prepare for ENETC v4 VF support Wei Fang
                   ` (5 preceding siblings ...)
  2026-05-11  8:07 ` [PATCH net-next 06/15] net: enetc: use read_poll_timeout() for VF mailbox polling Wei Fang
@ 2026-05-11  8:07 ` Wei Fang
  2026-05-11  8:07 ` [PATCH net-next 08/15] net: enetc: add VF-PF messaging support for IP minor revision query Wei Fang
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Wei Fang @ 2026-05-11  8:07 UTC (permalink / raw)
  To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
	davem, edumazet, kuba, pabeni
  Cc: imx, netdev, linux-kernel

On the LS1028A platform, the PF-VF mailbox was only used to update the
VF's MAC address. The original message format is minimal, lacks a clear
structure, and provides no means for the receiver to validate message
integrity, making it difficult to extend for new features.

With the introduction of i.MX ENETC v4, the interaction between PF and
VF has become significantly more complex. Typical deployments now include
scenarios where the PF is controlled by an M core while the VF is driven
by either the Linux kernel or DPDK, or where the PF is controlled by the
Linux kernel while the VF is controlled by DPDK. These heterogeneous
driver combinations require a unified and extensible message format to
ensure compatibility across different operating environments.

This patch introduces a newly defined PF-VF message structure and
converts the existing MAC-update mechanism to use the new format. The
redesigned message layout provides:

  - extensibility to support future PF-VF features on ENETC v4,
  - consistent framing for all message types,
  - improved data integrity checking,
  - a common protocol usable across Linux, M core firmware, and DPDK.

Additional PF-VF message types will be added in subsequent patches.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 drivers/net/ethernet/freescale/enetc/Kconfig  |   2 +
 drivers/net/ethernet/freescale/enetc/enetc.h  |  15 +-
 .../net/ethernet/freescale/enetc/enetc4_pf.c  |   4 -
 .../ethernet/freescale/enetc/enetc_mailbox.h  | 153 ++++++++++++++++++
 .../net/ethernet/freescale/enetc/enetc_msg.c  | 107 +++++++++---
 .../net/ethernet/freescale/enetc/enetc_vf.c   |  88 +++++++---
 6 files changed, 306 insertions(+), 63 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_mailbox.h

diff --git a/drivers/net/ethernet/freescale/enetc/Kconfig b/drivers/net/ethernet/freescale/enetc/Kconfig
index 117038104b69..0e338b33bc85 100644
--- a/drivers/net/ethernet/freescale/enetc/Kconfig
+++ b/drivers/net/ethernet/freescale/enetc/Kconfig
@@ -37,6 +37,7 @@ config FSL_ENETC
 	select PHYLINK
 	select PCS_LYNX
 	select DIMLIB
+	select CRC_ITU_T
 	help
 	  This driver supports NXP ENETC gigabit ethernet controller PCIe
 	  physical function (PF) devices, managing ENETC Ports at a privileged
@@ -70,6 +71,7 @@ config FSL_ENETC_VF
 	select FSL_ENETC_MDIO
 	select PHYLINK
 	select DIMLIB
+	select CRC_ITU_T
 	help
 	  This driver supports NXP ENETC gigabit ethernet controller PCIe
 	  virtual function (VF) devices enabled by the ENETC PF driver.
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
index e691144e8756..b70b625328ea 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc.h
@@ -16,6 +16,7 @@
 
 #include "enetc_hw.h"
 #include "enetc4_hw.h"
+#include "enetc_mailbox.h"
 
 #define ENETC_MAC_MAXFRM_SIZE	9600
 #define ENETC_MAX_MTU		(ENETC_MAC_MAXFRM_SIZE - \
@@ -257,12 +258,6 @@ static inline union enetc_rx_bd *enetc_rxbd_ext(union enetc_rx_bd *rxbd)
 	return ++rxbd;
 }
 
-struct enetc_msg_swbd {
-	void *vaddr;
-	dma_addr_t dma;
-	int size;
-};
-
 #define ENETC_REV1	0x1
 #define ENETC_REV4	0x4
 
@@ -490,14 +485,6 @@ struct enetc_ndev_priv {
 	u64 sysclk_freq; /* NETC system clock frequency */
 };
 
-/* Messaging */
-
-/* VF-PF set primary MAC address message format */
-struct enetc_msg_cmd_set_primary_mac {
-	struct enetc_msg_cmd_header header;
-	struct sockaddr mac;
-};
-
 #define ENETC_CBD(R, i)	(&(((struct enetc_cbd *)((R).bd_base))[i]))
 
 #define ENETC_CBDR_TIMEOUT	1000 /* usecs */
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
index 56899f2254aa..4e771f852358 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
@@ -17,10 +17,6 @@
 #define ENETC_MAC_FILTER_TYPE_ALL	(ENETC_MAC_FILTER_TYPE_UC | \
 					 ENETC_MAC_FILTER_TYPE_MC)
 
-struct enetc_mac_addr {
-	u8 addr[ETH_ALEN];
-};
-
 static void enetc4_get_port_caps(struct enetc_pf *pf)
 {
 	struct enetc_hw *hw = &pf->si->hw;
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_mailbox.h b/drivers/net/ethernet/freescale/enetc/enetc_mailbox.h
new file mode 100644
index 000000000000..260c7333d93a
--- /dev/null
+++ b/drivers/net/ethernet/freescale/enetc/enetc_mailbox.h
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+/*
+ * Copyright 2025-2026 NXP
+ *
+ * The VSI-to-PSI message generic format:
+ *
+ * OFFSET  0                               16              24            31
+ *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  0x0   |       CRC16 (big-endian)      |    CLASS ID   |     CMD ID    |
+ *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  0x4   |   PROTO VER   |      LEN      |    RESV       | COOKIE|  RESV |
+ *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  0x8   |                              RESV                             |
+ *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  0xc   |                              RESV                             |
+ *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  0x10  |                                                               |
+ *  0x14  |                                                               |
+ *  0x18  |                          Message Body                         |
+ *  0x1c  |                                                               |
+ *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  0x20  |                                                               |
+ *    ~   |              Extended Message Body: LEN x 32B                 |
+ *  0x3e0 |                                                               |
+ *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * Field Descriptions:
+ * CRC16 (16-bit): Big endian, CRC16 CCITT-FALSE algorithm, It provides the
+ * equivalent data integrity check functionality as the FCS for standard
+ * Ethernet frames.
+ *
+ * CLASS ID (8-bit) and CMD ID (8-bit): These are 8-bit fields identifying
+ * the command class and the class-specific operations supported. For more
+ * details, please refer to the definitions of the relevant class ID and
+ * cmd ID in this document.
+ *
+ * PROTO VER (8-bit): Supported VSI-PSI command protocol version. Currently
+ * only support version 0. To be incremented for future protocol extensions.
+ *
+ * LEN (8-bit): Extended message body length in increments of 32B. The upper
+ * limit is given by the physical implementation of the NETC VSI-PSI Messaging
+ * mechanism that supports message sizes of up to 1024B (including headers),
+ * that are multiple of 32B.
+ *
+ * COOKIE (4-bit): Optional parameter, which, if not 0, indicates that the
+ * command should be execute asynchronously on PSI side. If COOKIE is not 0
+ * and the command cannot be executed instantly on the PSI side (it would
+ * take longer time to complete), the PSI may enqueue the request in a command
+ * queue of up to 15 entries per VSI and, later after command execution, the
+ * PSI returns the COOKIE to VSI as part of an asynchronous notification
+ * message that indicates the command completion status. If COOKIE is 0 then
+ * the command is considered as blocking, the PSI will wait for the execution
+ * of the command to complete before updating the PSIMSGRR[MC] field with the
+ * corresponding return code.
+ *
+ * The PSI-to-VSI message generic format:
+ *   0               4               8               12          15
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ * |       COOKIE      |   CLASS CODE  |          CLASS ID         |
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ *
+ * The PSI to VSI message format is mapped to the following PSI message
+ * registers/fields, depending on use case:
+ * 1) PSI_RX_control: PSIMSGRR[MC] - for VSI command return code messages
+ * (blocking requests), and
+ * 2) PSI_TX_control: PSIMSGSR[MC] - for PSI to VSI notification messages
+ * (async mode)
+ */
+
+#ifndef __ENETC_MAILBOX_H
+#define __ENETC_MAILBOX_H
+
+#include <linux/crc-itu-t.h>
+
+#define ENETC_CRC_INIT				0xffff
+#define ENETC_MSG_ALIGN				32
+/* s indicates the size of the message */
+#define ENETC_MSG_EXT_BODY_LEN(s)		((s) / ENETC_MSG_ALIGN - 1)
+/* l indicates the extended body len (LEN field) of the message */
+#define ENETC_MSG_SIZE(l)			(((l) + 1) * ENETC_MSG_ALIGN)
+
+enum enetc_msg_class_id {
+	/* Class ID for PSI-to-VSI messages */
+	ENETC_MSG_CLASS_ID_CMD_SUCCESS		= 1,
+	ENETC_MSG_CLASS_ID_PERMISSION_DENY,
+	ENETC_MSG_CLASS_ID_CMD_NOT_SUPPORT,
+	ENETC_MSG_CLASS_ID_PSI_BUSY,
+	ENETC_MSG_CLASS_ID_CRC_ERROR,
+	ENETC_MSG_CLASS_ID_PROTO_NOT_SUPPORT,
+	ENETC_MSG_CLASS_ID_INVALID_MSG_LEN,
+	ENETC_MSG_CLASS_ID_CMD_TIMEOUT,
+	ENETC_MSG_CLASS_ID_CMD_DEFERRED		= 0xf,
+
+	/* Common Class ID for PSI-to-VSI and VSI-to-PSI messages */
+	ENETC_MSG_CLASS_ID_MAC_FILTER		= 0x20,
+};
+
+enum enetc_msg_mac_filter_cmd_id {
+	ENETC_MSG_SET_PRIMARY_MAC,
+};
+
+/* Class-specific error return codes of MAC filter */
+enum enetc_mac_filter_class_code {
+	ENETC_MF_CLASS_CODE_INVALID_MAC,
+};
+
+struct enetc_msg_swbd {
+	void *vaddr;
+	dma_addr_t dma;
+	int size;
+};
+
+/* The PSI-tO-VSI message format, only a 16-bits code */
+union enetc_pf_msg {
+	struct {
+		u8 cookie:4;
+		u8 class_code:4;
+		u8 class_id;
+	};
+	u16 code;
+};
+
+/* The generic VSI-to-PSI message header */
+struct enetc_msg_header {
+	__be16 crc16;
+	u8 class_id;
+	u8 cmd_id;
+	u8 proto_ver;
+	u8 len;
+	u8 resv0;
+	u8 cookie:4;
+	u8 resv1:4;
+	u8 resv2[8];
+};
+
+struct enetc_mac_addr {
+	u8 addr[ETH_ALEN]; /* Network byte order */
+};
+
+/* Message format of class_id 0x20 for exact MAC filter.
+ * cmd_id 0x0: set primary MAC
+ * cmd_id 0x1: Add entries to MAC address filter table
+ * cmd_id 0x2: Delete entries from MAC address filter table
+ * Note that cmd_id 0x1 and 0x2 are not supported yet.
+ */
+struct enetc_msg_mac_exact_filter {
+	struct enetc_msg_header hdr;
+	u8 mac_cnt; /* No need to set for cmd_id 0 */
+	u8 resv[3];
+	struct enetc_mac_addr mac[];
+};
+
+#endif
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_msg.c b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
index a137fa1e6f20..1384752efa7b 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_msg.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
@@ -29,49 +29,104 @@ static irqreturn_t enetc_msg_psi_msix(int irq, void *data)
 }
 
 /* Messaging */
-static u16 enetc_msg_pf_set_vf_primary_mac_addr(struct enetc_pf *pf,
-						int vf_id)
+static void enetc_msg_set_vf_primary_mac_addr(struct enetc_pf *pf, int vf_id,
+					      union enetc_pf_msg *pf_msg)
 {
 	struct enetc_vf_state *vf_state = &pf->vf_state[vf_id];
-	struct enetc_msg_swbd *msg = &pf->rxmsg[vf_id];
-	struct enetc_msg_cmd_set_primary_mac *cmd;
+	struct enetc_msg_swbd *msg_swbd = &pf->rxmsg[vf_id];
 	struct device *dev = &pf->si->pdev->dev;
-	u16 cmd_id;
+	struct enetc_msg_mac_exact_filter *msg;
 	char *addr;
 
-	cmd = (struct enetc_msg_cmd_set_primary_mac *)msg->vaddr;
-	cmd_id = cmd->header.id;
-	if (cmd_id != ENETC_MSG_CMD_MNG_ADD)
-		return ENETC_MSG_CMD_STATUS_FAIL;
+	msg = (struct enetc_msg_mac_exact_filter *)msg_swbd->vaddr;
+	addr = msg->mac[0].addr;
+	if (!is_valid_ether_addr(addr)) {
+		dev_err(dev, "Invalid MAC address from VSI message\n");
+		pf_msg->class_id = ENETC_MSG_CLASS_ID_MAC_FILTER;
+		pf_msg->class_code = ENETC_MF_CLASS_CODE_INVALID_MAC;
+
+		return;
+	}
 
-	addr = cmd->mac.sa_data;
 	if (vf_state->flags & ENETC_VF_FLAG_PF_SET_MAC)
 		dev_warn(dev, "Attempt to override PF set mac addr for VF%d\n",
 			 vf_id);
 	else
 		pf->ops->set_si_primary_mac(&pf->si->hw, vf_id + 1, addr);
 
-	return ENETC_MSG_CMD_STATUS_OK;
+	pf_msg->class_id = ENETC_MSG_CLASS_ID_CMD_SUCCESS;
+}
+
+static bool enetc_msg_check_crc16(void *msg_addr, u32 msg_size)
+{
+	u32 data_size = msg_size - 2;
+	u8 *data_buf = msg_addr + 2;
+	u16 verify_val;
+
+	if (msg_size > ENETC_DEFAULT_MSG_SIZE)
+		return false;
+
+	verify_val = crc_itu_t(ENETC_CRC_INIT, data_buf, data_size);
+	verify_val = crc_itu_t(verify_val, msg_addr, 2);
+	if (verify_val)
+		return false;
+
+	return true;
+}
+
+static void enetc_msg_handle_mac_filter(struct enetc_msg_header *msg_hdr,
+					struct enetc_pf *pf, int vf_id,
+					union enetc_pf_msg *pf_msg)
+{
+	switch (msg_hdr->cmd_id) {
+	case ENETC_MSG_SET_PRIMARY_MAC:
+		enetc_msg_set_vf_primary_mac_addr(pf, vf_id, pf_msg);
+		break;
+	default:
+		pf_msg->class_id = ENETC_MSG_CLASS_ID_CMD_NOT_SUPPORT;
+	}
 }
 
-static void enetc_msg_handle_rxmsg(struct enetc_pf *pf, int vf_id, u16 *status)
+static void enetc_msg_handle_rxmsg(struct enetc_pf *pf, int vf_id,
+				   union enetc_pf_msg *pf_msg)
 {
-	struct enetc_msg_swbd *msg = &pf->rxmsg[vf_id];
+	struct enetc_msg_swbd *msg_swbd = &pf->rxmsg[vf_id];
 	struct device *dev = &pf->si->pdev->dev;
-	struct enetc_msg_cmd_header *cmd_hdr;
-	u16 cmd_type;
+	struct enetc_msg_header *msg_hdr;
+	u32 msg_size;
+
+	msg_hdr = (struct enetc_msg_header *)msg_swbd->vaddr;
+	msg_size = ENETC_MSG_SIZE(msg_hdr->len);
+	if (!enetc_msg_check_crc16(msg_swbd->vaddr, msg_size)) {
+		dev_err(dev, "VSI to PSI Message CRC16 error\n");
+		pf_msg->class_id = ENETC_MSG_CLASS_ID_CRC_ERROR;
+
+		return;
+	}
 
-	*status = ENETC_MSG_CMD_STATUS_OK;
-	cmd_hdr = (struct enetc_msg_cmd_header *)msg->vaddr;
-	cmd_type = cmd_hdr->type;
+	/* Currently, asynchronous actions are not supported */
+	if (msg_hdr->cookie) {
+		dev_err(dev, "Cookie field is not supported yet\n");
+		pf_msg->class_id = ENETC_MSG_CLASS_ID_CMD_NOT_SUPPORT;
+
+		return;
+	}
+
+	/* Currently only support protocol version 0 */
+	if (msg_hdr->proto_ver) {
+		dev_err(dev, "Protocol version %u is not supported yet\n",
+			msg_hdr->proto_ver);
+		pf_msg->class_id = ENETC_MSG_CLASS_ID_PROTO_NOT_SUPPORT;
+
+		return;
+	}
 
-	switch (cmd_type) {
-	case ENETC_MSG_CMD_MNG_MAC:
-		*status = enetc_msg_pf_set_vf_primary_mac_addr(pf, vf_id);
+	switch (msg_hdr->class_id) {
+	case ENETC_MSG_CLASS_ID_MAC_FILTER:
+		enetc_msg_handle_mac_filter(msg_hdr, pf, vf_id, pf_msg);
 		break;
 	default:
-		dev_err(dev, "command not supported (cmd_type: 0x%x)\n",
-			cmd_type);
+		pf_msg->class_id = ENETC_MSG_CLASS_ID_CMD_NOT_SUPPORT;
 	}
 }
 
@@ -92,15 +147,15 @@ static void enetc_msg_task(struct work_struct *work)
 		}
 
 		for (i = 0; i < pf->num_vfs; i++) {
+			union enetc_pf_msg pf_msg = {};
 			u32 psimsgrr;
-			u16 msg_code;
 
 			if (!(ENETC_PSIMSGRR_MR(i) & mr_mask))
 				continue;
 
-			enetc_msg_handle_rxmsg(pf, i, &msg_code);
+			enetc_msg_handle_rxmsg(pf, i, &pf_msg);
 
-			psimsgrr = ENETC_SIMSGSR_SET_MC(msg_code);
+			psimsgrr = ENETC_SIMSGSR_SET_MC(pf_msg.code);
 			psimsgrr |= ENETC_PSIMSGRR_MR(i); /* w1c */
 			enetc_wr(hw, ENETC_PSIMSGRR, psimsgrr);
 		}
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
index 669eb939e33c..31ca08e679b8 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
@@ -6,7 +6,29 @@
 
 #define ENETC_DRV_NAME_STR "ENETC VF driver"
 
-/* Messaging */
+/* Note: This function should be called after filling the message body,
+ * because the CRC16 needs to be calculated after all the data has been
+ * filled.
+ */
+static void enetc_msg_fill_common_hdr(struct enetc_msg_swbd *msg_swbd,
+				      u8 class_id, u8 cmd_id, u8 proto_ver,
+				      u8 cookie)
+{
+	struct enetc_msg_header *hdr = msg_swbd->vaddr;
+	u8 *data_buf = ((u8 *)msg_swbd->vaddr) + 2; /* skip crc16 field */
+	u32 data_size = msg_swbd->size - 2;
+	u16 crc16;
+
+	hdr->class_id = class_id;
+	hdr->cmd_id = cmd_id;
+	hdr->len = ENETC_MSG_EXT_BODY_LEN(msg_swbd->size);
+	hdr->proto_ver = proto_ver;
+	hdr->cookie = cookie;
+
+	crc16 = crc_itu_t(ENETC_CRC_INIT, data_buf, data_size);
+	hdr->crc16 = htons(crc16);
+}
+
 static void enetc_msg_vsi_write_msg(struct enetc_hw *hw,
 				    struct enetc_msg_swbd *msg)
 {
@@ -28,6 +50,7 @@ static void enetc_msg_dma_free(struct device *dev, struct enetc_msg_swbd *msg)
 static int enetc_msg_vsi_send(struct enetc_si *si, struct enetc_msg_swbd *msg)
 {
 	struct device *dev = &si->pdev->dev;
+	union enetc_pf_msg pf_msg;
 	u32 vsimsgsr;
 	int err;
 
@@ -59,36 +82,63 @@ static int enetc_msg_vsi_send(struct enetc_si *si, struct enetc_msg_swbd *msg)
 
 	/* check for message delivery error */
 	if (vsimsgsr & ENETC_VSIMSGSR_MS) {
-		dev_err(dev, "VSI command execute error: %d\n",
-			ENETC_SIMSGSR_GET_MC(vsimsgsr));
+		dev_err(dev, "Transfer error when copying the data\n");
 		return -EIO;
 	}
 
-	return 0;
+	pf_msg.code = ENETC_SIMSGSR_GET_MC(vsimsgsr);
+	/* Check the user-defined completion status. */
+	if (pf_msg.class_id != ENETC_MSG_CLASS_ID_CMD_SUCCESS) {
+		switch (pf_msg.class_id) {
+		case ENETC_MSG_CLASS_ID_PERMISSION_DENY:
+			return -EACCES;
+		case ENETC_MSG_CLASS_ID_CMD_NOT_SUPPORT:
+		case ENETC_MSG_CLASS_ID_PROTO_NOT_SUPPORT:
+			err = -EOPNOTSUPP;
+			break;
+		case ENETC_MSG_CLASS_ID_PSI_BUSY:
+			err = -EBUSY;
+			break;
+		case ENETC_MSG_CLASS_ID_CMD_TIMEOUT:
+			err = -ETIME;
+			break;
+		case ENETC_MSG_CLASS_ID_INVALID_MSG_LEN:
+		case ENETC_MSG_CLASS_ID_MAC_FILTER:
+			err = -EINVAL;
+			break;
+		default:
+			err = -EIO;
+		}
+	}
+
+	if (err)
+		dev_err(dev, "Return error code from PSI: 0x%04x\n",
+			pf_msg.code);
+
+	return err;
 }
 
 static int enetc_msg_vsi_set_primary_mac_addr(struct enetc_ndev_priv *priv,
 					      struct sockaddr *saddr)
 {
-	struct enetc_msg_cmd_set_primary_mac *cmd;
-	struct enetc_msg_swbd msg;
-
-	msg.size = ALIGN(sizeof(struct enetc_msg_cmd_set_primary_mac), 64);
-	msg.vaddr = dma_alloc_coherent(priv->dev, msg.size, &msg.dma,
-				       GFP_KERNEL);
-	if (!msg.vaddr) {
-		dev_err(priv->dev, "Failed to alloc Tx msg (size: %d)\n",
-			msg.size);
+	struct enetc_msg_mac_exact_filter *msg;
+	struct enetc_msg_swbd msg_swbd;
+	u32 msg_size;
+
+	msg_size = struct_size(msg, mac, 1);
+	msg_swbd.size = ALIGN(msg_size, ENETC_MSG_ALIGN);
+	msg_swbd.vaddr = dma_alloc_coherent(priv->dev, msg_swbd.size,
+					    &msg_swbd.dma, GFP_KERNEL);
+	if (!msg_swbd.vaddr)
 		return -ENOMEM;
-	}
 
-	cmd = (struct enetc_msg_cmd_set_primary_mac *)msg.vaddr;
-	cmd->header.type = ENETC_MSG_CMD_MNG_MAC;
-	cmd->header.id = ENETC_MSG_CMD_MNG_ADD;
-	memcpy(&cmd->mac, saddr, sizeof(struct sockaddr));
+	msg = (struct enetc_msg_mac_exact_filter *)msg_swbd.vaddr;
+	memcpy(&msg->mac[0].addr, saddr->sa_data, ETH_ALEN);
+	enetc_msg_fill_common_hdr(&msg_swbd, ENETC_MSG_CLASS_ID_MAC_FILTER,
+				  ENETC_MSG_SET_PRIMARY_MAC, 0, 0);
 
 	/* send the command and wait */
-	return enetc_msg_vsi_send(priv->si, &msg);
+	return enetc_msg_vsi_send(priv->si, &msg_swbd);
 }
 
 static int enetc_vf_set_mac_addr(struct net_device *ndev, void *addr)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next 08/15] net: enetc: add VF-PF messaging support for IP minor revision query
  2026-05-11  8:07 [PATCH net-next 00/15] net: enetc: Prepare for ENETC v4 VF support Wei Fang
                   ` (6 preceding siblings ...)
  2026-05-11  8:07 ` [PATCH net-next 07/15] net: enetc: convert mailbox messages to new formats Wei Fang
@ 2026-05-11  8:07 ` Wei Fang
  2026-05-11  8:07 ` [PATCH net-next 09/15] net: enetc: align v1 CBDR API with v4 for VF driver sharing Wei Fang
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Wei Fang @ 2026-05-11  8:07 UTC (permalink / raw)
  To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
	davem, edumazet, kuba, pabeni
  Cc: imx, netdev, linux-kernel

For ENETC v4, different SoCs use different minor revisions, such as
i.MX95 v4.1, i.MX94 v4.3, and i.MX952 v4.6. Unlike the PF, the VF does
not have access to a global register that exposes the IP minor revision.
In the current driver model, the VF must select the appropriate driver
data based on this revision information.

To support this requirement, the VF now sends a minor revision query
message to the PF through the VSI-to-PSI mailbox mechanism. The PF
responds with the IP minor revision so that the VF can match the correct
driver data.

This patch adds PF-side support for replying to the minor revision
message and VF-side support for sending the query.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 .../ethernet/freescale/enetc/enetc_mailbox.h  | 28 ++++++++++-
 .../net/ethernet/freescale/enetc/enetc_msg.c  | 29 ++++++++++++
 .../net/ethernet/freescale/enetc/enetc_vf.c   | 47 ++++++++++++++++++-
 3 files changed, 101 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc_mailbox.h b/drivers/net/ethernet/freescale/enetc/enetc_mailbox.h
index 260c7333d93a..294185b54147 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_mailbox.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_mailbox.h
@@ -65,6 +65,9 @@
  * (blocking requests), and
  * 2) PSI_TX_control: PSIMSGSR[MC] - for PSI to VSI notification messages
  * (async mode)
+ *
+ * Note that for some GET messages, there is no COOKIE field, and the CLASS
+ * CODE field is expanded to 8 bits.
  */
 
 #ifndef __ENETC_MAILBOX_H
@@ -93,12 +96,17 @@ enum enetc_msg_class_id {
 
 	/* Common Class ID for PSI-to-VSI and VSI-to-PSI messages */
 	ENETC_MSG_CLASS_ID_MAC_FILTER		= 0x20,
+	ENETC_MSG_CLASS_ID_IP_REVISION		= 0xf0,
 };
 
 enum enetc_msg_mac_filter_cmd_id {
 	ENETC_MSG_SET_PRIMARY_MAC,
 };
 
+enum enetc_msg_ip_revision_cmd_id {
+	ENETC_MSG_GET_IP_MN			= 1,
+};
+
 /* Class-specific error return codes of MAC filter */
 enum enetc_mac_filter_class_code {
 	ENETC_MF_CLASS_CODE_INVALID_MAC,
@@ -108,13 +116,20 @@ struct enetc_msg_swbd {
 	void *vaddr;
 	dma_addr_t dma;
 	int size;
+	u8 class_code; /* save return code from PSI for 'get' messages */
 };
 
 /* The PSI-tO-VSI message format, only a 16-bits code */
 union enetc_pf_msg {
 	struct {
-		u8 cookie:4;
-		u8 class_code:4;
+		union {
+			struct {
+				u8 cookie:4;
+				u8 class_code:4;
+			};
+			/* some messages class_code is 8-bit without cookie */
+			u8 class_code_u8;
+		};
 		u8 class_id;
 	};
 	u16 code;
@@ -150,4 +165,13 @@ struct enetc_msg_mac_exact_filter {
 	struct enetc_mac_addr mac[];
 };
 
+/* The generic message format applies to the following messages:
+ * Get IP revision message, class_id 0xf0.
+ * cmd_id 1: get IP minor revision
+ */
+struct enetc_msg_generic {
+	struct enetc_msg_header hdr;
+	u8 resv[16];
+};
+
 #endif
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_msg.c b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
index 1384752efa7b..f3e78865617e 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_msg.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
@@ -87,6 +87,20 @@ static void enetc_msg_handle_mac_filter(struct enetc_msg_header *msg_hdr,
 	}
 }
 
+static void enetc_msg_handle_ip_revision(struct enetc_msg_header *msg_hdr,
+					 struct enetc_pf *pf,
+					 union enetc_pf_msg *pf_msg)
+{
+	switch (msg_hdr->cmd_id) {
+	case ENETC_MSG_GET_IP_MN:
+		pf_msg->class_id = ENETC_MSG_CLASS_ID_IP_REVISION;
+		pf_msg->class_code_u8 = pf->si->revision & 0xff;
+		break;
+	default:
+		pf_msg->class_id = ENETC_MSG_CLASS_ID_CMD_NOT_SUPPORT;
+	}
+}
+
 static void enetc_msg_handle_rxmsg(struct enetc_pf *pf, int vf_id,
 				   union enetc_pf_msg *pf_msg)
 {
@@ -121,10 +135,25 @@ static void enetc_msg_handle_rxmsg(struct enetc_pf *pf, int vf_id,
 		return;
 	}
 
+	/* The new messages are currently only supported on ENETC v4. If v1
+	 * requires them, the current restriction can be lifted.
+	 */
+	if (is_enetc_rev1(pf->si) &&
+	    !(msg_hdr->class_id == ENETC_MSG_CLASS_ID_MAC_FILTER &&
+	      msg_hdr->cmd_id == ENETC_MSG_SET_PRIMARY_MAC)) {
+		dev_err(dev, "Unsupported messages for ENETC v1\n");
+		pf_msg->class_id = ENETC_MSG_CLASS_ID_CMD_NOT_SUPPORT;
+
+		return;
+	}
+
 	switch (msg_hdr->class_id) {
 	case ENETC_MSG_CLASS_ID_MAC_FILTER:
 		enetc_msg_handle_mac_filter(msg_hdr, pf, vf_id, pf_msg);
 		break;
+	case ENETC_MSG_CLASS_ID_IP_REVISION:
+		enetc_msg_handle_ip_revision(msg_hdr, pf, pf_msg);
+		break;
 	default:
 		pf_msg->class_id = ENETC_MSG_CLASS_ID_CMD_NOT_SUPPORT;
 	}
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
index 31ca08e679b8..d17ab5b2306d 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
@@ -106,6 +106,9 @@ static int enetc_msg_vsi_send(struct enetc_si *si, struct enetc_msg_swbd *msg)
 		case ENETC_MSG_CLASS_ID_MAC_FILTER:
 			err = -EINVAL;
 			break;
+		case ENETC_MSG_CLASS_ID_IP_REVISION:
+			msg->class_code = pf_msg.class_code_u8;
+			break;
 		default:
 			err = -EIO;
 		}
@@ -141,6 +144,27 @@ static int enetc_msg_vsi_set_primary_mac_addr(struct enetc_ndev_priv *priv,
 	return enetc_msg_vsi_send(priv->si, &msg_swbd);
 }
 
+static int enetc_vf_get_ip_minor_revision(struct enetc_si *si)
+{
+	struct device *dev = &si->pdev->dev;
+	struct enetc_msg_swbd msg_swbd;
+	int err;
+
+	msg_swbd.size = ALIGN(sizeof(struct enetc_msg_generic),
+			      ENETC_MSG_ALIGN);
+	msg_swbd.vaddr = dma_alloc_coherent(dev, msg_swbd.size,
+					    &msg_swbd.dma, GFP_KERNEL);
+	if (!msg_swbd.vaddr)
+		return -ENOMEM;
+
+	enetc_msg_fill_common_hdr(&msg_swbd, ENETC_MSG_CLASS_ID_IP_REVISION,
+				  ENETC_MSG_GET_IP_MN, 0, 0);
+
+	err = enetc_msg_vsi_send(si, &msg_swbd);
+
+	return err ? err : msg_swbd.class_code;
+}
+
 static int enetc_vf_set_mac_addr(struct net_device *ndev, void *addr)
 {
 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
@@ -192,6 +216,27 @@ static const struct net_device_ops enetc_ndev_ops = {
 	.ndo_hwtstamp_set	= enetc_hwtstamp_set,
 };
 
+static void enetc_vf_get_revision(struct enetc_si *si)
+{
+	int ip_mn;
+
+	if (is_enetc_rev1(si)) {
+		si->revision = ENETC_REV_1_0;
+		return;
+	}
+
+	ip_mn = enetc_vf_get_ip_minor_revision(si);
+	if (ip_mn >= 0) {
+		si->revision = (si->pdev->revision << 8) | ip_mn;
+		return;
+	}
+
+	si->revision = ENETC_REV_4_1;
+	dev_info(&si->pdev->dev,
+		 "Failed to get revision, use compatible revision: 0x%04x\n",
+		 si->revision);
+}
+
 static void enetc_vf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
 				  const struct net_device_ops *ndev_ops)
 {
@@ -251,7 +296,7 @@ static int enetc_vf_probe(struct pci_dev *pdev,
 		return dev_err_probe(&pdev->dev, err, "PCI probing failed\n");
 
 	si = pci_get_drvdata(pdev);
-	si->revision = ENETC_REV_1_0;
+	enetc_vf_get_revision(si);
 	si->ops = &enetc_vsi_ops;
 	err = enetc_get_driver_data(si);
 	if (err) {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next 09/15] net: enetc: align v1 CBDR API with v4 for VF driver sharing
  2026-05-11  8:07 [PATCH net-next 00/15] net: enetc: Prepare for ENETC v4 VF support Wei Fang
                   ` (7 preceding siblings ...)
  2026-05-11  8:07 ` [PATCH net-next 08/15] net: enetc: add VF-PF messaging support for IP minor revision query Wei Fang
@ 2026-05-11  8:07 ` Wei Fang
  2026-05-11  8:08 ` [PATCH net-next 10/15] net: enetc: add CBDR setup/teardown hooks to enetc_si_ops for VF support Wei Fang
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Wei Fang @ 2026-05-11  8:07 UTC (permalink / raw)
  To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
	davem, edumazet, kuba, pabeni
  Cc: imx, netdev, linux-kernel

The upcoming ENETC v4 VF will share the enetc-vf driver with the v1 VF.
However, ENETC v4 introduces different CBDR (command BD ring) setup and
teardown semantics that are incompatible with v1.

To support both versions in the same driver, add setup_cbdr() and
teardown_cbdr() hooks to struct enetc_si_ops, allowing the driver to
register version-specific implementations. This patch refactors the v1
CBDR functions to match the v4-style interface (taking struct enetc_si*
instead of individual parameters), enabling them to be registered via
si_ops.

Changes:
- Update enetc_setup_cbdr() and enetc_teardown_cbdr() prototypes to
  take 'struct enetc_si *' as the sole parameter
- Extract parameters (dev, hw, bd_count) from the enetc_si structure
  within the function implementations
- Update all call sites in enetc_pf.c and enetc_vf.c

No functional changes. This prepares for adding v4-specific CBDR handling
in subsequent patches.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 drivers/net/ethernet/freescale/enetc/enetc.h     |  5 ++---
 .../net/ethernet/freescale/enetc/enetc_cbdr.c    | 16 ++++++++++------
 drivers/net/ethernet/freescale/enetc/enetc_pf.c  |  7 +++----
 drivers/net/ethernet/freescale/enetc/enetc_vf.c  |  7 +++----
 4 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
index b70b625328ea..772f0ab2f8c1 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc.h
@@ -537,9 +537,8 @@ void enetc_mm_link_state_update(struct enetc_ndev_priv *priv, bool link);
 void enetc_mm_commit_preemptible_tcs(struct enetc_ndev_priv *priv);
 
 /* control buffer descriptor ring (CBDR) */
-int enetc_setup_cbdr(struct device *dev, struct enetc_hw *hw, int bd_count,
-		     struct enetc_cbdr *cbdr);
-void enetc_teardown_cbdr(struct enetc_cbdr *cbdr);
+int enetc_setup_cbdr(struct enetc_si *si);
+void enetc_teardown_cbdr(struct enetc_si *si);
 int enetc4_setup_cbdr(struct enetc_si *si);
 void enetc4_teardown_cbdr(struct enetc_si *si);
 int enetc_set_mac_flt_entry(struct enetc_si *si, int index,
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_cbdr.c b/drivers/net/ethernet/freescale/enetc/enetc_cbdr.c
index a635bfdc30af..e4a393a8a58e 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_cbdr.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_cbdr.c
@@ -3,10 +3,12 @@
 
 #include "enetc.h"
 
-int enetc_setup_cbdr(struct device *dev, struct enetc_hw *hw, int bd_count,
-		     struct enetc_cbdr *cbdr)
+int enetc_setup_cbdr(struct enetc_si *si)
 {
-	int size = bd_count * sizeof(struct enetc_cbd);
+	int size = ENETC_CBDR_DEFAULT_SIZE * sizeof(struct enetc_cbd);
+	struct enetc_cbdr *cbdr = &si->cbd_ring;
+	struct device *dev = &si->pdev->dev;
+	struct enetc_hw *hw = &si->hw;
 
 	cbdr->bd_base = dma_alloc_coherent(dev, size, &cbdr->bd_dma_base,
 					   GFP_KERNEL);
@@ -23,7 +25,7 @@ int enetc_setup_cbdr(struct device *dev, struct enetc_hw *hw, int bd_count,
 	cbdr->next_to_clean = 0;
 	cbdr->next_to_use = 0;
 	cbdr->dma_dev = dev;
-	cbdr->bd_count = bd_count;
+	cbdr->bd_count = ENETC_CBDR_DEFAULT_SIZE;
 
 	cbdr->pir = hw->reg + ENETC_SICBDRPIR;
 	cbdr->cir = hw->reg + ENETC_SICBDRCIR;
@@ -46,13 +48,15 @@ int enetc_setup_cbdr(struct device *dev, struct enetc_hw *hw, int bd_count,
 }
 EXPORT_SYMBOL_GPL(enetc_setup_cbdr);
 
-void enetc_teardown_cbdr(struct enetc_cbdr *cbdr)
+void enetc_teardown_cbdr(struct enetc_si *si)
 {
-	int size = cbdr->bd_count * sizeof(struct enetc_cbd);
+	struct enetc_cbdr *cbdr = &si->cbd_ring;
+	int size;
 
 	/* disable ring */
 	enetc_wr_reg(cbdr->mr, 0);
 
+	size = cbdr->bd_count * sizeof(struct enetc_cbd);
 	dma_free_coherent(cbdr->dma_dev, size, cbdr->bd_base,
 			  cbdr->bd_dma_base);
 	cbdr->bd_base = NULL;
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index fea5cb6a1662..b126a624e6dd 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -798,8 +798,7 @@ static struct enetc_si *enetc_psi_create(struct pci_dev *pdev)
 		goto out_pci_remove;
 	}
 
-	err = enetc_setup_cbdr(&pdev->dev, &si->hw, ENETC_CBDR_DEFAULT_SIZE,
-			       &si->cbd_ring);
+	err = enetc_setup_cbdr(si);
 	if (err)
 		goto out_pci_remove;
 
@@ -818,7 +817,7 @@ static struct enetc_si *enetc_psi_create(struct pci_dev *pdev)
 	return si;
 
 out_teardown_cbdr:
-	enetc_teardown_cbdr(&si->cbd_ring);
+	enetc_teardown_cbdr(si);
 out_pci_remove:
 	enetc_pci_remove(pdev);
 out:
@@ -829,7 +828,7 @@ static void enetc_psi_destroy(struct pci_dev *pdev)
 {
 	struct enetc_si *si = pci_get_drvdata(pdev);
 
-	enetc_teardown_cbdr(&si->cbd_ring);
+	enetc_teardown_cbdr(si);
 	enetc_pci_remove(pdev);
 }
 
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
index d17ab5b2306d..eb6f8065e1ea 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
@@ -320,8 +320,7 @@ static int enetc_vf_probe(struct pci_dev *pdev,
 
 	enetc_init_si_rings_params(priv);
 
-	err = enetc_setup_cbdr(priv->dev, &si->hw, ENETC_CBDR_DEFAULT_SIZE,
-			       &si->cbd_ring);
+	err = enetc_setup_cbdr(si);
 	if (err)
 		goto err_setup_cbdr;
 
@@ -357,7 +356,7 @@ static int enetc_vf_probe(struct pci_dev *pdev,
 err_alloc_msix:
 	enetc_free_si_resources(priv);
 err_alloc_si_res:
-	enetc_teardown_cbdr(&si->cbd_ring);
+	enetc_teardown_cbdr(si);
 err_setup_cbdr:
 	si->ndev = NULL;
 	free_netdev(ndev);
@@ -379,7 +378,7 @@ static void enetc_vf_remove(struct pci_dev *pdev)
 	enetc_free_msix(priv);
 
 	enetc_free_si_resources(priv);
-	enetc_teardown_cbdr(&si->cbd_ring);
+	enetc_teardown_cbdr(si);
 
 	free_netdev(si->ndev);
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next 10/15] net: enetc: add CBDR setup/teardown hooks to enetc_si_ops for VF support
  2026-05-11  8:07 [PATCH net-next 00/15] net: enetc: Prepare for ENETC v4 VF support Wei Fang
                   ` (8 preceding siblings ...)
  2026-05-11  8:07 ` [PATCH net-next 09/15] net: enetc: align v1 CBDR API with v4 for VF driver sharing Wei Fang
@ 2026-05-11  8:08 ` Wei Fang
  2026-05-11  8:08 ` [PATCH net-next 11/15] net: enetc: add generic helper to initialize SR-IOV resources Wei Fang
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Wei Fang @ 2026-05-11  8:08 UTC (permalink / raw)
  To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
	davem, edumazet, kuba, pabeni
  Cc: imx, netdev, linux-kernel

The upcoming ENETC v4 VF will share the enetc-vf driver with the
existing v1 VF. However, ENETC v4 uses a revised CBDR (command BD ring)
setup/teardown API that differs from v1.

To support both versions in the same driver, add setup_cbdr() and
teardown_cbdr() function pointers to struct enetc_si_ops. This allows
each hardware version to register its own CBDR implementation:

- ENETC v1 VF registers enetc_setup_cbdr/enetc_teardown_cbdr (existing)
- ENETC v4 VF will register enetc4_setup_cbdr/enetc4_teardown_cbdr

Update the enetc-vf driver to call CBDR operations through si->ops
instead of directly invoking the v1 functions. This enables runtime
selection of the correct CBDR backend based on hardware version.

Changes:
- Add setup_cbdr() and teardown_cbdr() hooks to struct enetc_si_ops
- Register v1 CBDR functions in enetc_vsi_ops
- Replace direct calls with si->ops->setup_cbdr() and
  si->ops->teardown_cbdr() in enetc_vf.c

No functional changes to existing v1 VF behavior.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 drivers/net/ethernet/freescale/enetc/enetc.h    | 2 ++
 drivers/net/ethernet/freescale/enetc/enetc_vf.c | 8 +++++---
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
index 772f0ab2f8c1..04a5dd5ea6c7 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc.h
@@ -297,6 +297,8 @@ struct enetc_si;
 struct enetc_si_ops {
 	int (*get_rss_table)(struct enetc_si *si, u32 *table, int count);
 	int (*set_rss_table)(struct enetc_si *si, const u32 *table, int count);
+	int (*setup_cbdr)(struct enetc_si *si);
+	void (*teardown_cbdr)(struct enetc_si *si);
 };
 
 /* PCI IEP device data */
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
index eb6f8065e1ea..11ffd2083abc 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
@@ -281,6 +281,8 @@ static void enetc_vf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
 static const struct enetc_si_ops enetc_vsi_ops = {
 	.get_rss_table = enetc_get_rss_table,
 	.set_rss_table = enetc_set_rss_table,
+	.setup_cbdr = enetc_setup_cbdr,
+	.teardown_cbdr = enetc_teardown_cbdr,
 };
 
 static int enetc_vf_probe(struct pci_dev *pdev,
@@ -320,7 +322,7 @@ static int enetc_vf_probe(struct pci_dev *pdev,
 
 	enetc_init_si_rings_params(priv);
 
-	err = enetc_setup_cbdr(si);
+	err = si->ops->setup_cbdr(si);
 	if (err)
 		goto err_setup_cbdr;
 
@@ -356,7 +358,7 @@ static int enetc_vf_probe(struct pci_dev *pdev,
 err_alloc_msix:
 	enetc_free_si_resources(priv);
 err_alloc_si_res:
-	enetc_teardown_cbdr(si);
+	si->ops->teardown_cbdr(si);
 err_setup_cbdr:
 	si->ndev = NULL;
 	free_netdev(ndev);
@@ -378,7 +380,7 @@ static void enetc_vf_remove(struct pci_dev *pdev)
 	enetc_free_msix(priv);
 
 	enetc_free_si_resources(priv);
-	enetc_teardown_cbdr(si);
+	si->ops->teardown_cbdr(si);
 
 	free_netdev(si->ndev);
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next 11/15] net: enetc: add generic helper to initialize SR-IOV resources
  2026-05-11  8:07 [PATCH net-next 00/15] net: enetc: Prepare for ENETC v4 VF support Wei Fang
                   ` (9 preceding siblings ...)
  2026-05-11  8:08 ` [PATCH net-next 10/15] net: enetc: add CBDR setup/teardown hooks to enetc_si_ops for VF support Wei Fang
@ 2026-05-11  8:08 ` Wei Fang
  2026-05-11  8:08 ` [PATCH net-next 12/15] net: enetc: use MADDR_TYPE for MAC filter array size Wei Fang
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Wei Fang @ 2026-05-11  8:08 UTC (permalink / raw)
  To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
	davem, edumazet, kuba, pabeni
  Cc: imx, netdev, linux-kernel

The upcoming ENETC v4 PF driver will support SR-IOV, and its logic for
initializing VF resources is identical to the existing ENETC v1 PF
implementation. To avoid code duplication across PF drivers, factor out
the common SR-IOV initialization logic into the enetc-pf-common driver.

Add enetc_init_sriov_resources() to handle:
- Querying the total number of VFs supported by the device via
  pci_sriov_get_totalvfs()
- Allocating memory for the VF state array (struct enetc_vf_state)

The implementation uses devm_kcalloc() instead of kzalloc() to simplify
memory management. This automatically frees VF state memory when the PF
device is removed, eliminating the need for explicit cleanup in error
and remove paths.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 .../net/ethernet/freescale/enetc/enetc_pf.c    | 15 ++++-----------
 .../ethernet/freescale/enetc/enetc_pf_common.c | 18 ++++++++++++++++++
 .../ethernet/freescale/enetc/enetc_pf_common.h |  1 +
 3 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index b126a624e6dd..13a1c9bdfee8 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -868,13 +868,9 @@ static int enetc_pf_probe(struct pci_dev *pdev,
 	pf->si = si;
 	pf->ops = &enetc_pf_ops;
 
-	pf->total_vfs = pci_sriov_get_totalvfs(pdev);
-	if (pf->total_vfs) {
-		pf->vf_state = kzalloc_objs(struct enetc_vf_state,
-					    pf->total_vfs);
-		if (!pf->vf_state)
-			goto err_alloc_vf_state;
-	}
+	err = enetc_init_sriov_resources(pf);
+	if (err)
+		goto err_init_sriov_resources;
 
 	err = enetc_setup_mac_addresses(node, pf);
 	if (err)
@@ -952,8 +948,7 @@ static int enetc_pf_probe(struct pci_dev *pdev,
 	free_netdev(ndev);
 err_alloc_netdev:
 err_setup_mac_addresses:
-	kfree(pf->vf_state);
-err_alloc_vf_state:
+err_init_sriov_resources:
 	enetc_psi_destroy(pdev);
 err_psi_create:
 	return err;
@@ -980,8 +975,6 @@ static void enetc_pf_remove(struct pci_dev *pdev)
 	enetc_free_si_resources(priv);
 
 	free_netdev(si->ndev);
-	kfree(pf->vf_state);
-
 	enetc_psi_destroy(pdev);
 }
 
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
index 76263b8566bb..60a330ee03b7 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
@@ -435,5 +435,23 @@ int enetc_vlan_rx_del_vid(struct net_device *ndev, __be16 prot, u16 vid)
 }
 EXPORT_SYMBOL_GPL(enetc_vlan_rx_del_vid);
 
+int enetc_init_sriov_resources(struct enetc_pf *pf)
+{
+	struct device *dev = &pf->si->pdev->dev;
+
+	pf->total_vfs = pci_sriov_get_totalvfs(pf->si->pdev);
+	if (!pf->total_vfs)
+		return 0;
+
+	pf->vf_state = devm_kcalloc(dev, pf->total_vfs,
+				    sizeof(struct enetc_vf_state),
+				    GFP_KERNEL);
+	if (!pf->vf_state)
+		return -ENOMEM;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(enetc_init_sriov_resources);
+
 MODULE_DESCRIPTION("NXP ENETC PF common functionality driver");
 MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
index 548323d29f36..ce499cfcce30 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
@@ -15,6 +15,7 @@ void enetc_phylink_destroy(struct enetc_ndev_priv *priv);
 void enetc_set_default_rss_key(struct enetc_pf *pf);
 int enetc_vlan_rx_add_vid(struct net_device *ndev, __be16 prot, u16 vid);
 int enetc_vlan_rx_del_vid(struct net_device *ndev, __be16 prot, u16 vid);
+int enetc_init_sriov_resources(struct enetc_pf *pf);
 
 static inline u16 enetc_get_ip_revision(struct enetc_hw *hw)
 {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next 12/15] net: enetc: use MADDR_TYPE for MAC filter array size
  2026-05-11  8:07 [PATCH net-next 00/15] net: enetc: Prepare for ENETC v4 VF support Wei Fang
                   ` (10 preceding siblings ...)
  2026-05-11  8:08 ` [PATCH net-next 11/15] net: enetc: add generic helper to initialize SR-IOV resources Wei Fang
@ 2026-05-11  8:08 ` Wei Fang
  2026-05-11  8:08 ` [PATCH net-next 13/15] net: enetc: dynamically allocate rxmsg based on VF count Wei Fang
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Wei Fang @ 2026-05-11  8:08 UTC (permalink / raw)
  To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
	davem, edumazet, kuba, pabeni
  Cc: imx, netdev, linux-kernel

The mac_filter array in struct enetc_pf is sized as
ENETC_MAX_NUM_MAC_FLT, defined as (ENETC_MAX_NUM_VFS + 1) * MADDR_TYPE.
This resulted in an array of 6 elements (for 2 VFs), but only the first
2 entries are actually used.

The PF driver maintains MAC filters for unicast (UC) and multicast (MC)
addresses, indexed by the enum enetc_mac_addr_type (UC=0, MC=1). The
code only iterates over MADDR_TYPE (2) entries and directly accesses
mac_filter[UC] and mac_filter[MC]. The extra space allocated for
(ENETC_MAX_NUM_VFS * MADDR_TYPE) entries is never used because VF MAC
filtering is not implemented yet.

Remove the ENETC_MAX_NUM_MAC_FLT macro and size the array as
MADDR_TYPE, reducing the allocation from 6 to 2 entries. This saves 48
bytes per PF and better reflects the actual usage.

This change has no functional impact. Future VF MAC filtering support
will move mac_filter into struct enetc_si, allowing each SI (PF or VF)
to maintain its own independent filter table.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 drivers/net/ethernet/freescale/enetc/enetc_pf.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.h b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
index 731d56bad5fc..9fcf1c58d59b 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
@@ -5,8 +5,6 @@
 #include <linux/phylink.h>
 
 #define ENETC_PF_NUM_RINGS	8
-#define ENETC_MAX_NUM_MAC_FLT	((ENETC_MAX_NUM_VFS + 1) * MADDR_TYPE)
-
 #define ENETC_VLAN_HT_SIZE	64
 
 enum enetc_vf_flags {
@@ -42,7 +40,7 @@ struct enetc_pf {
 	int total_vfs; /* max number of VFs, set for PF at probe */
 	struct enetc_vf_state *vf_state;
 
-	struct enetc_mac_filter mac_filter[ENETC_MAX_NUM_MAC_FLT];
+	struct enetc_mac_filter mac_filter[MADDR_TYPE];
 
 	struct enetc_msg_swbd rxmsg[ENETC_MAX_NUM_VFS];
 	struct work_struct msg_task;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next 13/15] net: enetc: dynamically allocate rxmsg based on VF count
  2026-05-11  8:07 [PATCH net-next 00/15] net: enetc: Prepare for ENETC v4 VF support Wei Fang
                   ` (11 preceding siblings ...)
  2026-05-11  8:08 ` [PATCH net-next 12/15] net: enetc: use MADDR_TYPE for MAC filter array size Wei Fang
@ 2026-05-11  8:08 ` Wei Fang
  2026-05-11  8:08 ` [PATCH net-next 14/15] net: enetc: refactor MR interrupt enable/disable helpers Wei Fang
  2026-05-11  8:08 ` [PATCH net-next 15/15] net: enetc: generate MR interrupt mask based on the number of enabled VFs Wei Fang
  14 siblings, 0 replies; 18+ messages in thread
From: Wei Fang @ 2026-05-11  8:08 UTC (permalink / raw)
  To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
	davem, edumazet, kuba, pabeni
  Cc: imx, netdev, linux-kernel

The constant ENETC_MAX_NUM_VFS is defined as 2 when enabling support for
LS1028A. This works for LS1028A because its ENETC hardware supports up
to 2 VFs. However, ENETC v4 has varying VF capabilities depending on the
SoC:

i.MX94 standalone ENETC: 0 VFs
i.MX94 internal ENETC:   3 VFs
i.MX952:                 1 VF

Using a fixed ENETC_MAX_NUM_VFS for memory allocation leads to
over-allocation on SoCs with fewer or no VF support. To better match
hardware capabilities and avoid unnecessary memory usage, change rxmsg
memory allocation from a fixed-size array to dynamic allocation based
on the actual VF count retrieved via pci_sriov_get_totalvfs().

Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 drivers/net/ethernet/freescale/enetc/enetc_hw.h        | 1 -
 drivers/net/ethernet/freescale/enetc/enetc_pf.h        | 2 +-
 drivers/net/ethernet/freescale/enetc/enetc_pf_common.c | 6 ++++++
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
index 662e4fbafb74..94f53762cea8 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
@@ -672,7 +672,6 @@ union enetc_rx_bd {
 
 #define ENETC_MAC_ADDR_FILT_CNT	8 /* # of supported entries per port */
 #define EMETC_MAC_ADDR_FILT_RES	3 /* # of reserved entries at the beginning */
-#define ENETC_MAX_NUM_VFS	2
 
 #define ENETC_CBD_FLAGS_SF	BIT(7) /* short format */
 #define ENETC_CBD_STATUS_MASK	0xf
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.h b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
index 9fcf1c58d59b..d4f1041587f7 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
@@ -42,7 +42,7 @@ struct enetc_pf {
 
 	struct enetc_mac_filter mac_filter[MADDR_TYPE];
 
-	struct enetc_msg_swbd rxmsg[ENETC_MAX_NUM_VFS];
+	struct enetc_msg_swbd *rxmsg;
 	struct work_struct msg_task;
 	char msg_int_name[ENETC_INT_NAME_MAX];
 
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
index 60a330ee03b7..43225aaab54e 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
@@ -449,6 +449,12 @@ int enetc_init_sriov_resources(struct enetc_pf *pf)
 	if (!pf->vf_state)
 		return -ENOMEM;
 
+	pf->rxmsg = devm_kcalloc(dev, pf->total_vfs,
+				 sizeof(struct enetc_msg_swbd),
+				 GFP_KERNEL);
+	if (!pf->rxmsg)
+		return -ENOMEM;
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(enetc_init_sriov_resources);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next 14/15] net: enetc: refactor MR interrupt enable/disable helpers
  2026-05-11  8:07 [PATCH net-next 00/15] net: enetc: Prepare for ENETC v4 VF support Wei Fang
                   ` (12 preceding siblings ...)
  2026-05-11  8:08 ` [PATCH net-next 13/15] net: enetc: dynamically allocate rxmsg based on VF count Wei Fang
@ 2026-05-11  8:08 ` Wei Fang
  2026-05-11  8:08 ` [PATCH net-next 15/15] net: enetc: generate MR interrupt mask based on the number of enabled VFs Wei Fang
  14 siblings, 0 replies; 18+ messages in thread
From: Wei Fang @ 2026-05-11  8:08 UTC (permalink / raw)
  To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
	davem, edumazet, kuba, pabeni
  Cc: imx, netdev, linux-kernel

The MR interrupt helpers currently operate on struct enetc_hw and rely
on the fixed ENETC_PSIIER_MR_MASK constant when enabling or disabling
MR-related interrupt sources. As part of upcoming support for ENETC v4
with more or less VFs, the mask used for MR interrupts will need to be
generated dynamically based on the number of enabled VFs, rather than
relying on a global constant.

Consolidate enetc_msg_enable_mr_int() and enetc_msg_disable_mr_int()
into a single function. The unified helper takes struct enetc_pf *pf
and a bool enable parameter, replacing the previous struct enetc_hw *hw
argument. This change allows future code to access pf->num_vfs and
dynamically derive the interrupt mask.

This is a preparatory refactoring with no functional changes. The
implementation still uses the fixed ENETC_PSIIER_MR_MASK constant. A
subsequent patch will implement dynamic mask generation based on the
actual VF count.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 .../net/ethernet/freescale/enetc/enetc_msg.c  | 26 +++++++++----------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc_msg.c b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
index f3e78865617e..73e32c9b65a8 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_msg.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
@@ -3,18 +3,18 @@
 
 #include "enetc_pf_common.h"
 
-static void enetc_msg_disable_mr_int(struct enetc_hw *hw)
+static void enetc_msg_set_mr_int(struct enetc_pf *pf, bool enable)
 {
-	u32 psiier = enetc_rd(hw, ENETC_PSIIER);
-	/* disable MR int source(s) */
-	enetc_wr(hw, ENETC_PSIIER, psiier & ~ENETC_PSIIER_MR_MASK);
-}
+	struct enetc_hw *hw = &pf->si->hw;
+	u32 val;
 
-static void enetc_msg_enable_mr_int(struct enetc_hw *hw)
-{
-	u32 psiier = enetc_rd(hw, ENETC_PSIIER);
+	val = enetc_rd(hw, ENETC_PSIIER);
+	if (enable)
+		val |= ENETC_PSIIER_MR_MASK;
+	else
+		val &= ~ENETC_PSIIER_MR_MASK;
 
-	enetc_wr(hw, ENETC_PSIIER, psiier | ENETC_PSIIER_MR_MASK);
+	enetc_wr(hw, ENETC_PSIIER, val);
 }
 
 static irqreturn_t enetc_msg_psi_msix(int irq, void *data)
@@ -22,7 +22,7 @@ static irqreturn_t enetc_msg_psi_msix(int irq, void *data)
 	struct enetc_si *si = (struct enetc_si *)data;
 	struct enetc_pf *pf = enetc_si_priv(si);
 
-	enetc_msg_disable_mr_int(&si->hw);
+	enetc_msg_set_mr_int(pf, false);
 	schedule_work(&pf->msg_task);
 
 	return IRQ_HANDLED;
@@ -171,7 +171,7 @@ static void enetc_msg_task(struct work_struct *work)
 		if (!mr_mask) {
 			/* re-arm MR interrupts, w1c the IDR reg */
 			enetc_wr(hw, ENETC_PSIIDR, ENETC_PSIIER_MR_MASK);
-			enetc_msg_enable_mr_int(hw);
+			enetc_msg_set_mr_int(pf, true);
 			return;
 		}
 
@@ -264,7 +264,7 @@ static int enetc_msg_psi_init(struct enetc_pf *pf)
 	}
 
 	/* enable MR interrupts */
-	enetc_msg_enable_mr_int(&si->hw);
+	enetc_msg_set_mr_int(pf, true);
 
 	return 0;
 
@@ -285,7 +285,7 @@ static void enetc_msg_psi_free(struct enetc_pf *pf)
 	cancel_work_sync(&pf->msg_task);
 
 	/* disable MR interrupts */
-	enetc_msg_disable_mr_int(&si->hw);
+	enetc_msg_set_mr_int(pf, false);
 
 	for (i = 0; i < pf->num_vfs; i++)
 		enetc_msg_free_mbx(si, i);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net-next 15/15] net: enetc: generate MR interrupt mask based on the number of enabled VFs
  2026-05-11  8:07 [PATCH net-next 00/15] net: enetc: Prepare for ENETC v4 VF support Wei Fang
                   ` (13 preceding siblings ...)
  2026-05-11  8:08 ` [PATCH net-next 14/15] net: enetc: refactor MR interrupt enable/disable helpers Wei Fang
@ 2026-05-11  8:08 ` Wei Fang
  14 siblings, 0 replies; 18+ messages in thread
From: Wei Fang @ 2026-05-11  8:08 UTC (permalink / raw)
  To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
	davem, edumazet, kuba, pabeni
  Cc: imx, netdev, linux-kernel

The current message-receive (MR) interrupt logic relies on the fixed
ENETC_PSIIER_MR_MASK constant to determine which VF MR interrupt bits to
enable or disable. This is sufficient for ENETC v1, where the number of
supported VFs is limited and fixed. However, ENETC v4 devices may support
a different number of VFs across implementations, making a static mask
inadequate: it may fail to cover valid MR interrupt sources or enable
bits for non-existent VFs.

To accommodate hardware with varying VF counts, replace the fixed
ENETC_PSIIER_MR_MASK constant with a new parameterized macro named
PSIIER_MR_MASK(num_vf), which generates the appropriate mask based on
the number of enabled VFs. The macro uses GENMASK_U32(num_vf, 1) to
create a mask covering bits 1 through num_vf, where bit N corresponds
to VF (N-1). This preserves the existing behavior for ENETC v1 (2 VFs)
while also correctly handling devices with different VF counts such as
0, 1, 3, or more VFs as found in ENETC v4 implementations.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 drivers/net/ethernet/freescale/enetc/enetc_hw.h  |  3 ++-
 drivers/net/ethernet/freescale/enetc/enetc_msg.c | 15 ++++++++-------
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
index 94f53762cea8..77dd7913d199 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
@@ -94,7 +94,8 @@ static inline u32 enetc_vsi_set_msize(u32 size)
 #define ENETC_SICAPR1	0x904
 
 #define ENETC_PSIIER	0xa00
-#define ENETC_PSIIER_MR_MASK	GENMASK(2, 1)
+#define  PSIIER_MR_MASK(num_vf)	GENMASK_U32((num_vf), 1)
+
 #define ENETC_PSIIDR	0xa08
 #define ENETC_SITXIDR	0xa18
 #define ENETC_SIRXIDR	0xa28
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_msg.c b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
index 73e32c9b65a8..e9963ea154b0 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_msg.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
@@ -10,9 +10,9 @@ static void enetc_msg_set_mr_int(struct enetc_pf *pf, bool enable)
 
 	val = enetc_rd(hw, ENETC_PSIIER);
 	if (enable)
-		val |= ENETC_PSIIER_MR_MASK;
+		val |= PSIIER_MR_MASK(pf->num_vfs);
 	else
-		val &= ~ENETC_PSIIER_MR_MASK;
+		val &= ~PSIIER_MR_MASK(pf->num_vfs);
 
 	enetc_wr(hw, ENETC_PSIIER, val);
 }
@@ -162,15 +162,16 @@ static void enetc_msg_handle_rxmsg(struct enetc_pf *pf, int vf_id,
 static void enetc_msg_task(struct work_struct *work)
 {
 	struct enetc_pf *pf = container_of(work, struct enetc_pf, msg_task);
+	u32 mr_mask = PSIIER_MR_MASK(pf->num_vfs);
 	struct enetc_hw *hw = &pf->si->hw;
-	unsigned long mr_mask;
+	u32 mr_status;
 	int i;
 
 	for (;;) {
-		mr_mask = enetc_rd(hw, ENETC_PSIMSGRR) & ENETC_PSIMSGRR_MR_MASK;
-		if (!mr_mask) {
+		mr_status = enetc_rd(hw, ENETC_PSIMSGRR) & mr_mask;
+		if (!mr_status) {
 			/* re-arm MR interrupts, w1c the IDR reg */
-			enetc_wr(hw, ENETC_PSIIDR, ENETC_PSIIER_MR_MASK);
+			enetc_wr(hw, ENETC_PSIIDR, mr_mask);
 			enetc_msg_set_mr_int(pf, true);
 			return;
 		}
@@ -179,7 +180,7 @@ static void enetc_msg_task(struct work_struct *work)
 			union enetc_pf_msg pf_msg = {};
 			u32 psimsgrr;
 
-			if (!(ENETC_PSIMSGRR_MR(i) & mr_mask))
+			if (!(ENETC_PSIMSGRR_MR(i) & mr_status))
 				continue;
 
 			enetc_msg_handle_rxmsg(pf, i, &pf_msg);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH net-next 01/15] net: enetc: switch VF primary MAC setter to PF ops for commonization
  2026-05-11  8:07 ` [PATCH net-next 01/15] net: enetc: switch VF primary MAC setter to PF ops for commonization Wei Fang
@ 2026-05-11 15:41   ` Vladimir Oltean
  2026-05-12  1:54     ` Wei Fang
  0 siblings, 1 reply; 18+ messages in thread
From: Vladimir Oltean @ 2026-05-11 15:41 UTC (permalink / raw)
  To: Wei Fang
  Cc: claudiu.manoil, xiaoning.wang, andrew+netdev, davem, edumazet,
	kuba, pabeni, imx, netdev, linux-kernel

On Mon, May 11, 2026 at 04:07:51PM +0800, Wei Fang wrote:
> Use pf->ops->set_si_primary_mac() instead of direct call to
> enetc_pf_set_primary_mac_addr() in preparation for moving
> enetc_msg_pf_set_vf_primary_mac_addr() to enetc-pf-common.
> 
> This enables both ENETC v1 and v4 PF drivers to share the VF MAC
> configuration interface. No functional change.
> 
> Signed-off-by: Wei Fang <wei.fang@nxp.com>
> ---
>  drivers/net/ethernet/freescale/enetc/enetc_pf.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> index a12fd54a475f..9063255d8ca5 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> @@ -497,7 +497,7 @@ static u16 enetc_msg_pf_set_vf_primary_mac_addr(struct enetc_pf *pf,
>  		dev_warn(dev, "Attempt to override PF set mac addr for VF%d\n",
>  			 vf_id);
>  	else
> -		enetc_pf_set_primary_mac_addr(&pf->si->hw, vf_id + 1, addr);
> +		pf->ops->set_si_primary_mac(&pf->si->hw, vf_id + 1, addr);

Doesn't enetc_set_si_hw_addr() exist as a wrapper around
pf->ops->set_si_primary_mac()?

>  
>  	return ENETC_MSG_CMD_STATUS_OK;
>  }
> -- 
> 2.34.1
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH net-next 01/15] net: enetc: switch VF primary MAC setter to PF ops for commonization
  2026-05-11 15:41   ` Vladimir Oltean
@ 2026-05-12  1:54     ` Wei Fang
  0 siblings, 0 replies; 18+ messages in thread
From: Wei Fang @ 2026-05-12  1:54 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Claudiu Manoil, Clark Wang, andrew+netdev@lunn.ch,
	davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
	pabeni@redhat.com, imx@lists.linux.dev, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org

> On Mon, May 11, 2026 at 04:07:51PM +0800, Wei Fang wrote:
> > Use pf->ops->set_si_primary_mac() instead of direct call to
> > enetc_pf_set_primary_mac_addr() in preparation for moving
> > enetc_msg_pf_set_vf_primary_mac_addr() to enetc-pf-common.
> >
> > This enables both ENETC v1 and v4 PF drivers to share the VF MAC
> > configuration interface. No functional change.
> >
> > Signed-off-by: Wei Fang <wei.fang@nxp.com>
> > ---
> >  drivers/net/ethernet/freescale/enetc/enetc_pf.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> > b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> > index a12fd54a475f..9063255d8ca5 100644
> > --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> > +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> > @@ -497,7 +497,7 @@ static u16
> enetc_msg_pf_set_vf_primary_mac_addr(struct enetc_pf *pf,
> >  		dev_warn(dev, "Attempt to override PF set mac addr for VF%d\n",
> >  			 vf_id);
> >  	else
> > -		enetc_pf_set_primary_mac_addr(&pf->si->hw, vf_id + 1, addr);
> > +		pf->ops->set_si_primary_mac(&pf->si->hw, vf_id + 1, addr);
> 
> Doesn't enetc_set_si_hw_addr() exist as a wrapper around
> pf->ops->set_si_primary_mac()?
> 

Yes, enetc_set_si_hw_addr() is the wrapper for
pf->ops->set_si_primary_mac().
I will export enetc_set_si_hw_addr() for enetc_pf.c to use.

> >
> >  	return ENETC_MSG_CMD_STATUS_OK;
> >  }
> > --
> > 2.34.1
> >

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2026-05-12  1:54 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-11  8:07 [PATCH net-next 00/15] net: enetc: Prepare for ENETC v4 VF support Wei Fang
2026-05-11  8:07 ` [PATCH net-next 01/15] net: enetc: switch VF primary MAC setter to PF ops for commonization Wei Fang
2026-05-11 15:41   ` Vladimir Oltean
2026-05-12  1:54     ` Wei Fang
2026-05-11  8:07 ` [PATCH net-next 02/15] net: enetc: move VF message handlers to enetc_msg.c Wei Fang
2026-05-11  8:07 ` [PATCH net-next 03/15] net: enetc: avoid VF->PF mailbox timeout during SR-IOV teardown Wei Fang
2026-05-11  8:07 ` [PATCH net-next 04/15] net: enetc: relocate SR-IOV configuration helper for common PF support Wei Fang
2026-05-11  8:07 ` [PATCH net-next 05/15] net: enetc: integrate enetc_msg.c into enetc-pf-common driver Wei Fang
2026-05-11  8:07 ` [PATCH net-next 06/15] net: enetc: use read_poll_timeout() for VF mailbox polling Wei Fang
2026-05-11  8:07 ` [PATCH net-next 07/15] net: enetc: convert mailbox messages to new formats Wei Fang
2026-05-11  8:07 ` [PATCH net-next 08/15] net: enetc: add VF-PF messaging support for IP minor revision query Wei Fang
2026-05-11  8:07 ` [PATCH net-next 09/15] net: enetc: align v1 CBDR API with v4 for VF driver sharing Wei Fang
2026-05-11  8:08 ` [PATCH net-next 10/15] net: enetc: add CBDR setup/teardown hooks to enetc_si_ops for VF support Wei Fang
2026-05-11  8:08 ` [PATCH net-next 11/15] net: enetc: add generic helper to initialize SR-IOV resources Wei Fang
2026-05-11  8:08 ` [PATCH net-next 12/15] net: enetc: use MADDR_TYPE for MAC filter array size Wei Fang
2026-05-11  8:08 ` [PATCH net-next 13/15] net: enetc: dynamically allocate rxmsg based on VF count Wei Fang
2026-05-11  8:08 ` [PATCH net-next 14/15] net: enetc: refactor MR interrupt enable/disable helpers Wei Fang
2026-05-11  8:08 ` [PATCH net-next 15/15] net: enetc: generate MR interrupt mask based on the number of enabled VFs Wei Fang

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