Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/hv/vmbus_bufring.h
26278 views
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 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
*/
43
struct 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
90
struct vmbus_br {
91
struct vmbus_bufring *vbr;
92
uint32_t dsize;
93
uint32_t windex; /* next available location */
94
};
95
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_ */
101
uint64_t xactid;
102
} __packed;
103
104
struct vmbus_chanpkt {
105
struct vmbus_chanpkt_hdr hdr;
106
} __packed;
107
108
struct vmbuspipe_hdr {
109
unsigned int flags;
110
unsigned int msgsize;
111
} __packed;
112
113
struct ic_version {
114
unsigned short major;
115
unsigned short minor;
116
} __packed;
117
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 */
123
} __packed;
124
125
struct 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
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);
141
142
/* Amount of space available for write */
143
static 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
153
static 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
160