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 "qemu/notify.h"
  21#include "hw/pci/pci.h"
  22#include "hw/pci/msix.h"
  23#include "chardev/char-fe.h"
  24#include "hw/net/vmxnet3_defs.h"
  25
  26#include "../rdma_backend_defs.h"
  27#include "../rdma_rm_defs.h"
  28
  29#include "standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h"
  30#include "pvrdma_dev_ring.h"
  31#include "qom/object.h"
  32
  33/* BARs */
  34#define RDMA_MSIX_BAR_IDX    0
  35#define RDMA_REG_BAR_IDX     1
  36#define RDMA_UAR_BAR_IDX     2
  37#define RDMA_BAR0_MSIX_SIZE  (16 * KiB)
  38#define RDMA_BAR1_REGS_SIZE  64
  39#define RDMA_BAR2_UAR_SIZE   (0x1000 * MAX_UCS) /* each uc gets page */
  40
  41/* MSIX */
  42#define RDMA_MAX_INTRS       3
  43#define RDMA_MSIX_TABLE      0x0000
  44#define RDMA_MSIX_PBA        0x2000
  45
  46/* Interrupts Vectors */
  47#define INTR_VEC_CMD_RING            0
  48#define INTR_VEC_CMD_ASYNC_EVENTS    1
  49#define INTR_VEC_CMD_COMPLETION_Q    2
  50
  51/* HW attributes */
  52#define PVRDMA_HW_NAME       "pvrdma"
  53#define PVRDMA_HW_VERSION    17
  54#define PVRDMA_FW_VERSION    14
  55
  56/* Some defaults */
  57#define PVRDMA_PKEY          0xFFFF
  58
  59typedef struct DSRInfo {
  60    dma_addr_t dma;
  61    struct pvrdma_device_shared_region *dsr;
  62
  63    union pvrdma_cmd_req *req;
  64    union pvrdma_cmd_resp *rsp;
  65
  66    PvrdmaRingState *async_ring_state;
  67    PvrdmaRing async;
  68
  69    PvrdmaRingState *cq_ring_state;
  70    PvrdmaRing cq;
  71} DSRInfo;
  72
  73typedef struct PVRDMADevStats {
  74    uint64_t commands;
  75    uint64_t regs_reads;
  76    uint64_t regs_writes;
  77    uint64_t uar_writes;
  78    uint64_t interrupts;
  79} PVRDMADevStats;
  80
  81struct PVRDMADev {
  82    PCIDevice parent_obj;
  83    MemoryRegion msix;
  84    MemoryRegion regs;
  85    uint32_t regs_data[RDMA_BAR1_REGS_SIZE];
  86    MemoryRegion uar;
  87    uint32_t uar_data[RDMA_BAR2_UAR_SIZE];
  88    DSRInfo dsr_info;
  89    int interrupt_mask;
  90    struct ibv_device_attr dev_attr;
  91    uint64_t node_guid;
  92    char *backend_eth_device_name;
  93    char *backend_device_name;
  94    uint8_t backend_port_num;
  95    RdmaBackendDev backend_dev;
  96    RdmaDeviceResources rdma_dev_res;
  97    CharBackend mad_chr;
  98    VMXNET3State *func0;
  99    Notifier shutdown_notifier;
 100    PVRDMADevStats stats;
 101};
 102typedef struct PVRDMADev PVRDMADev;
 103DECLARE_INSTANCE_CHECKER(PVRDMADev, PVRDMA_DEV,
 104                         PVRDMA_HW_NAME)
 105
 106static inline int get_reg_val(PVRDMADev *dev, hwaddr addr, uint32_t *val)
 107{
 108    int idx = addr >> 2;
 109
 110    if (idx >= RDMA_BAR1_REGS_SIZE) {
 111        return -EINVAL;
 112    }
 113
 114    *val = dev->regs_data[idx];
 115
 116    return 0;
 117}
 118
 119static inline int set_reg_val(PVRDMADev *dev, hwaddr addr, uint32_t val)
 120{
 121    int idx = addr >> 2;
 122
 123    if (idx >= RDMA_BAR1_REGS_SIZE) {
 124        return -EINVAL;
 125    }
 126
 127    dev->regs_data[idx] = val;
 128
 129    return 0;
 130}
 131
 132static inline void post_interrupt(PVRDMADev *dev, unsigned vector)
 133{
 134    PCIDevice *pci_dev = PCI_DEVICE(dev);
 135
 136    if (likely(!dev->interrupt_mask)) {
 137        dev->stats.interrupts++;
 138        msix_notify(pci_dev, vector);
 139    }
 140}
 141
 142int pvrdma_exec_cmd(PVRDMADev *dev);
 143
 144#endif
 145