qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

pvrdma.h (3343B)


      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