* [PATCH v2 net-next 00/12] net: enetc: Prepare for ENETC v4 VF support
@ 2026-05-22 9:24 Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 01/12] net: enetc: use enetc_set_si_hw_addr() for setting MAC address Wei Fang
` (11 more replies)
0 siblings, 12 replies; 13+ messages in thread
From: Wei Fang @ 2026-05-22 9:24 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
- 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
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
- 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.
---
v2:
1. Drop patch 3, 14 and 15 in v1.
2. Use enetc_set_si_hw_addr() instead of pf->ops->set_si_primary_mac()
in patch 1, update title and commit message
3. Refine the implementation of patch 6, such as remove bitfields from
the message structure (struct enetc_msg_header), remove union
enetc_pf_msg, change the prototypes of some functions, add a generic
error code (ENETC_MSG_CLASS_ID_CMD_FAIL) for PF message, and update
the commit message
4. Remove class_code from struct enetc_msg_swbd. enetc_msg_vsi_send()
directly returns the message code for 'get' messages, as the message
code is >= 0
5. Update commit messages of some other patches
v1 link: https://lore.kernel.org/imx/20260511080805.2052495-1-wei.fang@nxp.com/
---
Wei Fang (12):
net: enetc: use enetc_set_si_hw_addr() for setting MAC address
net: enetc: move VF message handlers to enetc_msg.c
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
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 | 1 -
.../ethernet/freescale/enetc/enetc_mailbox.h | 170 ++++++++++++++
.../net/ethernet/freescale/enetc/enetc_msg.c | 209 +++++++++++++++++-
.../net/ethernet/freescale/enetc/enetc_pf.c | 142 +-----------
.../net/ethernet/freescale/enetc/enetc_pf.h | 10 +-
.../freescale/enetc/enetc_pf_common.c | 31 ++-
.../freescale/enetc/enetc_pf_common.h | 11 +
.../net/ethernet/freescale/enetc/enetc_vf.c | 175 +++++++++++----
13 files changed, 581 insertions(+), 214 deletions(-)
create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_mailbox.h
--
2.34.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 net-next 01/12] net: enetc: use enetc_set_si_hw_addr() for setting MAC address
2026-05-22 9:24 [PATCH v2 net-next 00/12] net: enetc: Prepare for ENETC v4 VF support Wei Fang
@ 2026-05-22 9:24 ` Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 02/12] net: enetc: move VF message handlers to enetc_msg.c Wei Fang
` (10 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wei Fang @ 2026-05-22 9:24 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni
Cc: imx, netdev, linux-kernel
Replace enetc_pf_set_primary_mac_addr() with the generic
enetc_set_si_hw_addr() function. This prepares for moving
enetc_msg_pf_set_vf_primary_mac_addr() to the enetc-pf-common driver,
where it can be shared between ENETC v1 and v4 PF drivers.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
drivers/net/ethernet/freescale/enetc/enetc_pf.c | 2 +-
drivers/net/ethernet/freescale/enetc/enetc_pf_common.c | 4 ++--
drivers/net/ethernet/freescale/enetc/enetc_pf_common.h | 1 +
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index 3206b3daa1a0..4d72e2b77072 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -509,7 +509,7 @@ static u16 enetc_msg_pf_set_vf_primary_mac_addr(struct enetc_pf *pf,
return ENETC_MSG_CMD_STATUS_FAIL;
}
- enetc_pf_set_primary_mac_addr(&pf->si->hw, vf_id + 1, addr);
+ enetc_set_si_hw_addr(pf, vf_id + 1, addr);
mutex_unlock(&vf_state->lock);
return ENETC_MSG_CMD_STATUS_OK;
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
index 76263b8566bb..c30b5f71efd5 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
@@ -7,13 +7,13 @@
#include "enetc_pf_common.h"
-static void enetc_set_si_hw_addr(struct enetc_pf *pf, int si,
- const u8 *mac_addr)
+void enetc_set_si_hw_addr(struct enetc_pf *pf, int si, const u8 *mac_addr)
{
struct enetc_hw *hw = &pf->si->hw;
pf->ops->set_si_primary_mac(hw, si, mac_addr);
}
+EXPORT_SYMBOL_GPL(enetc_set_si_hw_addr);
static void enetc_get_si_hw_addr(struct enetc_pf *pf, int si, u8 *mac_addr)
{
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
index 96d4840a3107..cef9fcc58e2f 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
@@ -3,6 +3,7 @@
#include "enetc_pf.h"
+void enetc_set_si_hw_addr(struct enetc_pf *pf, int si, const u8 *mac_addr);
int enetc_pf_set_mac_addr(struct net_device *ndev, void *addr);
int enetc_setup_mac_addresses(struct device_node *np, struct enetc_pf *pf);
void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 net-next 02/12] net: enetc: move VF message handlers to enetc_msg.c
2026-05-22 9:24 [PATCH v2 net-next 00/12] net: enetc: Prepare for ENETC v4 VF support Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 01/12] net: enetc: use enetc_set_si_hw_addr() for setting MAC address Wei Fang
@ 2026-05-22 9:24 ` Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 03/12] net: enetc: relocate SR-IOV configuration helper for common PF support Wei Fang
` (9 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wei Fang @ 2026-05-22 9:24 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 | 78 ++++++++++++++++++-
.../net/ethernet/freescale/enetc/enetc_pf.c | 75 ------------------
.../net/ethernet/freescale/enetc/enetc_pf.h | 1 -
3 files changed, 77 insertions(+), 77 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_msg.c b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
index c09635e7eb3d..73da2018034e 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_pf *pf)
{
@@ -35,6 +35,82 @@ 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, void *msg)
+{
+ struct enetc_vf_state *vf_state = &pf->vf_state[vf_id];
+ struct enetc_msg_cmd_set_primary_mac *cmd = msg;
+ struct device *dev = &pf->si->pdev->dev;
+ u16 cmd_id = cmd->header.id;
+ char *addr;
+
+ if (cmd_id != ENETC_MSG_CMD_MNG_ADD)
+ return ENETC_MSG_CMD_STATUS_FAIL;
+
+ addr = cmd->mac.sa_data;
+ if (!is_valid_ether_addr(addr)) {
+ dev_err_ratelimited(dev, "VF%d attempted to set invalid MAC\n",
+ vf_id);
+ return ENETC_MSG_CMD_STATUS_FAIL;
+ }
+
+ mutex_lock(&vf_state->lock);
+ if (vf_state->flags & ENETC_VF_FLAG_PF_SET_MAC) {
+ mutex_unlock(&vf_state->lock);
+ dev_err_ratelimited(dev,
+ "VF%d attempted to override PF set MAC\n",
+ vf_id);
+ return ENETC_MSG_CMD_STATUS_FAIL;
+ }
+
+ enetc_set_si_hw_addr(pf, vf_id + 1, addr);
+ mutex_unlock(&vf_state->lock);
+
+ 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_swbd = &pf->rxmsg[vf_id];
+ struct device *dev = &pf->si->pdev->dev;
+ struct enetc_msg_cmd_header *cmd_hdr;
+ u16 cmd_type;
+ u8 *msg;
+
+ msg = kzalloc_objs(*msg, msg_swbd->size);
+ if (!msg) {
+ dev_err_ratelimited(dev,
+ "Failed to allocate message buffer\n");
+ *status = ENETC_MSG_CMD_STATUS_FAIL;
+ return;
+ }
+
+ /* Currently, only ENETC_MSG_CMD_MNG_MAC command is supported, so
+ * only sizeof(struct enetc_msg_cmd_set_primary_mac) bytes need to
+ * be copied. This data already includes the cmd_type field, so it
+ * can correctly return an error code.
+ */
+ memcpy(msg, msg_swbd->vaddr,
+ sizeof(struct enetc_msg_cmd_set_primary_mac));
+ cmd_hdr = (struct enetc_msg_cmd_header *)msg;
+ 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, msg);
+ break;
+ default:
+ *status = ENETC_MSG_CMD_STATUS_FAIL;
+ dev_err_ratelimited(dev,
+ "command not supported (cmd_type: 0x%x)\n",
+ cmd_type);
+ }
+
+ kfree(msg);
+}
+
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 4d72e2b77072..67cc80adec72 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -480,81 +480,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, void *msg)
-{
- struct enetc_vf_state *vf_state = &pf->vf_state[vf_id];
- struct enetc_msg_cmd_set_primary_mac *cmd = msg;
- struct device *dev = &pf->si->pdev->dev;
- u16 cmd_id = cmd->header.id;
- char *addr;
-
- if (cmd_id != ENETC_MSG_CMD_MNG_ADD)
- return ENETC_MSG_CMD_STATUS_FAIL;
-
- addr = cmd->mac.sa_data;
- if (!is_valid_ether_addr(addr)) {
- dev_err_ratelimited(dev, "VF%d attempted to set invalid MAC\n",
- vf_id);
- return ENETC_MSG_CMD_STATUS_FAIL;
- }
-
- mutex_lock(&vf_state->lock);
- if (vf_state->flags & ENETC_VF_FLAG_PF_SET_MAC) {
- mutex_unlock(&vf_state->lock);
- dev_err_ratelimited(dev,
- "VF%d attempted to override PF set MAC\n",
- vf_id);
- return ENETC_MSG_CMD_STATUS_FAIL;
- }
-
- enetc_set_si_hw_addr(pf, vf_id + 1, addr);
- mutex_unlock(&vf_state->lock);
-
- 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_swbd = &pf->rxmsg[vf_id];
- struct device *dev = &pf->si->pdev->dev;
- struct enetc_msg_cmd_header *cmd_hdr;
- u16 cmd_type;
- u8 *msg;
-
- msg = kzalloc_objs(*msg, msg_swbd->size);
- if (!msg) {
- dev_err_ratelimited(dev,
- "Failed to allocate message buffer\n");
- *status = ENETC_MSG_CMD_STATUS_FAIL;
- return;
- }
-
- /* Currently, only ENETC_MSG_CMD_MNG_MAC command is supported, so
- * only sizeof(struct enetc_msg_cmd_set_primary_mac) bytes need to
- * be copied. This data already includes the cmd_type field, so it
- * can correctly return an error code.
- */
- memcpy(msg, msg_swbd->vaddr,
- sizeof(struct enetc_msg_cmd_set_primary_mac));
- cmd_hdr = (struct enetc_msg_cmd_header *)msg;
- 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, msg);
- break;
- default:
- *status = ENETC_MSG_CMD_STATUS_FAIL;
- dev_err_ratelimited(dev,
- "command not supported (cmd_type: 0x%x)\n",
- cmd_type);
- }
-
- kfree(msg);
-}
-
#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 35d484858c7b..3b265ad8d845 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
@@ -71,4 +71,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] 13+ messages in thread
* [PATCH v2 net-next 03/12] net: enetc: relocate SR-IOV configuration helper for common PF support
2026-05-22 9:24 [PATCH v2 net-next 00/12] net: enetc: Prepare for ENETC v4 VF support Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 01/12] net: enetc: use enetc_set_si_hw_addr() for setting MAC address Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 02/12] net: enetc: move VF message handlers to enetc_msg.c Wei Fang
@ 2026-05-22 9:24 ` Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 04/12] net: enetc: integrate enetc_msg.c into enetc-pf-common driver Wei Fang
` (8 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wei Fang @ 2026-05-22 9:24 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 | 3 --
.../freescale/enetc/enetc_pf_common.h | 9 +++++
4 files changed, 47 insertions(+), 45 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_msg.c b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
index 73da2018034e..fd1a42bbdcb1 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_msg.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
@@ -189,7 +189,7 @@ static void enetc_msg_free_mbx(struct enetc_si *si, int idx)
memset(msg, 0, sizeof(*msg));
}
-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;
@@ -229,7 +229,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;
@@ -248,3 +248,39 @@ void enetc_msg_psi_free(struct enetc_pf *pf)
for (i = 0; i < pf->num_vfs; i++)
enetc_msg_free_mbx(si, i);
}
+
+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 67cc80adec72..fbe2c126082e 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -480,46 +480,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 3b265ad8d845..5b4094f8d5d4 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
@@ -68,6 +68,3 @@ 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);
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
index cef9fcc58e2f..c9b3512d4e2f 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
@@ -21,3 +21,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] 13+ messages in thread
* [PATCH v2 net-next 04/12] net: enetc: integrate enetc_msg.c into enetc-pf-common driver
2026-05-22 9:24 [PATCH v2 net-next 00/12] net: enetc: Prepare for ENETC v4 VF support Wei Fang
` (2 preceding siblings ...)
2026-05-22 9:24 ` [PATCH v2 net-next 03/12] net: enetc: relocate SR-IOV configuration helper for common PF support Wei Fang
@ 2026-05-22 9:24 ` Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 05/12] net: enetc: use read_poll_timeout() for VF mailbox polling Wei Fang
` (7 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wei Fang @ 2026-05-22 9:24 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
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 | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
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 fd1a42bbdcb1..f696751c00ea 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_msg.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
@@ -284,3 +284,4 @@ int enetc_sriov_configure(struct pci_dev *pdev, int num_vfs)
return err;
}
+EXPORT_SYMBOL_GPL(enetc_sriov_configure);
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 net-next 05/12] net: enetc: use read_poll_timeout() for VF mailbox polling
2026-05-22 9:24 [PATCH v2 net-next 00/12] net: enetc: Prepare for ENETC v4 VF support Wei Fang
` (3 preceding siblings ...)
2026-05-22 9:24 ` [PATCH v2 net-next 04/12] net: enetc: integrate enetc_msg.c into enetc-pf-common driver Wei Fang
@ 2026-05-22 9:24 ` Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 06/12] net: enetc: convert mailbox messages to new formats Wei Fang
` (6 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wei Fang @ 2026-05-22 9:24 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 | 19 +++++++------------
1 file changed, 7 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..9065bdbd02aa 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/* Copyright 2017-2019 NXP */
+#include <linux/iopoll.h>
#include <linux/module.h>
#include "enetc.h"
@@ -28,8 +29,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 +49,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] 13+ messages in thread
* [PATCH v2 net-next 06/12] net: enetc: convert mailbox messages to new formats
2026-05-22 9:24 [PATCH v2 net-next 00/12] net: enetc: Prepare for ENETC v4 VF support Wei Fang
` (4 preceding siblings ...)
2026-05-22 9:24 ` [PATCH v2 net-next 05/12] net: enetc: use read_poll_timeout() for VF mailbox polling Wei Fang
@ 2026-05-22 9:24 ` Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 07/12] net: enetc: add VF-PF messaging support for IP minor revision query Wei Fang
` (5 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wei Fang @ 2026-05-22 9:24 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.
Note that switch to the new message format will not affect ENETC v1
(LS1028A). Due to a hardware limitation of ENETC v1, the ENETC PF and
VFs can only be controlled by the same OS. If the PF is controlled by
the Linux kernel driver, then the VFs must also be controlled by the
Linux kernel driver.
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 | 151 ++++++++++++++++++
.../net/ethernet/freescale/enetc/enetc_msg.c | 127 +++++++++++----
.../net/ethernet/freescale/enetc/enetc_vf.c | 97 ++++++++---
6 files changed, 326 insertions(+), 70 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..db5c17a44613 100644
--- a/drivers/net/ethernet/freescale/enetc/Kconfig
+++ b/drivers/net/ethernet/freescale/enetc/Kconfig
@@ -10,6 +10,7 @@ config FSL_ENETC_CORE
config NXP_ENETC_PF_COMMON
tristate
+ select CRC_ITU_T
help
This module supports common functionality between drivers of
different versions of NXP ENETC PF controllers.
@@ -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..86a51bae19f3
--- /dev/null
+++ b/drivers/net/ethernet/freescale/enetc/enetc_mailbox.h
@@ -0,0 +1,151 @@
+/* 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)
+
+/* The cookie filed of VSI-to-PSI message */
+#define ENETC_VF_MSG_COOKIE GENMASK(3, 0)
+/* The fileds of PSI-to-VSI message, the message is only 16-bit */
+#define ENETC_PF_MSG_COOKIE GENMASK(3, 0)
+#define ENETC_PF_MSG_CLASS_CODE GENMASK(7, 4)
+#define ENETC_PF_MSG_CLASS_ID GENMASK(15, 8)
+
+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_NOT_PERMITTED,
+ ENETC_MSG_CLASS_ID_CMD_FAIL, /* Generic error code for failure */
+ 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 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;
+ 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 f696751c00ea..4ab123cbfbec 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_msg.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
@@ -3,6 +3,11 @@
#include "enetc_pf_common.h"
+#define ENETC_PF_MSG_SUCCESS FIELD_PREP(ENETC_PF_MSG_CLASS_ID, \
+ ENETC_MSG_CLASS_ID_CMD_SUCCESS)
+#define ENETC_PF_MSG_NOTSUPP FIELD_PREP(ENETC_PF_MSG_CLASS_ID, \
+ ENETC_MSG_CLASS_ID_CMD_NOT_SUPPORT)
+
static void enetc_msg_disable_mr_int(struct enetc_pf *pf)
{
struct enetc_hw *hw = &pf->si->hw;
@@ -36,23 +41,35 @@ 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, void *msg)
+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;
+
+ 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 u16 enetc_msg_set_vf_primary_mac_addr(struct enetc_pf *pf, int vf_id,
+ void *vf_msg)
{
struct enetc_vf_state *vf_state = &pf->vf_state[vf_id];
- struct enetc_msg_cmd_set_primary_mac *cmd = msg;
+ struct enetc_msg_mac_exact_filter *msg = vf_msg;
struct device *dev = &pf->si->pdev->dev;
- u16 cmd_id = cmd->header.id;
- char *addr;
-
- if (cmd_id != ENETC_MSG_CMD_MNG_ADD)
- return ENETC_MSG_CMD_STATUS_FAIL;
+ char *addr = msg->mac[0].addr;
- addr = cmd->mac.sa_data;
if (!is_valid_ether_addr(addr)) {
dev_err_ratelimited(dev, "VF%d attempted to set invalid MAC\n",
vf_id);
- return ENETC_MSG_CMD_STATUS_FAIL;
+ return (FIELD_PREP(ENETC_PF_MSG_CLASS_ID,
+ ENETC_MSG_CLASS_ID_MAC_FILTER) |
+ FIELD_PREP(ENETC_PF_MSG_CLASS_CODE,
+ ENETC_MF_CLASS_CODE_INVALID_MAC));
}
mutex_lock(&vf_state->lock);
@@ -61,53 +78,97 @@ static u16 enetc_msg_pf_set_vf_primary_mac_addr(struct enetc_pf *pf,
dev_err_ratelimited(dev,
"VF%d attempted to override PF set MAC\n",
vf_id);
- return ENETC_MSG_CMD_STATUS_FAIL;
+ return FIELD_PREP(ENETC_PF_MSG_CLASS_ID,
+ ENETC_MSG_CLASS_ID_CMD_NOT_PERMITTED);
}
enetc_set_si_hw_addr(pf, vf_id + 1, addr);
mutex_unlock(&vf_state->lock);
- return ENETC_MSG_CMD_STATUS_OK;
+ return ENETC_PF_MSG_SUCCESS;
+}
+
+static u16 enetc_msg_handle_mac_filter(struct enetc_pf *pf, int vf_id,
+ void *vf_msg)
+{
+ struct enetc_msg_header *msg_hdr = vf_msg;
+
+ switch (msg_hdr->cmd_id) {
+ case ENETC_MSG_SET_PRIMARY_MAC:
+ return enetc_msg_set_vf_primary_mac_addr(pf, vf_id, vf_msg);
+ default:
+ return ENETC_PF_MSG_NOTSUPP;
+ }
}
static void enetc_msg_handle_rxmsg(struct enetc_pf *pf, int vf_id,
- u16 *status)
+ u16 *pf_msg)
{
struct enetc_msg_swbd *msg_swbd = &pf->rxmsg[vf_id];
+ struct enetc_msg_header *msg_hdr = msg_swbd->vaddr;
+ u32 msg_size = ENETC_MSG_SIZE(msg_hdr->len);
struct device *dev = &pf->si->pdev->dev;
- struct enetc_msg_cmd_header *cmd_hdr;
- u16 cmd_type;
u8 *msg;
- msg = kzalloc_objs(*msg, msg_swbd->size);
+ if (msg_size > ENETC_DEFAULT_MSG_SIZE) {
+ dev_err_ratelimited(dev,
+ "Invalid message size: %u\n", msg_size);
+ *pf_msg = FIELD_PREP(ENETC_PF_MSG_CLASS_ID,
+ ENETC_MSG_CLASS_ID_INVALID_MSG_LEN);
+ return;
+ }
+
+ /* To prevent malicious VF from tampering with the original data by
+ * sending new messages after passing the check, the DMA buffer data
+ * is copied to the msg buffer before validation.
+ */
+ msg = kzalloc_objs(*msg, msg_size);
if (!msg) {
dev_err_ratelimited(dev,
"Failed to allocate message buffer\n");
- *status = ENETC_MSG_CMD_STATUS_FAIL;
+ *pf_msg = FIELD_PREP(ENETC_PF_MSG_CLASS_ID,
+ ENETC_MSG_CLASS_ID_CMD_FAIL);
return;
}
- /* Currently, only ENETC_MSG_CMD_MNG_MAC command is supported, so
- * only sizeof(struct enetc_msg_cmd_set_primary_mac) bytes need to
- * be copied. This data already includes the cmd_type field, so it
- * can correctly return an error code.
- */
- memcpy(msg, msg_swbd->vaddr,
- sizeof(struct enetc_msg_cmd_set_primary_mac));
- cmd_hdr = (struct enetc_msg_cmd_header *)msg;
- 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, msg);
+ memcpy(msg, msg_swbd->vaddr, msg_size);
+ if (!enetc_msg_check_crc16(msg, msg_size)) {
+ dev_err_ratelimited(dev, "VSI to PSI Message CRC16 error\n");
+ *pf_msg = FIELD_PREP(ENETC_PF_MSG_CLASS_ID,
+ ENETC_MSG_CLASS_ID_CRC_ERROR);
+
+ goto free_msg;
+ }
+
+ /* Default to not supported */
+ *pf_msg = ENETC_PF_MSG_NOTSUPP;
+ msg_hdr = (struct enetc_msg_header *)msg;
+
+ /* Currently, asynchronous actions are not supported */
+ if (FIELD_GET(ENETC_VF_MSG_COOKIE, msg_hdr->cookie)) {
+ dev_err_ratelimited(dev,
+ "Cookie field is not supported yet\n");
+ goto free_msg;
+ }
+
+ /* Currently only support protocol version 0 */
+ if (msg_hdr->proto_ver) {
+ dev_err_ratelimited(dev, "Unsupported protocol version %u\n",
+ msg_hdr->proto_ver);
+ goto free_msg;
+ }
+
+ switch (msg_hdr->class_id) {
+ case ENETC_MSG_CLASS_ID_MAC_FILTER:
+ *pf_msg = enetc_msg_handle_mac_filter(pf, vf_id, msg);
break;
default:
- *status = ENETC_MSG_CMD_STATUS_FAIL;
dev_err_ratelimited(dev,
- "command not supported (cmd_type: 0x%x)\n",
- cmd_type);
+ "Unsupported message class ID: 0x%x\n",
+ msg_hdr->class_id);
}
+free_msg:
kfree(msg);
}
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
index 9065bdbd02aa..77c0eddba6e2 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
@@ -7,7 +7,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 = FIELD_PREP(ENETC_VF_MSG_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)
{
@@ -30,6 +52,7 @@ static int enetc_msg_vsi_send(struct enetc_si *si, struct enetc_msg_swbd *msg)
{
struct device *dev = &si->pdev->dev;
u32 vsimsgsr;
+ u16 pf_msg;
int err;
/* The VSI mailbox may be busy if last message was not yet processed
@@ -60,36 +83,72 @@ 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 = ENETC_SIMSGSR_GET_MC(vsimsgsr);
+ /* Check the user-defined completion status. */
+ if (FIELD_GET(ENETC_PF_MSG_CLASS_ID, pf_msg) !=
+ ENETC_MSG_CLASS_ID_CMD_SUCCESS) {
+ switch (FIELD_GET(ENETC_PF_MSG_CLASS_ID, pf_msg)) {
+ case ENETC_MSG_CLASS_ID_PERMISSION_DENY:
+ /* Intentionally returning early to prevent excessive
+ * error logs due to permission issues.
+ */
+ 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;
+ case ENETC_MSG_CLASS_ID_CMD_NOT_PERMITTED:
+ err = -EPERM;
+ break;
+ case ENETC_MSG_CLASS_ID_CMD_FAIL:
+ case ENETC_MSG_CLASS_ID_CRC_ERROR:
+ case ENETC_MSG_CLASS_ID_CMD_DEFERRED:
+ default:
+ err = -EIO;
+ }
+ }
+
+ if (err)
+ dev_err(dev, "Return error code from PSI: 0x%04x\n", pf_msg);
+
+ 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] 13+ messages in thread
* [PATCH v2 net-next 07/12] net: enetc: add VF-PF messaging support for IP minor revision query
2026-05-22 9:24 [PATCH v2 net-next 00/12] net: enetc: Prepare for ENETC v4 VF support Wei Fang
` (5 preceding siblings ...)
2026-05-22 9:24 ` [PATCH v2 net-next 06/12] net: enetc: convert mailbox messages to new formats Wei Fang
@ 2026-05-22 9:24 ` Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 08/12] net: enetc: align v1 CBDR API with v4 for VF driver sharing Wei Fang
` (4 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wei Fang @ 2026-05-22 9:24 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 | 19 +++++++
.../net/ethernet/freescale/enetc/enetc_msg.c | 29 +++++++++++
.../net/ethernet/freescale/enetc/enetc_vf.c | 52 +++++++++++++++++--
3 files changed, 97 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_mailbox.h b/drivers/net/ethernet/freescale/enetc/enetc_mailbox.h
index 86a51bae19f3..d9677da38989 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
@@ -84,6 +87,8 @@
/* The fileds of PSI-to-VSI message, the message is only 16-bit */
#define ENETC_PF_MSG_COOKIE GENMASK(3, 0)
#define ENETC_PF_MSG_CLASS_CODE GENMASK(7, 4)
+/* Extend the class code to 8-bit for GET messages without COOKIE */
+#define ENETC_PF_MSG_CLASS_CODE_U8 GENMASK(7, 0)
#define ENETC_PF_MSG_CLASS_ID GENMASK(15, 8)
enum enetc_msg_class_id {
@@ -102,12 +107,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,
@@ -148,4 +158,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 4ab123cbfbec..edc1277bb586 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_msg.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
@@ -101,6 +101,21 @@ static u16 enetc_msg_handle_mac_filter(struct enetc_pf *pf, int vf_id,
}
}
+static u16 enetc_msg_handle_ip_revision(struct enetc_pf *pf, void *vf_msg)
+{
+ struct enetc_msg_header *msg_hdr = vf_msg;
+
+ switch (msg_hdr->cmd_id) {
+ case ENETC_MSG_GET_IP_MN:
+ return (FIELD_PREP(ENETC_PF_MSG_CLASS_ID,
+ ENETC_MSG_CLASS_ID_IP_REVISION) |
+ FIELD_PREP(ENETC_PF_MSG_CLASS_CODE_U8,
+ pf->si->revision));
+ default:
+ return ENETC_PF_MSG_NOTSUPP;
+ }
+}
+
static void enetc_msg_handle_rxmsg(struct enetc_pf *pf, int vf_id,
u16 *pf_msg)
{
@@ -158,10 +173,24 @@ static void enetc_msg_handle_rxmsg(struct enetc_pf *pf, int vf_id,
goto free_msg;
}
+ /* 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_ratelimited(dev, "Unsupported message for ENETC v1\n");
+
+ goto free_msg;
+ }
+
switch (msg_hdr->class_id) {
case ENETC_MSG_CLASS_ID_MAC_FILTER:
*pf_msg = enetc_msg_handle_mac_filter(pf, vf_id, msg);
break;
+ case ENETC_MSG_CLASS_ID_IP_REVISION:
+ *pf_msg = enetc_msg_handle_ip_revision(pf, msg);
+ break;
default:
dev_err_ratelimited(dev,
"Unsupported message class ID: 0x%x\n",
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
index 77c0eddba6e2..7d022b9c12d7 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
@@ -114,6 +114,9 @@ static int enetc_msg_vsi_send(struct enetc_si *si, struct enetc_msg_swbd *msg)
case ENETC_MSG_CLASS_ID_CMD_NOT_PERMITTED:
err = -EPERM;
break;
+ case ENETC_MSG_CLASS_ID_IP_REVISION:
+ err = FIELD_GET(ENETC_PF_MSG_CLASS_CODE_U8, pf_msg);
+ break;
case ENETC_MSG_CLASS_ID_CMD_FAIL:
case ENETC_MSG_CLASS_ID_CRC_ERROR:
case ENETC_MSG_CLASS_ID_CMD_DEFERRED:
@@ -122,7 +125,7 @@ static int enetc_msg_vsi_send(struct enetc_si *si, struct enetc_msg_swbd *msg)
}
}
- if (err)
+ if (err < 0)
dev_err(dev, "Return error code from PSI: 0x%04x\n", pf_msg);
return err;
@@ -151,6 +154,24 @@ 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;
+
+ 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);
+
+ return enetc_msg_vsi_send(si, &msg_swbd);
+}
+
static int enetc_vf_set_mac_addr(struct net_device *ndev, void *addr)
{
struct enetc_ndev_priv *priv = netdev_priv(ndev);
@@ -202,6 +223,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)
{
@@ -252,6 +294,7 @@ static int enetc_vf_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct enetc_ndev_priv *priv;
+ struct enetc_msg_swbd msg;
struct net_device *ndev;
struct enetc_si *si;
int err;
@@ -261,13 +304,13 @@ 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) {
dev_err_probe(&pdev->dev, err,
"Could not get VF driver data\n");
- goto err_alloc_netdev;
+ goto err_get_driver_data;
}
enetc_get_si_caps(si);
@@ -327,7 +370,10 @@ static int enetc_vf_probe(struct pci_dev *pdev,
si->ndev = NULL;
free_netdev(ndev);
err_alloc_netdev:
+err_get_driver_data:
+ msg = si->msg;
enetc_pci_remove(pdev);
+ enetc_msg_dma_free(&pdev->dev, &msg);
return err;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 net-next 08/12] net: enetc: align v1 CBDR API with v4 for VF driver sharing
2026-05-22 9:24 [PATCH v2 net-next 00/12] net: enetc: Prepare for ENETC v4 VF support Wei Fang
` (6 preceding siblings ...)
2026-05-22 9:24 ` [PATCH v2 net-next 07/12] net: enetc: add VF-PF messaging support for IP minor revision query Wei Fang
@ 2026-05-22 9:24 ` Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 09/12] net: enetc: add CBDR setup/teardown hooks to enetc_si_ops for VF support Wei Fang
` (3 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wei Fang @ 2026-05-22 9:24 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, the .setup_cbdr() and
.teardown_cbdr() hooks will be added to struct enetc_si_ops, allowing
the driver to register version-specific implementations. So refactor 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 in the subsequent patch.
Changes:
- Update enetc_setup_cbdr() and enetc_teardown_cbdr() prototypes to
take 'struct enetc_si *' as the sole parameter
- Extract parameters (dev, hw) from the enetc_si structure within the
function implementations
- ENETC_CBDR_DEFAULT_SIZE has always been used as the number of command
BDs, and there is no need to adjust the size of the command BD ring.
Therefore, ENETC_CBDR_DEFAULT_SIZE is moved into the enetc_setup_cbdr()
- 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 fbe2c126082e..7a5dcbfeb693 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -802,8 +802,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;
@@ -822,7 +821,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:
@@ -833,7 +832,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 7d022b9c12d7..e8ad5ad5aba4 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
@@ -328,8 +328,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;
@@ -365,7 +364,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);
@@ -390,7 +389,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] 13+ messages in thread
* [PATCH v2 net-next 09/12] net: enetc: add CBDR setup/teardown hooks to enetc_si_ops for VF support
2026-05-22 9:24 [PATCH v2 net-next 00/12] net: enetc: Prepare for ENETC v4 VF support Wei Fang
` (7 preceding siblings ...)
2026-05-22 9:24 ` [PATCH v2 net-next 08/12] net: enetc: align v1 CBDR API with v4 for VF driver sharing Wei Fang
@ 2026-05-22 9:24 ` Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 10/12] net: enetc: add generic helper to initialize SR-IOV resources Wei Fang
` (2 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wei Fang @ 2026-05-22 9:24 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 e8ad5ad5aba4..9cdb0a4d6baf 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
@@ -288,6 +288,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,
@@ -328,7 +330,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;
@@ -364,7 +366,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);
@@ -389,7 +391,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] 13+ messages in thread
* [PATCH v2 net-next 10/12] net: enetc: add generic helper to initialize SR-IOV resources
2026-05-22 9:24 [PATCH v2 net-next 00/12] net: enetc: Prepare for ENETC v4 VF support Wei Fang
` (8 preceding siblings ...)
2026-05-22 9:24 ` [PATCH v2 net-next 09/12] net: enetc: add CBDR setup/teardown hooks to enetc_si_ops for VF support Wei Fang
@ 2026-05-22 9:24 ` Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 11/12] net: enetc: use MADDR_TYPE for MAC filter array size Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 12/12] net: enetc: dynamically allocate rxmsg based on VF count Wei Fang
11 siblings, 0 replies; 13+ messages in thread
From: Wei Fang @ 2026-05-22 9:24 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 | 20 ++++--------------
.../freescale/enetc/enetc_pf_common.c | 21 +++++++++++++++++++
.../freescale/enetc/enetc_pf_common.h | 1 +
3 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index 7a5dcbfeb693..2d687bb8c3a0 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -872,18 +872,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) {
- err = -ENOMEM;
- goto err_alloc_vf_state;
- }
-
- for (int i = 0; i < pf->total_vfs; i++)
- mutex_init(&pf->vf_state[i].lock);
- }
+ err = enetc_init_sriov_resources(pf);
+ if (err)
+ goto err_init_sriov_resources;
err = enetc_setup_mac_addresses(node, pf);
if (err)
@@ -961,8 +952,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;
@@ -989,8 +979,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 c30b5f71efd5..c423eed6bc78 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
@@ -435,5 +435,26 @@ 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;
+
+ for (int i = 0; i < pf->total_vfs; i++)
+ mutex_init(&pf->vf_state[i].lock);
+
+ 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 c9b3512d4e2f..57d2e0ebd2b0 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
@@ -16,6 +16,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] 13+ messages in thread
* [PATCH v2 net-next 11/12] net: enetc: use MADDR_TYPE for MAC filter array size
2026-05-22 9:24 [PATCH v2 net-next 00/12] net: enetc: Prepare for ENETC v4 VF support Wei Fang
` (9 preceding siblings ...)
2026-05-22 9:24 ` [PATCH v2 net-next 10/12] net: enetc: add generic helper to initialize SR-IOV resources Wei Fang
@ 2026-05-22 9:24 ` Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 12/12] net: enetc: dynamically allocate rxmsg based on VF count Wei Fang
11 siblings, 0 replies; 13+ messages in thread
From: Wei Fang @ 2026-05-22 9:24 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 5b4094f8d5d4..64e2c738e8e7 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 {
@@ -43,7 +41,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] 13+ messages in thread
* [PATCH v2 net-next 12/12] net: enetc: dynamically allocate rxmsg based on VF count
2026-05-22 9:24 [PATCH v2 net-next 00/12] net: enetc: Prepare for ENETC v4 VF support Wei Fang
` (10 preceding siblings ...)
2026-05-22 9:24 ` [PATCH v2 net-next 11/12] net: enetc: use MADDR_TYPE for MAC filter array size Wei Fang
@ 2026-05-22 9:24 ` Wei Fang
11 siblings, 0 replies; 13+ messages in thread
From: Wei Fang @ 2026-05-22 9:24 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 e58cc81d199d..bf99b65d7598 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
@@ -681,7 +681,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 64e2c738e8e7..285b7e5c48fd 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
@@ -43,7 +43,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 c423eed6bc78..6e5d2f869915 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
@@ -443,6 +443,12 @@ int enetc_init_sriov_resources(struct enetc_pf *pf)
if (!pf->total_vfs)
return 0;
+ pf->rxmsg = devm_kcalloc(dev, pf->total_vfs,
+ sizeof(struct enetc_msg_swbd),
+ GFP_KERNEL);
+ if (!pf->rxmsg)
+ return -ENOMEM;
+
pf->vf_state = devm_kcalloc(dev, pf->total_vfs,
sizeof(struct enetc_vf_state),
GFP_KERNEL);
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-05-22 9:22 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-22 9:24 [PATCH v2 net-next 00/12] net: enetc: Prepare for ENETC v4 VF support Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 01/12] net: enetc: use enetc_set_si_hw_addr() for setting MAC address Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 02/12] net: enetc: move VF message handlers to enetc_msg.c Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 03/12] net: enetc: relocate SR-IOV configuration helper for common PF support Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 04/12] net: enetc: integrate enetc_msg.c into enetc-pf-common driver Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 05/12] net: enetc: use read_poll_timeout() for VF mailbox polling Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 06/12] net: enetc: convert mailbox messages to new formats Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 07/12] net: enetc: add VF-PF messaging support for IP minor revision query Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 08/12] net: enetc: align v1 CBDR API with v4 for VF driver sharing Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 09/12] net: enetc: add CBDR setup/teardown hooks to enetc_si_ops for VF support Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 10/12] net: enetc: add generic helper to initialize SR-IOV resources Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 11/12] net: enetc: use MADDR_TYPE for MAC filter array size Wei Fang
2026-05-22 9:24 ` [PATCH v2 net-next 12/12] net: enetc: dynamically allocate rxmsg based on VF count Wei Fang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox