xref: /openbmc/qemu/hw/rdma/vmw/pvrdma.h (revision 073d9f2c)
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 
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     struct pvrdma_ring *async_ring_state;
67     PvrdmaRing async;
68 
69     struct pvrdma_ring *cq_ring_state;
70     PvrdmaRing cq;
71 } DSRInfo;
72 
73 typedef struct PVRDMADev {
74     PCIDevice parent_obj;
75     MemoryRegion msix;
76     MemoryRegion regs;
77     uint32_t regs_data[RDMA_BAR1_REGS_SIZE];
78     MemoryRegion uar;
79     uint32_t uar_data[RDMA_BAR2_UAR_SIZE];
80     DSRInfo dsr_info;
81     int interrupt_mask;
82     struct ibv_device_attr dev_attr;
83     uint64_t node_guid;
84     char *backend_eth_device_name;
85     char *backend_device_name;
86     uint8_t backend_port_num;
87     RdmaBackendDev backend_dev;
88     RdmaDeviceResources rdma_dev_res;
89     CharBackend mad_chr;
90     VMXNET3State *func0;
91     Notifier shutdown_notifier;
92 } PVRDMADev;
93 #define PVRDMA_DEV(dev) OBJECT_CHECK(PVRDMADev, (dev), PVRDMA_HW_NAME)
94 
95 static inline int get_reg_val(PVRDMADev *dev, hwaddr addr, uint32_t *val)
96 {
97     int idx = addr >> 2;
98 
99     if (idx >= RDMA_BAR1_REGS_SIZE) {
100         return -EINVAL;
101     }
102 
103     *val = dev->regs_data[idx];
104 
105     return 0;
106 }
107 
108 static inline int set_reg_val(PVRDMADev *dev, hwaddr addr, uint32_t val)
109 {
110     int idx = addr >> 2;
111 
112     if (idx >= RDMA_BAR1_REGS_SIZE) {
113         return -EINVAL;
114     }
115 
116     dev->regs_data[idx] = val;
117 
118     return 0;
119 }
120 
121 static inline void post_interrupt(PVRDMADev *dev, unsigned vector)
122 {
123     PCIDevice *pci_dev = PCI_DEVICE(dev);
124 
125     if (likely(!dev->interrupt_mask)) {
126         msix_notify(pci_dev, vector);
127     }
128 }
129 
130 int execute_command(PVRDMADev *dev);
131 
132 #endif
133