]> www.infradead.org Git - users/willy/pagecache.git/commitdiff
vdpa/octeon_ep: read vendor-specific PCI capability
authorShijith Thotton <sthotton@marvell.com>
Fri, 3 Jan 2025 15:31:37 +0000 (21:01 +0530)
committerMichael S. Tsirkin <mst@redhat.com>
Mon, 27 Jan 2025 14:39:25 +0000 (09:39 -0500)
Added support to read the vendor-specific PCI capability to identify the
type of device being emulated.

Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Shijith Thotton <sthotton@marvell.com>
Message-Id: <20250103153226.1933479-4-sthotton@marvell.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
drivers/vdpa/octeon_ep/octep_vdpa.h
drivers/vdpa/octeon_ep/octep_vdpa_hw.c
drivers/vdpa/octeon_ep/octep_vdpa_main.c

index 2cadb878e679f539abb1ad9d29c931d1076a90a4..53b020b019f7356858aa681fff456550b30e53ee 100644 (file)
@@ -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);
index d5a599f87e18fa55f99bbdf6e32f33d056294970..74240101c5052ef99e1ebd6c4dc5b299b94cb57b 100644 (file)
@@ -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;
index 4d56be64ae56205d104831a86c716febed84faab..f3d4dda4e04cdeec178fc0e7f704bec580b0af03 100644 (file)
@@ -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)