[PATCH v1] net/idpf: add IDPF PCI class ID support
Vemula Venkatesh
venkatesh.vemula at intel.com
Fri Sep 19 16:51:25 CEST 2025
Current IDPF supports only the MEV device IDs. MMG has new set of device
IDs and same might be the case for the future devices. Instead of adding
new device IDs every time, make use of the IDPF PCI class ID(0x20001) to
differentiate between PF and VF.
Write and read the VF_ARQBAL register to find if the current device is
a PF or a VF.
Signed-off-by: Vemula Venkatesh <venkatesh.vemula at intel.com>
---
.../net/intel/idpf/base/idpf_controlq_api.h | 1 +
drivers/net/intel/idpf/idpf_common_device.c | 31 ++++++++++++++++++-
drivers/net/intel/idpf/idpf_common_device.h | 17 ++++++++++
drivers/net/intel/idpf/idpf_ethdev.c | 2 ++
4 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/drivers/net/intel/idpf/base/idpf_controlq_api.h b/drivers/net/intel/idpf/base/idpf_controlq_api.h
index 8a90258099..7c25aabb28 100644
--- a/drivers/net/intel/idpf/base/idpf_controlq_api.h
+++ b/drivers/net/intel/idpf/base/idpf_controlq_api.h
@@ -184,6 +184,7 @@ struct idpf_hw {
u16 subsystem_device_id;
u16 subsystem_vendor_id;
u8 revision_id;
+ uint32_t cls_id;
bool adapter_stopped;
LIST_HEAD_TYPE(list_head, idpf_ctlq_info) cq_list_head;
diff --git a/drivers/net/intel/idpf/idpf_common_device.c b/drivers/net/intel/idpf/idpf_common_device.c
index ff1fbcd2b4..4ad94da449 100644
--- a/drivers/net/intel/idpf/idpf_common_device.c
+++ b/drivers/net/intel/idpf/idpf_common_device.c
@@ -388,8 +388,21 @@ idpf_adapter_init(struct idpf_adapter *adapter)
{
struct idpf_hw *hw = &adapter->hw;
int ret;
+ int err;
+ bool is_vf = 0;
- if (hw->device_id == IDPF_DEV_ID_SRIOV) {
+ switch (hw->device_id) {
+ case IDPF_DEV_ID_SRIOV:
+ is_vf = 1;
+ break;
+ default:
+ if (hw->cls_id == IDPF_CLASS_NETWORK_ETHERNET_PROGIF) {
+ err = idpf_is_vf_device(hw, &is_vf);
+ if (err)
+ return err;
+ }
+ }
+ if (is_vf) {
ret = idpf_check_vf_reset_done(hw);
} else {
idpf_reset_pf(hw);
@@ -443,6 +456,22 @@ idpf_adapter_init(struct idpf_adapter *adapter)
return ret;
}
+#define IDPF_VF_TEST_VAL 0xFEED0000
+
+/**
+ * idpf_is_vf_device - Helper to find if it is a VF device
+ * @pdev: PCI device information struct
+ * @is_vf: used to update VF device status
+ *
+ * Return: 0 on success, errno on failure.
+ */
+int idpf_is_vf_device(struct idpf_hw *hw, bool *is_vf)
+{
+ IDPF_WRITE_REG(hw, VF_ARQBAL, IDPF_VF_TEST_VAL);
+ *is_vf = (IDPF_READ_REG(hw, VF_ARQBAL) == IDPF_VF_TEST_VAL);
+ return 0;
+}
+
RTE_EXPORT_INTERNAL_SYMBOL(idpf_adapter_deinit)
int
idpf_adapter_deinit(struct idpf_adapter *adapter)
diff --git a/drivers/net/intel/idpf/idpf_common_device.h b/drivers/net/intel/idpf/idpf_common_device.h
index 5f3e4a4fcf..9d1d7dc47c 100644
--- a/drivers/net/intel/idpf/idpf_common_device.h
+++ b/drivers/net/intel/idpf/idpf_common_device.h
@@ -44,6 +44,23 @@
(sizeof(struct virtchnl2_ptype) + \
(((p)->proto_id_count ? ((p)->proto_id_count - 1) : 0) * sizeof((p)->proto_id[0])))
+/** Macro used to help building up tables of device IDs with PCI class */
+#define RTE_PCI_CLASS(cls) \
+ .class_id = (cls), \
+ .vendor_id = RTE_PCI_ANY_ID, \
+ .device_id = RTE_PCI_ANY_ID, \
+ .subsystem_vendor_id = RTE_PCI_ANY_ID, \
+ .subsystem_device_id = RTE_PCI_ANY_ID
+
+
+/* PCI Class network ethernet */
+#define PCI_CLASS_NETWORK_ETHERNET 0x0200
+#define IDPF_NETWORK_ETHERNET_PROGIF 0x01
+#define IDPF_CLASS_NETWORK_ETHERNET_PROGIF \
+ (PCI_CLASS_NETWORK_ETHERNET << 8 | IDPF_NETWORK_ETHERNET_PROGIF)
+
+int idpf_is_vf_device(struct idpf_hw *hw, bool *is_vf);
+
struct idpf_adapter {
struct idpf_hw hw;
struct virtchnl2_version_info virtchnl_version;
diff --git a/drivers/net/intel/idpf/idpf_ethdev.c b/drivers/net/intel/idpf/idpf_ethdev.c
index 90720909bf..7c1db00562 100644
--- a/drivers/net/intel/idpf/idpf_ethdev.c
+++ b/drivers/net/intel/idpf/idpf_ethdev.c
@@ -1201,6 +1201,7 @@ idpf_adapter_ext_init(struct rte_pci_device *pci_dev, struct idpf_adapter_ext *a
hw->vendor_id = pci_dev->id.vendor_id;
hw->device_id = pci_dev->id.device_id;
hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
+ hw->cls_id = pci_dev->id.class_id;
strncpy(adapter->name, pci_dev->device.name, PCI_PRI_STR_SIZE);
@@ -1313,6 +1314,7 @@ idpf_dev_vport_init(struct rte_eth_dev *dev, void *init_params)
static const struct rte_pci_id pci_id_idpf_map[] = {
{ RTE_PCI_DEVICE(IDPF_INTEL_VENDOR_ID, IDPF_DEV_ID_PF) },
{ RTE_PCI_DEVICE(IDPF_INTEL_VENDOR_ID, IDPF_DEV_ID_SRIOV) },
+ { RTE_PCI_CLASS(IDPF_CLASS_NETWORK_ETHERNET_PROGIF) },
{ .vendor_id = 0, /* sentinel */ },
};
--
2.34.1
More information about the dev
mailing list