1 /* SPDX-License-Identifier: BSD-3-Clause */
9 #define __packed __attribute__((__packed__))
10 #define unlikely(x) __builtin_expect(!!(x), 0)
12 #define ICMSGHDRFLAG_TRANSACTION 1
13 #define ICMSGHDRFLAG_REQUEST 2
14 #define ICMSGHDRFLAG_RESPONSE 4
16 #define IC_VERSION_NEGOTIATION_MAX_VER_COUNT 100
17 #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)))
26 /* Channel packet flags */
27 #define VMBUS_CHANPKT_TYPE_INBAND 0x0006
28 #define VMBUS_CHANPKT_TYPE_RXBUF 0x0007
29 #define VMBUS_CHANPKT_TYPE_GPA 0x0009
30 #define VMBUS_CHANPKT_TYPE_COMP 0x000b
32 #define VMBUS_CHANPKT_FLAG_NONE 0
33 #define VMBUS_CHANPKT_FLAG_RC 0x0001 /* report completion */
35 #define VMBUS_CHANPKT_SIZE_SHIFT 3
36 #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)
43 struct vmbus_bufring
{
44 volatile uint32_t windex
;
45 volatile uint32_t rindex
;
48 * Interrupt mask {0,1}
50 * For TX bufring, host set this to 1, when it is processing
51 * the TX bufring, so that we can safely skip the TX event
52 * notification to host.
54 * For RX bufring, once this is set to 1 by us, host will not
55 * further dispatch interrupts to us, even if there are data
56 * pending on the RX bufring. This effectively disables the
57 * interrupt of the channel to which this RX bufring is attached.
59 volatile uint32_t imask
;
62 * Win8 uses some of the reserved bits to implement
63 * interrupt driven flow management. On the send side
64 * we can request that the receiver interrupt the sender
65 * when the ring transitions from being full to being able
66 * to handle a message of size "pending_send_sz".
68 * Add necessary state for this enhancement.
70 volatile uint32_t pending_send
;
71 uint32_t reserved1
[12];
75 uint32_t feat_pending_send_sz
:1;
80 /* Pad it to rte_mem_page_size() so that data starts on page boundary */
81 uint8_t reserved2
[4028];
84 * Ring data starts here + RingDataStartOffset
85 * !!! DO NOT place any fields below this !!!
91 struct vmbus_bufring
*vbr
;
93 uint32_t windex
; /* next available location */
96 struct 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_ */
104 struct vmbus_chanpkt
{
105 struct vmbus_chanpkt_hdr hdr
;
108 struct vmbuspipe_hdr
{
110 unsigned int msgsize
;
114 unsigned short major
;
115 unsigned short minor
;
118 struct 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 */
126 struct ic_version icverframe
;
127 unsigned short icmsgtype
;
128 struct ic_version icvermsg
;
129 unsigned short icmsgsize
;
131 unsigned char ictransaction_id
;
132 unsigned char icflags
;
133 unsigned char reserved
[2];
136 int rte_vmbus_chan_recv_raw(struct vmbus_br
*rxbr
, void *data
, uint32_t *len
);
137 int rte_vmbus_chan_send(struct vmbus_br
*txbr
, uint16_t type
, void *data
,
138 uint32_t dlen
, uint32_t flags
);
139 void vmbus_br_setup(struct vmbus_br
*br
, void *buf
, unsigned int blen
);
140 void *vmbus_uio_map(int *fd
, int size
);
142 /* Amount of space available for write */
143 static inline uint32_t vmbus_br_availwrite(const struct vmbus_br
*br
, uint32_t windex
)
145 uint32_t rindex
= br
->vbr
->rindex
;
147 if (windex
>= rindex
)
148 return br
->dsize
- (windex
- rindex
);
150 return rindex
- windex
;
153 static inline uint32_t vmbus_br_availread(const struct vmbus_br
*br
)
155 return br
->dsize
- vmbus_br_availwrite(br
, br
->vbr
->windex
);
158 #endif /* !_VMBUS_BUF_H_ */