qemu/hw/rdma/vmw/pvrdma.h
<<
>>
Prefs
   1/*
   2 * QEMU VMWARE paravirtual RDMA device definitions
   3 *
   4 * Copyright (C) 2018 Oracle
   5 * Copyright (C) 2018 Red Hat Inc
   6 *
   7 * Authors:
   8 *     Yuval Shaia <yuval.shaia@oracle.com>
   9 *     Marcel Apfelbaum <marcel@redhat.com>
  10 *
  11 * This work is licensed under the terms of the GNU GPL, version 2 or later.
  12 * See the COPYING file in the top-level directory.
  13 *
  14 */
  15
  16#ifndef PVRDMA_PVRDMA_H
  17#define PVRDMA_PVRDMA_H
  18
  19#include "qemu/units.h"
  20#include "hw/pci/pci.h"
  21#include "hw/pci/msix.h"
  22
  23#include "../rdma_backend_defs.h"
  24#include "../rdma_rm_defs.h"
  25
  26#include "standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h"
  27#include "standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h"
  28#include "pvrdma_dev_ring.h"
  29
  30/* BARs */
  31#define RDMA_MSIX_BAR_IDX    0
  32#define RDMA_REG_BAR_IDX     1
  33#define RDMA_UAR_BAR_IDX     2
  34#define RDMA_BAR0_MSIX_SIZE  (16 * KiB)
  35#define RDMA_BAR1_REGS_SIZE  64
  36#define RDMA_BAR2_UAR_SIZE   (0x1000 * MAX_UCS) /* each uc gets page */
  37
  38/* MSIX */
  39#define RDMA_MAX_INTRS       3
  40#define RDMA_MSIX_TABLE      0x0000
  41#define RDMA_MSIX_PBA        0x2000
  42
  43/* Interrupts Vectors */
  44#define INTR_VEC_CMD_RING            0
  45#define INTR_VEC_CMD_ASYNC_EVENTS    1
  46#define INTR_VEC_CMD_COMPLETION_Q    2
  47
  48/* HW attributes */
  49#define PVRDMA_HW_NAME       "pvrdma"
  50#define PVRDMA_HW_VERSION    17
  51#define PVRDMA_FW_VERSION    14
  52
  53/* Some defaults */
  54#define PVRDMA_PKEY          0x7FFF
  55
  56typedef struct DSRInfo {
  57    dma_addr_t dma;
  58    struct pvrdma_device_shared_region *dsr;
  59
  60    union pvrdma_cmd_req *req;
  61    union pvrdma_cmd_resp *rsp;
  62
  63    struct pvrdma_ring *async_ring_state;
  64    PvrdmaRing async;
  65
  66    struct pvrdma_ring *cq_ring_state;
  67    PvrdmaRing cq;
  68} DSRInfo;
  69
  70typedef struct PVRDMADev {
  71    PCIDevice parent_obj;
  72    MemoryRegion msix;
  73    MemoryRegion regs;
  74    uint32_t regs_data[RDMA_BAR1_REGS_SIZE];
  75    MemoryRegion uar;
  76    uint32_t uar_data[RDMA_BAR2_UAR_SIZE];
  77    DSRInfo dsr_info;
  78    int interrupt_mask;
  79    struct ibv_device_attr dev_attr;
  80    uint64_t node_guid;
  81    char *backend_device_name;
  82    uint8_t backend_gid_idx;
  83    uint8_t backend_port_num;
  84    RdmaBackendDev backend_dev;
  85    RdmaDeviceResources rdma_dev_res;
  86} PVRDMADev;
  87#define PVRDMA_DEV(dev) OBJECT_CHECK(PVRDMADev, (dev), PVRDMA_HW_NAME)
  88
  89static inline int get_reg_val(PVRDMADev *dev, hwaddr addr, uint32_t *val)
  90{
  91    int idx = addr >> 2;
  92
  93    if (idx >= RDMA_BAR1_REGS_SIZE) {
  94        return -EINVAL;
  95    }
  96
  97    *val = dev->regs_data[idx];
  98
  99    return 0;
 100}
 101
 102static inline int set_reg_val(PVRDMADev *dev, hwaddr addr, uint32_t val)
 103{
 104    int idx = addr >> 2;
 105
 106    if (idx >= RDMA_BAR1_REGS_SIZE) {
 107        return -EINVAL;
 108    }
 109
 110    dev->regs_data[idx] = val;
 111
 112    return 0;
 113}
 114
 115static inline void post_interrupt(PVRDMADev *dev, unsigned vector)
 116{
 117    PCIDevice *pci_dev = PCI_DEVICE(dev);
 118
 119    if (likely(!dev->interrupt_mask)) {
 120        msix_notify(pci_dev, vector);
 121    }
 122}
 123
 124int execute_command(PVRDMADev *dev);
 125
 126#endif
 127