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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
/* SPDX-License-Identifier: BSD-3-Clause */
#ifndef _VMBUS_BUF_H_
#define _VMBUS_BUF_H_
#include <stdbool.h>
#include <stdint.h>
#define __packed __attribute__((__packed__))
#define unlikely(x) __builtin_expect(!!(x), 0)
#define ICMSGHDRFLAG_TRANSACTION 1
#define ICMSGHDRFLAG_REQUEST 2
#define ICMSGHDRFLAG_RESPONSE 4
#define IC_VERSION_NEGOTIATION_MAX_VER_COUNT 100
#define ICMSG_HDR (sizeof(struct vmbuspipe_hdr) + sizeof(struct icmsg_hdr))
#define ICMSG_NEGOTIATE_PKT_SIZE(icframe_vercnt, icmsg_vercnt) \
(ICMSG_HDR + sizeof(struct icmsg_negotiate) + \
(((icframe_vercnt) + (icmsg_vercnt)) * sizeof(struct ic_version)))
/*
* Channel packets
*/
/* Channel packet flags */
#define VMBUS_CHANPKT_TYPE_INBAND 0x0006
#define VMBUS_CHANPKT_TYPE_RXBUF 0x0007
#define VMBUS_CHANPKT_TYPE_GPA 0x0009
#define VMBUS_CHANPKT_TYPE_COMP 0x000b
#define VMBUS_CHANPKT_FLAG_NONE 0
#define VMBUS_CHANPKT_FLAG_RC 0x0001 /* report completion */
#define VMBUS_CHANPKT_SIZE_SHIFT 3
#define VMBUS_CHANPKT_SIZE_ALIGN BIT(VMBUS_CHANPKT_SIZE_SHIFT)
#define VMBUS_CHANPKT_HLEN_MIN \
(sizeof(struct vmbus_chanpkt_hdr) >> VMBUS_CHANPKT_SIZE_SHIFT)
/*
* Buffer ring
*/
struct vmbus_bufring {
volatile uint32_t windex;
volatile uint32_t rindex;
/*
* Interrupt mask {0,1}
*
* For TX bufring, host set this to 1, when it is processing
* the TX bufring, so that we can safely skip the TX event
* notification to host.
*
* For RX bufring, once this is set to 1 by us, host will not
* further dispatch interrupts to us, even if there are data
* pending on the RX bufring. This effectively disables the
* interrupt of the channel to which this RX bufring is attached.
*/
volatile uint32_t imask;
/*
* Win8 uses some of the reserved bits to implement
* interrupt driven flow management. On the send side
* we can request that the receiver interrupt the sender
* when the ring transitions from being full to being able
* to handle a message of size "pending_send_sz".
*
* Add necessary state for this enhancement.
*/
volatile uint32_t pending_send;
uint32_t reserved1[12];
union {
struct {
uint32_t feat_pending_send_sz:1;
};
uint32_t value;
} feature_bits;
/* Pad it to rte_mem_page_size() so that data starts on page boundary */
uint8_t reserved2[4028];
/*
* Ring data starts here + RingDataStartOffset
* !!! DO NOT place any fields below this !!!
*/
uint8_t data[];
} __packed;
struct vmbus_br {
struct vmbus_bufring *vbr;
uint32_t dsize;
uint32_t windex; /* next available location */
};
struct vmbus_chanpkt_hdr {
uint16_t type; /* VMBUS_CHANPKT_TYPE_ */
uint16_t hlen; /* header len, in 8 bytes */
uint16_t tlen; /* total len, in 8 bytes */
uint16_t flags; /* VMBUS_CHANPKT_FLAG_ */
uint64_t xactid;
} __packed;
struct vmbus_chanpkt {
struct vmbus_chanpkt_hdr hdr;
} __packed;
struct vmbuspipe_hdr {
unsigned int flags;
unsigned int msgsize;
} __packed;
struct ic_version {
unsigned short major;
unsigned short minor;
} __packed;
struct icmsg_negotiate {
unsigned short icframe_vercnt;
unsigned short icmsg_vercnt;
unsigned int reserved;
struct ic_version icversion_data[]; /* any size array */
} __packed;
struct icmsg_hdr {
struct ic_version icverframe;
unsigned short icmsgtype;
struct ic_version icvermsg;
unsigned short icmsgsize;
unsigned int status;
unsigned char ictransaction_id;
unsigned char icflags;
unsigned char reserved[2];
} __packed;
int rte_vmbus_chan_recv_raw(struct vmbus_br *rxbr, void *data, uint32_t *len);
int rte_vmbus_chan_send(struct vmbus_br *txbr, uint16_t type, void *data,
uint32_t dlen, uint32_t flags);
void vmbus_br_setup(struct vmbus_br *br, void *buf, unsigned int blen);
void *vmbus_uio_map(int *fd, int size);
/* Amount of space available for write */
static inline uint32_t vmbus_br_availwrite(const struct vmbus_br *br, uint32_t windex)
{
uint32_t rindex = br->vbr->rindex;
if (windex >= rindex)
return br->dsize - (windex - rindex);
else
return rindex - windex;
}
static inline uint32_t vmbus_br_availread(const struct vmbus_br *br)
{
return br->dsize - vmbus_br_availwrite(br, br->vbr->windex);
}
#endif /* !_VMBUS_BUF_H_ */
|