blob: 6e7caacfff57449d3ec37c7db33661e3b0e2008f [file] [log] [blame]
Saurabh Sengar45bab4d2024-03-30 01:52:00 -07001/* 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 1
13#define ICMSGHDRFLAG_REQUEST 2
14#define ICMSGHDRFLAG_RESPONSE 4
15
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)))
21
22/*
23 * Channel packets
24 */
25
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
31
32#define VMBUS_CHANPKT_FLAG_NONE 0
33#define VMBUS_CHANPKT_FLAG_RC 0x0001 /* report completion */
34
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)
39
40/*
41 * Buffer ring
42 */
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 processing
51 * the TX bufring, so that we can safely skip the TX event
52 * notification to host.
53 *
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.
58 */
59 volatile uint32_t imask;
60
61 /*
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".
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 + RingDataStartOffset
85 * !!! 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 else
150 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_ */