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