summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWei Fang <wei.fang@nxp.com>2026-05-22 12:24:36 +0300
committerPaolo Abeni <pabeni@redhat.com>2026-05-26 14:20:13 +0300
commit250069ef0df3e1cf996f03c62eb96d1159cf8166 (patch)
treedc931bcdd9e6b2693d406d4c70ab796002591e7b
parent6bdc3144c0dc737915450c0cd9641ac64c53d714 (diff)
downloadlinux-250069ef0df3e1cf996f03c62eb96d1159cf8166.tar.xz
net: enetc: add generic helper to initialize SR-IOV resources
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> Link: https://patch.msgid.link/20260522092438.1264020-11-wei.fang@nxp.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc_pf.c20
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc_pf_common.c21
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc_pf_common.h1
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 @@ err_alloc_si_res:
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)
{