Added support to read the vendor-specific PCI capability to identify the
type of device being emulated.

Reviewed-by: Dan Carpenter <dan.carpen...@linaro.org>
Signed-off-by: Shijith Thotton <sthot...@marvell.com>
---
 drivers/vdpa/octeon_ep/octep_vdpa.h      | 20 +++++++++++++
 drivers/vdpa/octeon_ep/octep_vdpa_hw.c   | 36 +++++++++++++++++++++++-
 drivers/vdpa/octeon_ep/octep_vdpa_main.c |  4 ++-
 3 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/drivers/vdpa/octeon_ep/octep_vdpa.h 
b/drivers/vdpa/octeon_ep/octep_vdpa.h
index 2cadb878e679..53b020b019f7 100644
--- a/drivers/vdpa/octeon_ep/octep_vdpa.h
+++ b/drivers/vdpa/octeon_ep/octep_vdpa.h
@@ -8,6 +8,7 @@
 #include <linux/pci_regs.h>
 #include <linux/vdpa.h>
 #include <linux/virtio_pci_modern.h>
+#include <uapi/linux/virtio_crypto.h>
 #include <uapi/linux/virtio_net.h>
 #include <uapi/linux/virtio_blk.h>
 #include <uapi/linux/virtio_config.h>
@@ -52,6 +53,24 @@ struct octep_vring_info {
        phys_addr_t notify_pa;
 };
 
+enum octep_pci_vndr_cfg_type {
+       OCTEP_PCI_VNDR_CFG_TYPE_VIRTIO_ID,
+       OCTEP_PCI_VNDR_CFG_TYPE_MAX,
+};
+
+struct octep_pci_vndr_data {
+       struct virtio_pci_vndr_data hdr;
+       u8 id;
+       u8 bar;
+       union {
+               u64 data;
+               struct {
+                       u32 offset;
+                       u32 length;
+               };
+       };
+};
+
 struct octep_hw {
        struct pci_dev *pdev;
        u8 __iomem *base[PCI_STD_NUM_BARS];
@@ -69,6 +88,7 @@ struct octep_hw {
        u32 config_size;
        int nb_irqs;
        int *irqs;
+       u8 dev_id;
 };
 
 u8 octep_hw_get_status(struct octep_hw *oct_hw);
diff --git a/drivers/vdpa/octeon_ep/octep_vdpa_hw.c 
b/drivers/vdpa/octeon_ep/octep_vdpa_hw.c
index d5a599f87e18..74240101c505 100644
--- a/drivers/vdpa/octeon_ep/octep_vdpa_hw.c
+++ b/drivers/vdpa/octeon_ep/octep_vdpa_hw.c
@@ -2,6 +2,7 @@
 /* Copyright (C) 2024 Marvell. */
 
 #include <linux/iopoll.h>
+#include <linux/build_bug.h>
 
 #include "octep_vdpa.h"
 
@@ -358,7 +359,14 @@ u16 octep_get_vq_size(struct octep_hw *oct_hw)
 
 static u32 octep_get_config_size(struct octep_hw *oct_hw)
 {
-       return sizeof(struct virtio_net_config);
+       switch (oct_hw->dev_id) {
+       case VIRTIO_ID_NET:
+               return sizeof(struct virtio_net_config);
+       case VIRTIO_ID_CRYPTO:
+               return sizeof(struct virtio_crypto_config);
+       default:
+               return 0;
+       }
 }
 
 static void __iomem *octep_get_cap_addr(struct octep_hw *oct_hw, struct 
virtio_pci_cap *cap)
@@ -416,8 +424,25 @@ static int octep_pci_signature_verify(struct octep_hw 
*oct_hw)
        return 0;
 }
 
+static void octep_vndr_data_process(struct octep_hw *oct_hw,
+                                   struct octep_pci_vndr_data *vndr_data)
+{
+       BUILD_BUG_ON(sizeof(struct octep_pci_vndr_data) % 4 != 0);
+
+       switch (vndr_data->id) {
+       case OCTEP_PCI_VNDR_CFG_TYPE_VIRTIO_ID:
+               oct_hw->dev_id = (u8)vndr_data->data;
+               break;
+       default:
+               dev_err(&oct_hw->pdev->dev, "Invalid vendor data id %u\n",
+                       vndr_data->id);
+               break;
+       }
+}
+
 int octep_hw_caps_read(struct octep_hw *oct_hw, struct pci_dev *pdev)
 {
+       struct octep_pci_vndr_data vndr_data;
        struct octep_mbox __iomem *mbox;
        struct device *dev = &pdev->dev;
        struct virtio_pci_cap cap;
@@ -466,6 +491,15 @@ int octep_hw_caps_read(struct octep_hw *oct_hw, struct 
pci_dev *pdev)
                case VIRTIO_PCI_CAP_ISR_CFG:
                        oct_hw->isr = octep_get_cap_addr(oct_hw, &cap);
                        break;
+               case VIRTIO_PCI_CAP_VENDOR_CFG:
+                       octep_pci_caps_read(oct_hw, &vndr_data, 
sizeof(vndr_data), pos);
+                       if (vndr_data.hdr.vendor_id != PCI_VENDOR_ID_CAVIUM) {
+                               dev_err(dev, "Invalid vendor data\n");
+                               return -EINVAL;
+                       }
+
+                       octep_vndr_data_process(oct_hw, &vndr_data);
+                       break;
                }
 
                pos = cap.cap_next;
diff --git a/drivers/vdpa/octeon_ep/octep_vdpa_main.c 
b/drivers/vdpa/octeon_ep/octep_vdpa_main.c
index 4d56be64ae56..f3d4dda4e04c 100644
--- a/drivers/vdpa/octeon_ep/octep_vdpa_main.c
+++ b/drivers/vdpa/octeon_ep/octep_vdpa_main.c
@@ -302,7 +302,9 @@ static u32 octep_vdpa_get_generation(struct vdpa_device 
*vdpa_dev)
 
 static u32 octep_vdpa_get_device_id(struct vdpa_device *vdpa_dev)
 {
-       return VIRTIO_ID_NET;
+       struct octep_hw *oct_hw = vdpa_to_octep_hw(vdpa_dev);
+
+       return oct_hw->dev_id;
 }
 
 static u32 octep_vdpa_get_vendor_id(struct vdpa_device *vdpa_dev)
-- 
2.25.1


Reply via email to