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 53typedef struct DSRInfo { 54 dma_addr_t dma; 55 struct pvrdma_device_shared_region *dsr; 56 57 union pvrdma_cmd_req *req; 58 union pvrdma_cmd_resp *rsp; 59 60 struct pvrdma_ring *async_ring_state; 61 PvrdmaRing async; 62 63 struct pvrdma_ring *cq_ring_state; 64 PvrdmaRing cq; 65} DSRInfo; 66 67typedef struct PVRDMADev { 68 PCIDevice parent_obj; 69 MemoryRegion msix; 70 MemoryRegion regs; 71 uint32_t regs_data[RDMA_BAR1_REGS_SIZE]; 72 MemoryRegion uar; 73 uint32_t uar_data[RDMA_BAR2_UAR_SIZE]; 74 DSRInfo dsr_info; 75 int interrupt_mask; 76 struct ibv_device_attr dev_attr; 77 uint64_t node_guid; 78 char *backend_device_name; 79 uint8_t backend_gid_idx; 80 uint8_t backend_port_num; 81 RdmaBackendDev backend_dev; 82 RdmaDeviceResources rdma_dev_res; 83} PVRDMADev; 84#define PVRDMA_DEV(dev) OBJECT_CHECK(PVRDMADev, (dev), PVRDMA_HW_NAME) 85 86static inline int get_reg_val(PVRDMADev *dev, hwaddr addr, uint32_t *val) 87{ 88 int idx = addr >> 2; 89 90 if (idx >= RDMA_BAR1_REGS_SIZE) { 91 return -EINVAL; 92 } 93 94 *val = dev->regs_data[idx]; 95 96 return 0; 97} 98 99static inline int set_reg_val(PVRDMADev *dev, hwaddr addr, uint32_t val) 100{ 101 int idx = addr >> 2; 102 103 if (idx >= RDMA_BAR1_REGS_SIZE) { 104 return -EINVAL; 105 } 106 107 dev->regs_data[idx] = val; 108 109 return 0; 110} 111 112static inline void post_interrupt(PVRDMADev *dev, unsigned vector) 113{ 114 PCIDevice *pci_dev = PCI_DEVICE(dev); 115 116 if (likely(!dev->interrupt_mask)) { 117 msix_notify(pci_dev, vector); 118 } 119} 120 121int execute_command(PVRDMADev *dev); 122 123#endif 124