2018-02-09 16:39:19 +03:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
|
2018-06-25 15:42:31 +03:00
|
|
|
#include "qemu/units.h"
|
2018-12-21 17:40:34 +03:00
|
|
|
#include "qemu/notify.h"
|
2018-03-21 18:22:07 +03:00
|
|
|
#include "hw/pci/pci.h"
|
|
|
|
#include "hw/pci/msix.h"
|
2018-12-21 17:40:19 +03:00
|
|
|
#include "chardev/char-fe.h"
|
2018-12-21 17:40:27 +03:00
|
|
|
#include "hw/net/vmxnet3_defs.h"
|
2018-02-09 16:39:19 +03:00
|
|
|
|
|
|
|
#include "../rdma_backend_defs.h"
|
|
|
|
#include "../rdma_rm_defs.h"
|
|
|
|
|
2018-03-21 18:22:07 +03:00
|
|
|
#include "standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h"
|
|
|
|
#include "standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h"
|
2018-02-09 16:39:19 +03:00
|
|
|
#include "pvrdma_dev_ring.h"
|
2020-09-03 23:43:22 +03:00
|
|
|
#include "qom/object.h"
|
2018-02-09 16:39:19 +03:00
|
|
|
|
|
|
|
/* BARs */
|
|
|
|
#define RDMA_MSIX_BAR_IDX 0
|
|
|
|
#define RDMA_REG_BAR_IDX 1
|
|
|
|
#define RDMA_UAR_BAR_IDX 2
|
2018-06-25 15:42:31 +03:00
|
|
|
#define RDMA_BAR0_MSIX_SIZE (16 * KiB)
|
2018-04-30 23:02:21 +03:00
|
|
|
#define RDMA_BAR1_REGS_SIZE 64
|
2018-02-09 16:39:19 +03:00
|
|
|
#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
|
|
|
|
|
2018-08-05 18:35:10 +03:00
|
|
|
/* Some defaults */
|
2018-12-21 17:40:21 +03:00
|
|
|
#define PVRDMA_PKEY 0xFFFF
|
2018-08-05 18:35:10 +03:00
|
|
|
|
2018-02-09 16:39:19 +03:00
|
|
|
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;
|
|
|
|
|
2019-03-11 13:29:08 +03:00
|
|
|
typedef struct PVRDMADevStats {
|
|
|
|
uint64_t commands;
|
|
|
|
uint64_t regs_reads;
|
|
|
|
uint64_t regs_writes;
|
|
|
|
uint64_t uar_writes;
|
|
|
|
uint64_t interrupts;
|
|
|
|
} PVRDMADevStats;
|
|
|
|
|
2020-09-03 23:43:22 +03:00
|
|
|
struct PVRDMADev {
|
2018-02-09 16:39:19 +03:00
|
|
|
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;
|
2018-12-21 17:40:25 +03:00
|
|
|
char *backend_eth_device_name;
|
2018-02-09 16:39:19 +03:00
|
|
|
char *backend_device_name;
|
|
|
|
uint8_t backend_port_num;
|
|
|
|
RdmaBackendDev backend_dev;
|
|
|
|
RdmaDeviceResources rdma_dev_res;
|
2018-12-21 17:40:19 +03:00
|
|
|
CharBackend mad_chr;
|
2018-12-21 17:40:27 +03:00
|
|
|
VMXNET3State *func0;
|
2018-12-21 17:40:34 +03:00
|
|
|
Notifier shutdown_notifier;
|
2019-03-11 13:29:08 +03:00
|
|
|
PVRDMADevStats stats;
|
2020-09-03 23:43:22 +03:00
|
|
|
};
|
|
|
|
typedef struct PVRDMADev PVRDMADev;
|
2020-09-01 00:07:33 +03:00
|
|
|
DECLARE_INSTANCE_CHECKER(PVRDMADev, PVRDMA_DEV,
|
|
|
|
PVRDMA_HW_NAME)
|
2018-02-09 16:39:19 +03:00
|
|
|
|
|
|
|
static inline int get_reg_val(PVRDMADev *dev, hwaddr addr, uint32_t *val)
|
|
|
|
{
|
|
|
|
int idx = addr >> 2;
|
|
|
|
|
2018-04-30 23:02:21 +03:00
|
|
|
if (idx >= RDMA_BAR1_REGS_SIZE) {
|
2018-02-09 16:39:19 +03:00
|
|
|
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;
|
|
|
|
|
2018-04-30 23:02:21 +03:00
|
|
|
if (idx >= RDMA_BAR1_REGS_SIZE) {
|
2018-02-09 16:39:19 +03:00
|
|
|
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)) {
|
2019-03-11 13:29:08 +03:00
|
|
|
dev->stats.interrupts++;
|
2018-02-09 16:39:19 +03:00
|
|
|
msix_notify(pci_dev, vector);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-11 13:29:05 +03:00
|
|
|
int pvrdma_exec_cmd(PVRDMADev *dev);
|
2018-02-09 16:39:19 +03:00
|
|
|
|
|
|
|
#endif
|