1/* SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 * Google virtual Ethernet (gve) driver
3 *
4 * Copyright (C) 2015-2019 Google, Inc.
5 */
6
7#ifndef _GVE_ADMINQ_H
8#define _GVE_ADMINQ_H
9
10#include <linux/build_bug.h>
11
12/* Admin queue opcodes */
13enum gve_adminq_opcodes {
14	GVE_ADMINQ_DESCRIBE_DEVICE		= 0x1,
15	GVE_ADMINQ_CONFIGURE_DEVICE_RESOURCES	= 0x2,
16	GVE_ADMINQ_REGISTER_PAGE_LIST		= 0x3,
17	GVE_ADMINQ_UNREGISTER_PAGE_LIST		= 0x4,
18	GVE_ADMINQ_CREATE_TX_QUEUE		= 0x5,
19	GVE_ADMINQ_CREATE_RX_QUEUE		= 0x6,
20	GVE_ADMINQ_DESTROY_TX_QUEUE		= 0x7,
21	GVE_ADMINQ_DESTROY_RX_QUEUE		= 0x8,
22	GVE_ADMINQ_DECONFIGURE_DEVICE_RESOURCES	= 0x9,
23	GVE_ADMINQ_SET_DRIVER_PARAMETER		= 0xB,
24	GVE_ADMINQ_REPORT_STATS			= 0xC,
25	GVE_ADMINQ_REPORT_LINK_SPEED	= 0xD
26};
27
28/* Admin queue status codes */
29enum gve_adminq_statuses {
30	GVE_ADMINQ_COMMAND_UNSET			= 0x0,
31	GVE_ADMINQ_COMMAND_PASSED			= 0x1,
32	GVE_ADMINQ_COMMAND_ERROR_ABORTED		= 0xFFFFFFF0,
33	GVE_ADMINQ_COMMAND_ERROR_ALREADY_EXISTS		= 0xFFFFFFF1,
34	GVE_ADMINQ_COMMAND_ERROR_CANCELLED		= 0xFFFFFFF2,
35	GVE_ADMINQ_COMMAND_ERROR_DATALOSS		= 0xFFFFFFF3,
36	GVE_ADMINQ_COMMAND_ERROR_DEADLINE_EXCEEDED	= 0xFFFFFFF4,
37	GVE_ADMINQ_COMMAND_ERROR_FAILED_PRECONDITION	= 0xFFFFFFF5,
38	GVE_ADMINQ_COMMAND_ERROR_INTERNAL_ERROR		= 0xFFFFFFF6,
39	GVE_ADMINQ_COMMAND_ERROR_INVALID_ARGUMENT	= 0xFFFFFFF7,
40	GVE_ADMINQ_COMMAND_ERROR_NOT_FOUND		= 0xFFFFFFF8,
41	GVE_ADMINQ_COMMAND_ERROR_OUT_OF_RANGE		= 0xFFFFFFF9,
42	GVE_ADMINQ_COMMAND_ERROR_PERMISSION_DENIED	= 0xFFFFFFFA,
43	GVE_ADMINQ_COMMAND_ERROR_UNAUTHENTICATED	= 0xFFFFFFFB,
44	GVE_ADMINQ_COMMAND_ERROR_RESOURCE_EXHAUSTED	= 0xFFFFFFFC,
45	GVE_ADMINQ_COMMAND_ERROR_UNAVAILABLE		= 0xFFFFFFFD,
46	GVE_ADMINQ_COMMAND_ERROR_UNIMPLEMENTED		= 0xFFFFFFFE,
47	GVE_ADMINQ_COMMAND_ERROR_UNKNOWN_ERROR		= 0xFFFFFFFF,
48};
49
50#define GVE_ADMINQ_DEVICE_DESCRIPTOR_VERSION 1
51
52/* All AdminQ command structs should be naturally packed. The static_assert
53 * calls make sure this is the case at compile time.
54 */
55
56struct gve_adminq_describe_device {
57	__be64 device_descriptor_addr;
58	__be32 device_descriptor_version;
59	__be32 available_length;
60};
61
62static_assert(sizeof(struct gve_adminq_describe_device) == 16);
63
64struct gve_device_descriptor {
65	__be64 max_registered_pages;
66	__be16 reserved1;
67	__be16 tx_queue_entries;
68	__be16 rx_queue_entries;
69	__be16 default_num_queues;
70	__be16 mtu;
71	__be16 counters;
72	__be16 tx_pages_per_qpl;
73	__be16 rx_pages_per_qpl;
74	u8  mac[ETH_ALEN];
75	__be16 num_device_options;
76	__be16 total_length;
77	u8  reserved2[6];
78};
79
80static_assert(sizeof(struct gve_device_descriptor) == 40);
81
82struct device_option {
83	__be32 option_id;
84	__be32 option_length;
85};
86
87static_assert(sizeof(struct device_option) == 8);
88
89struct gve_adminq_configure_device_resources {
90	__be64 counter_array;
91	__be64 irq_db_addr;
92	__be32 num_counters;
93	__be32 num_irq_dbs;
94	__be32 irq_db_stride;
95	__be32 ntfy_blk_msix_base_idx;
96};
97
98static_assert(sizeof(struct gve_adminq_configure_device_resources) == 32);
99
100struct gve_adminq_register_page_list {
101	__be32 page_list_id;
102	__be32 num_pages;
103	__be64 page_address_list_addr;
104};
105
106static_assert(sizeof(struct gve_adminq_register_page_list) == 16);
107
108struct gve_adminq_unregister_page_list {
109	__be32 page_list_id;
110};
111
112static_assert(sizeof(struct gve_adminq_unregister_page_list) == 4);
113
114struct gve_adminq_create_tx_queue {
115	__be32 queue_id;
116	__be32 reserved;
117	__be64 queue_resources_addr;
118	__be64 tx_ring_addr;
119	__be32 queue_page_list_id;
120	__be32 ntfy_id;
121};
122
123static_assert(sizeof(struct gve_adminq_create_tx_queue) == 32);
124
125struct gve_adminq_create_rx_queue {
126	__be32 queue_id;
127	__be32 index;
128	__be32 reserved;
129	__be32 ntfy_id;
130	__be64 queue_resources_addr;
131	__be64 rx_desc_ring_addr;
132	__be64 rx_data_ring_addr;
133	__be32 queue_page_list_id;
134	u8 padding[4];
135};
136
137static_assert(sizeof(struct gve_adminq_create_rx_queue) == 48);
138
139/* Queue resources that are shared with the device */
140struct gve_queue_resources {
141	union {
142		struct {
143			__be32 db_index;	/* Device -> Guest */
144			__be32 counter_index;	/* Device -> Guest */
145		};
146		u8 reserved[64];
147	};
148};
149
150static_assert(sizeof(struct gve_queue_resources) == 64);
151
152struct gve_adminq_destroy_tx_queue {
153	__be32 queue_id;
154};
155
156static_assert(sizeof(struct gve_adminq_destroy_tx_queue) == 4);
157
158struct gve_adminq_destroy_rx_queue {
159	__be32 queue_id;
160};
161
162static_assert(sizeof(struct gve_adminq_destroy_rx_queue) == 4);
163
164/* GVE Set Driver Parameter Types */
165enum gve_set_driver_param_types {
166	GVE_SET_PARAM_MTU	= 0x1,
167};
168
169struct gve_adminq_set_driver_parameter {
170	__be32 parameter_type;
171	u8 reserved[4];
172	__be64 parameter_value;
173};
174
175static_assert(sizeof(struct gve_adminq_set_driver_parameter) == 16);
176
177struct gve_adminq_report_stats {
178	__be64 stats_report_len;
179	__be64 stats_report_addr;
180	__be64 interval;
181};
182
183static_assert(sizeof(struct gve_adminq_report_stats) == 24);
184
185struct gve_adminq_report_link_speed {
186	__be64 link_speed_address;
187};
188
189static_assert(sizeof(struct gve_adminq_report_link_speed) == 8);
190
191struct stats {
192	__be32 stat_name;
193	__be32 queue_id;
194	__be64 value;
195};
196
197static_assert(sizeof(struct stats) == 16);
198
199struct gve_stats_report {
200	__be64 written_count;
201	struct stats stats[];
202};
203
204static_assert(sizeof(struct gve_stats_report) == 8);
205
206enum gve_stat_names {
207	// stats from gve
208	TX_WAKE_CNT			= 1,
209	TX_STOP_CNT			= 2,
210	TX_FRAMES_SENT			= 3,
211	TX_BYTES_SENT			= 4,
212	TX_LAST_COMPLETION_PROCESSED	= 5,
213	RX_NEXT_EXPECTED_SEQUENCE	= 6,
214	RX_BUFFERS_POSTED		= 7,
215	TX_TIMEOUT_CNT			= 8,
216	// stats from NIC
217	RX_QUEUE_DROP_CNT		= 65,
218	RX_NO_BUFFERS_POSTED		= 66,
219	RX_DROPS_PACKET_OVER_MRU	= 67,
220	RX_DROPS_INVALID_CHECKSUM	= 68,
221};
222
223union gve_adminq_command {
224	struct {
225		__be32 opcode;
226		__be32 status;
227		union {
228			struct gve_adminq_configure_device_resources
229						configure_device_resources;
230			struct gve_adminq_create_tx_queue create_tx_queue;
231			struct gve_adminq_create_rx_queue create_rx_queue;
232			struct gve_adminq_destroy_tx_queue destroy_tx_queue;
233			struct gve_adminq_destroy_rx_queue destroy_rx_queue;
234			struct gve_adminq_describe_device describe_device;
235			struct gve_adminq_register_page_list reg_page_list;
236			struct gve_adminq_unregister_page_list unreg_page_list;
237			struct gve_adminq_set_driver_parameter set_driver_param;
238			struct gve_adminq_report_stats report_stats;
239			struct gve_adminq_report_link_speed report_link_speed;
240		};
241	};
242	u8 reserved[64];
243};
244
245static_assert(sizeof(union gve_adminq_command) == 64);
246
247int gve_adminq_alloc(struct device *dev, struct gve_priv *priv);
248void gve_adminq_free(struct device *dev, struct gve_priv *priv);
249void gve_adminq_release(struct gve_priv *priv);
250int gve_adminq_describe_device(struct gve_priv *priv);
251int gve_adminq_configure_device_resources(struct gve_priv *priv,
252					  dma_addr_t counter_array_bus_addr,
253					  u32 num_counters,
254					  dma_addr_t db_array_bus_addr,
255					  u32 num_ntfy_blks);
256int gve_adminq_deconfigure_device_resources(struct gve_priv *priv);
257int gve_adminq_create_tx_queues(struct gve_priv *priv, u32 num_queues);
258int gve_adminq_destroy_tx_queues(struct gve_priv *priv, u32 queue_id);
259int gve_adminq_create_rx_queues(struct gve_priv *priv, u32 num_queues);
260int gve_adminq_destroy_rx_queues(struct gve_priv *priv, u32 queue_id);
261int gve_adminq_register_page_list(struct gve_priv *priv,
262				  struct gve_queue_page_list *qpl);
263int gve_adminq_unregister_page_list(struct gve_priv *priv, u32 page_list_id);
264int gve_adminq_set_mtu(struct gve_priv *priv, u64 mtu);
265int gve_adminq_report_stats(struct gve_priv *priv, u64 stats_report_len,
266			    dma_addr_t stats_report_addr, u64 interval);
267int gve_adminq_report_link_speed(struct gve_priv *priv);
268#endif /* _GVE_ADMINQ_H */
269