159 lines · c
1/* SPDX-License-Identifier: BSD-3-Clause */2 3#ifndef _VMBUS_BUF_H_4#define _VMBUS_BUF_H_5 6#include <stdbool.h>7#include <stdint.h>8 9#define __packed __attribute__((__packed__))10#define unlikely(x) __builtin_expect(!!(x), 0)11 12#define ICMSGHDRFLAG_TRANSACTION 113#define ICMSGHDRFLAG_REQUEST 214#define ICMSGHDRFLAG_RESPONSE 415 16#define IC_VERSION_NEGOTIATION_MAX_VER_COUNT 10017#define ICMSG_HDR (sizeof(struct vmbuspipe_hdr) + sizeof(struct icmsg_hdr))18#define ICMSG_NEGOTIATE_PKT_SIZE(icframe_vercnt, icmsg_vercnt) \19 (ICMSG_HDR + sizeof(struct icmsg_negotiate) + \20 (((icframe_vercnt) + (icmsg_vercnt)) * sizeof(struct ic_version)))21 22/*23 * Channel packets24 */25 26/* Channel packet flags */27#define VMBUS_CHANPKT_TYPE_INBAND 0x000628#define VMBUS_CHANPKT_TYPE_RXBUF 0x000729#define VMBUS_CHANPKT_TYPE_GPA 0x000930#define VMBUS_CHANPKT_TYPE_COMP 0x000b31 32#define VMBUS_CHANPKT_FLAG_NONE 033#define VMBUS_CHANPKT_FLAG_RC 0x0001 /* report completion */34 35#define VMBUS_CHANPKT_SIZE_SHIFT 336#define VMBUS_CHANPKT_SIZE_ALIGN BIT(VMBUS_CHANPKT_SIZE_SHIFT)37#define VMBUS_CHANPKT_HLEN_MIN \38 (sizeof(struct vmbus_chanpkt_hdr) >> VMBUS_CHANPKT_SIZE_SHIFT)39 40/*41 * Buffer ring42 */43struct vmbus_bufring {44 volatile uint32_t windex;45 volatile uint32_t rindex;46 47 /*48 * Interrupt mask {0,1}49 *50 * For TX bufring, host set this to 1, when it is processing51 * the TX bufring, so that we can safely skip the TX event52 * notification to host.53 *54 * For RX bufring, once this is set to 1 by us, host will not55 * further dispatch interrupts to us, even if there are data56 * pending on the RX bufring. This effectively disables the57 * interrupt of the channel to which this RX bufring is attached.58 */59 volatile uint32_t imask;60 61 /*62 * Win8 uses some of the reserved bits to implement63 * interrupt driven flow management. On the send side64 * we can request that the receiver interrupt the sender65 * when the ring transitions from being full to being able66 * to handle a message of size "pending_send_sz".67 *68 * Add necessary state for this enhancement.69 */70 volatile uint32_t pending_send;71 uint32_t reserved1[12];72 73 union {74 struct {75 uint32_t feat_pending_send_sz:1;76 };77 uint32_t value;78 } feature_bits;79 80 /* Pad it to rte_mem_page_size() so that data starts on page boundary */81 uint8_t reserved2[4028];82 83 /*84 * Ring data starts here + RingDataStartOffset85 * !!! DO NOT place any fields below this !!!86 */87 uint8_t data[];88} __packed;89 90struct vmbus_br {91 struct vmbus_bufring *vbr;92 uint32_t dsize;93 uint32_t windex; /* next available location */94};95 96struct vmbus_chanpkt_hdr {97 uint16_t type; /* VMBUS_CHANPKT_TYPE_ */98 uint16_t hlen; /* header len, in 8 bytes */99 uint16_t tlen; /* total len, in 8 bytes */100 uint16_t flags; /* VMBUS_CHANPKT_FLAG_ */101 uint64_t xactid;102} __packed;103 104struct vmbus_chanpkt {105 struct vmbus_chanpkt_hdr hdr;106} __packed;107 108struct vmbuspipe_hdr {109 unsigned int flags;110 unsigned int msgsize;111} __packed;112 113struct ic_version {114 unsigned short major;115 unsigned short minor;116} __packed;117 118struct icmsg_negotiate {119 unsigned short icframe_vercnt;120 unsigned short icmsg_vercnt;121 unsigned int reserved;122 struct ic_version icversion_data[]; /* any size array */123} __packed;124 125struct icmsg_hdr {126 struct ic_version icverframe;127 unsigned short icmsgtype;128 struct ic_version icvermsg;129 unsigned short icmsgsize;130 unsigned int status;131 unsigned char ictransaction_id;132 unsigned char icflags;133 unsigned char reserved[2];134} __packed;135 136int rte_vmbus_chan_recv_raw(struct vmbus_br *rxbr, void *data, uint32_t *len);137int rte_vmbus_chan_send(struct vmbus_br *txbr, uint16_t type, void *data,138 uint32_t dlen, uint32_t flags);139void vmbus_br_setup(struct vmbus_br *br, void *buf, unsigned int blen);140void *vmbus_uio_map(int *fd, int size);141 142/* Amount of space available for write */143static inline uint32_t vmbus_br_availwrite(const struct vmbus_br *br, uint32_t windex)144{145 uint32_t rindex = br->vbr->rindex;146 147 if (windex >= rindex)148 return br->dsize - (windex - rindex);149 else150 return rindex - windex;151}152 153static inline uint32_t vmbus_br_availread(const struct vmbus_br *br)154{155 return br->dsize - vmbus_br_availwrite(br, br->vbr->windex);156}157 158#endif /* !_VMBUS_BUF_H_ */159