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