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>
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)
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;
enetc_free_si_resources(priv);
free_netdev(si->ndev);
- kfree(pf->vf_state);
-
enetc_psi_destroy(pdev);
}
}
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");
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)
{