aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netvsc/hn_nvs.h
blob: 984a9c11c51d87cfa4ccf81381a004fe1e24689a (plain)
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
/* SPDX-License-Identifier: BSD-3-Clause
 * Copyright (c) 2018 Microsoft Corp.
 * All rights reserved.
 */

/*
 * The indirection table message is the largest message
 * received from host, and that is 112 bytes.
 */
#define NVS_RESPSIZE_MAX	256

/*
 * NDIS protocol version numbers
 */
#define NDIS_VERSION_6_1		0x00060001
#define NDIS_VERSION_6_20		0x00060014
#define NDIS_VERSION_6_30		0x0006001e
#define NDIS_VERSION_MAJOR(ver)	(((ver) & 0xffff0000) >> 16)
#define NDIS_VERSION_MINOR(ver)	((ver) & 0xffff)

/*
 * NVS versions.
 */
#define NVS_VERSION_1		0x00002
#define NVS_VERSION_2		0x30002
#define NVS_VERSION_4		0x40000
#define NVS_VERSION_5		0x50000
#define NVS_VERSION_6		0x60000
#define NVS_VERSION_61		0x60001

#define NVS_RXBUF_SIG		0xcafe
#define NVS_CHIM_SIG			0xface

#define NVS_CHIM_IDX_INVALID		0xffffffff

#define NVS_RNDIS_MTYPE_DATA		0
#define NVS_RNDIS_MTYPE_CTRL		1

/*
 * NVS message transacion status codes.
 */
#define NVS_STATUS_OK		1
#define NVS_STATUS_FAILED		2

/*
 * NVS request/response message types.
 */
#define NVS_TYPE_INIT		1
#define NVS_TYPE_INIT_RESP	2

#define NVS_TYPE_NDIS_INIT	100
#define NVS_TYPE_RXBUF_CONN	101
#define NVS_TYPE_RXBUF_CONNRESP	102
#define NVS_TYPE_RXBUF_DISCONN	103
#define NVS_TYPE_CHIM_CONN	104
#define NVS_TYPE_CHIM_CONNRESP	105
#define NVS_TYPE_CHIM_DISCONN	106
#define NVS_TYPE_RNDIS		107
#define NVS_TYPE_RNDIS_ACK	108

#define NVS_TYPE_NDIS_CONF	125
#define NVS_TYPE_VFASSOC_NOTE	128	/* notification */
#define NVS_TYPE_SET_DATAPATH	129
#define NVS_TYPE_SUBCH_REQ	133
#define NVS_TYPE_SUBCH_RESP	133	/* same as SUBCH_REQ */
#define NVS_TYPE_TXTBL_NOTE	134	/* notification */


/* NVS message common header */
struct hn_nvs_hdr {
	uint32_t	type;
} __rte_packed;

struct hn_nvs_init {
	uint32_t	type;	/* NVS_TYPE_INIT */
	uint32_t	ver_min;
	uint32_t	ver_max;
	uint8_t		rsvd[28];
} __rte_packed;

struct hn_nvs_init_resp {
	uint32_t	type;	/* NVS_TYPE_INIT_RESP */
	uint32_t	ver;	/* deprecated */
	uint32_t	rsvd;
	uint32_t	status;	/* NVS_STATUS_ */
} __rte_packed;

/* No response */
struct hn_nvs_ndis_conf {
	uint32_t	type;	/* NVS_TYPE_NDIS_CONF */
	uint32_t	mtu;
	uint32_t	rsvd;
	uint64_t	caps;	/* NVS_NDIS_CONF_ */
	uint8_t		rsvd1[20];
} __rte_packed;

#define NVS_NDIS_CONF_SRIOV		0x0004
#define NVS_NDIS_CONF_VLAN		0x0008

/* No response */
struct hn_nvs_ndis_init {
	uint32_t	type;	/* NVS_TYPE_NDIS_INIT */
	uint32_t	ndis_major;	/* NDIS_VERSION_MAJOR_ */
	uint32_t	ndis_minor;	/* NDIS_VERSION_MINOR_ */
	uint8_t		rsvd[28];
} __rte_packed;

#define NVS_DATAPATH_SYNTHETIC	0
#define NVS_DATAPATH_VF		1

/* No response */
struct hn_nvs_datapath {
	uint32_t	type;	/* NVS_TYPE_SET_DATAPATH */
	uint32_t	active_path;/* NVS_DATAPATH_* */
	uint8_t		rsvd[32];
} __rte_packed;

