aboutsummaryrefslogtreecommitdiff
path: root/hw/rdma/vmw/pvrdma.h
blob: e3742d893a44ca9172f0f86abfe77ff6e6c7182e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
 * QEMU VMWARE paravirtual RDMA device definitions
 *
 * Copyright (C) 2018 Oracle
 * Copyright (C) 2018 Red Hat Inc
 *
 * Authors:
 *     Yuval Shaia <yuval.shaia@oracle.com>
 *     Marcel Apfelbaum <marcel@redhat.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 */

#ifndef PVRDMA_PVRDMA_H
#define PVRDMA_PVRDMA_H

#include "qemu/units.h"
#include "hw/pci/pci.h"
#include "hw/pci/msix.h"
#include "chardev/char-fe.h"

#include "../rdma_backend_defs.h"
#include "../rdma_rm_defs.h"

#include "standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h"
#include "standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h"
#include "pvrdma_dev_ring.h"

/* BARs */
#define RDMA_MSIX_BAR_IDX    0
#define RDMA_REG_BAR_IDX     1
#define RDMA_UAR_BAR_IDX     2
#define RDMA_BAR0_MSIX_SIZE  (16 * KiB)
#define RDMA_BAR1_REGS_SIZE  64
#define RDMA_BAR2_UAR_SIZE   (0x1000 * MAX_UCS) /* each uc gets page */

/* MSIX */
#define RDMA_MAX_INTRS       3
#define RDMA_MSIX_TABLE      0x0000
#define RDMA_MSIX_PBA        0x2000

/* Interrupts Vectors */
#define INTR_VEC_CMD_RING            0
#define INTR_VEC_CMD_ASYNC_EVENTS    1
#define INTR_VEC_CMD_COMPLETION_Q    2

/* HW attributes */
#define PVRDMA_HW_NAME       "pvrdma"
#define PVRDMA_HW_VERSION    17
#define PVRDMA_FW_VERSION    14

/* Some defaults */
#define PVRDMA_PKEY          0x7FFF

typedef struct DSRInfo {
    dma_addr_t dma;
    struct pvrdma_device_shared_region *dsr;

    union pvrdma_cmd_req *req;
    union pvrdma_cmd_resp *rsp;

    struct pvrdma_ring *async_ring_state;
    PvrdmaRing async;

    struct pvrdma_ring *cq_ring_state;
    PvrdmaRing cq;
} DSRInfo;

typedef struct PVRDMADev {
    PCIDevice parent_obj;
    MemoryRegion msix;
    MemoryRegion regs;
    uint32_t regs_data[RDMA_BAR1_REGS_SIZE];
    MemoryRegion uar;
    uint32_t uar_data[RDMA_BAR2_UAR_SIZE];
    DSRInfo dsr_info;
    int interrupt_mask;
    struct ibv_device_attr dev_attr;
    uint64_t node_guid;
    char *backend_device_name;
    uint8_t backend_gid_idx;
    uint8_t backend_port_num;
    RdmaBackendDev backend_dev;
    RdmaDeviceResources rdma_dev_res;
    CharBackend mad_chr;
} PVRDMADev;
#define PVRDMA_DEV(dev) OBJECT_CHECK(PVRDMADev, (dev), PVRDMA_HW_NAME)

static inline int get_reg_val(PVRDMADev *dev, hwaddr addr, uint32_t *val)
{
    int idx = addr >> 2;

    if (idx >= RDMA_BAR1_REGS_SIZE) {
        return -EINVAL;
    }

    *val = dev->regs_data[idx];

    return 0;
}

static inline int set_reg_val(PVRDMADev *dev, hwaddr addr, uint32_t val)
{
    int idx = addr >> 2;

    if (idx >= RDMA_BAR1_REGS_SIZE) {
        return -EINVAL;
    }

    dev->regs_data[idx] = val;

    return 0;
}

static inline void post_interrupt(PVRDMADev *dev, unsigned vector)
{
    PCIDevice *pci_dev = PCI_DEVICE(dev);

    if (likely(!dev->interrupt_mask)) {
        msix_notify(pci_dev, vector);
    }
}

int execute_command(PVRDMADev *dev);

#endif