Merge tag 'ak-pull-request' of https://gitlab.com/berrange/qemu into staging
[qemu.git] / hw / rdma / vmw / pvrdma.h
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
59 typedef 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
73 typedef 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
81 struct 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 };
102 typedef struct PVRDMADev PVRDMADev;
103 DECLARE_INSTANCE_CHECKER(PVRDMADev, PVRDMA_DEV,
104 PVRDMA_HW_NAME)
105
106 static 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
119 static 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
132 static 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
142 int pvrdma_exec_cmd(PVRDMADev *dev);
143
144 #endif