struct hn_nvs_rxbuf_conn {
	uint32_t	type;	/* NVS_TYPE_RXBUF_CONN */
	uint32_t	gpadl;	/* RXBUF vmbus GPADL */
	uint16_t	sig;	/* NVS_RXBUF_SIG */
	uint8_t		rsvd[30];
} __rte_packed;

struct hn_nvs_rxbuf_sect {
	uint32_t	start;
	uint32_t	slotsz;
	uint32_t	slotcnt;
	uint32_t	end;
} __rte_packed;

struct hn_nvs_rxbuf_connresp {
	uint32_t	type;	/* NVS_TYPE_RXBUF_CONNRESP */
	uint32_t	status;	/* NVS_STATUS_ */
	uint32_t	nsect;	/* # of elem in nvs_sect */
	struct hn_nvs_rxbuf_sect nvs_sect[1];
} __rte_packed;

/* No response */
struct hn_nvs_rxbuf_disconn {
	uint32_t	type;	/* NVS_TYPE_RXBUF_DISCONN */
	uint16_t	sig;	/* NVS_RXBUF_SIG */
	uint8_t		rsvd[34];
} __rte_packed;

struct hn_nvs_chim_conn {
	uint32_t	type;	/* NVS_TYPE_CHIM_CONN */
	uint32_t	gpadl;	/* chimney buf vmbus GPADL */
	uint16_t	sig;	/* NDIS_NVS_CHIM_SIG */
	uint8_t		rsvd[30];
} __rte_packed;

struct hn_nvs_chim_connresp {
	uint32_t	type;	/* NVS_TYPE_CHIM_CONNRESP */
	uint32_t	status;	/* NVS_STATUS_ */
	uint32_t	sectsz;	/* section size */
} __rte_packed;

/* No response */
struct hn_nvs_chim_disconn {
	uint32_t	type;	/* NVS_TYPE_CHIM_DISCONN */
	uint16_t	sig;	/* NVS_CHIM_SIG */
	uint8_t		rsvd[34];
} __rte_packed;

#define NVS_SUBCH_OP_ALLOC		1

struct hn_nvs_subch_req {
	uint32_t	type;	/* NVS_TYPE_SUBCH_REQ */
	uint32_t	op;	/* NVS_SUBCH_OP_ */
	uint32_t	nsubch;
	uint8_t		rsvd[28];
} __rte_packed;

struct hn_nvs_subch_resp {
	uint32_t	type;	/* NVS_TYPE_SUBCH_RESP */
	uint32_t	status;	/* NVS_STATUS_ */
	uint32_t	nsubch;
	uint8_t		rsvd[28];
} __rte_packed;

struct hn_nvs_rndis {
	uint32_t	type;	/* NVS_TYPE_RNDIS */
	uint32_t	rndis_mtype;/* NVS_RNDIS_MTYPE_ */
	/*
	 * Chimney sending buffer index and size.
	 *
	 * NOTE:
	 * If nvs_chim_idx is set to NVS_CHIM_IDX_INVALID
	 * and nvs_chim_sz is set to 0, then chimney sending
	 * buffer is _not_ used by this RNDIS message.
	 */
	uint32_t	chim_idx;
	uint32_t	chim_sz;
	uint8_t		rsvd[24];
} __rte_packed;

struct hn_nvs_rndis_ack {
	uint32_t	type;	/* NVS_TYPE_RNDIS_ACK */
	uint32_t	status;	/* NVS_STATUS_ */
	uint8_t		rsvd[32];
} __rte_packed;


int	hn_nvs_attach(struct hn_data *hv, unsigned int mtu);
void	hn_nvs_detach(struct hn_data *hv);
void	hn_nvs_ack_rxbuf(struct vmbus_channel *chan, uint64_t tid);
int	hn_nvs_alloc_subchans(struct hn_data *hv, uint32_t *nsubch);
void	hn_nvs_set_datapath(struct hn_data *hv, uint32_t path);

static inline int
hn_nvs_send(struct vmbus_channel *chan, uint16_t flags,
	    void *nvs_msg, int nvs_msglen, uintptr_t sndc,
	    bool *need_sig)
{
	return rte_vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_INBAND,
				   nvs_msg, nvs_msglen, (uint64_t)sndc,
				   flags, need_sig);
}

static inline int
hn_nvs_send_sglist(struct vmbus_channel *chan,
		   struct vmbus_gpa sg[], unsigned int sglen,
		   void *nvs_msg, int nvs_msglen,
		   uintptr_t sndc, bool *need_sig)
{
	return rte_vmbus_chan_send_sglist(chan, sg, sglen, nvs_msg, nvs_msglen,
					  (uint64_t)sndc, need_sig);
}