1 /*
2  * Copyright (C) 2018-2022 Intel Corporation.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 #ifndef _MEI_HBM_H_
8 #define _MEI_HBM_H_
9 #include <linux/uuid.h>
10 #include <linux/mei.h>
11 
12 #ifndef guid_t
13 #define guid_t uuid_le
14 #endif
15 
16 /*
17  * Timeouts in Seconds
18  */
19 #define MEI_HW_READY_TIMEOUT        2  /* Timeout on ready message */
20 #define MEI_CONNECT_TIMEOUT         3  /* HPS: at least 2 seconds */
21 
22 #define MEI_CL_CONNECT_TIMEOUT     15  /* HPS: Client Connect Timeout */
23 #define MEI_CLIENTS_INIT_TIMEOUT   15  /* HPS: Clients Enumeration Timeout */
24 
25 #define MEI_PGI_TIMEOUT             1  /* PG Isolation time response 1 sec */
26 #define MEI_D0I3_TIMEOUT            5  /* D0i3 set/unset max response time */
27 #define MEI_HBM_TIMEOUT             1  /* 1 second */
28 
29 /*
30  * MEI Version
31  */
32 #define MEI_HBM_MINOR_VERSION                   0
33 #define MEI_HBM_MAJOR_VERSION                   2
34 
35 /*
36  * MEI version with PGI support
37  */
38 #define MEI_HBM_MINOR_VERSION_PGI               1
39 #define MEI_HBM_MAJOR_VERSION_PGI               1
40 
41 /*
42  * MEI version with Dynamic clients support
43  */
44 #define MEI_HBM_MINOR_VERSION_DC               0
45 #define MEI_HBM_MAJOR_VERSION_DC               2
46 
47 /*
48  * MEI version with immediate reply to enum request support
49  */
50 #define MEI_HBM_MINOR_VERSION_IE               0
51 #define MEI_HBM_MAJOR_VERSION_IE               2
52 
53 /*
54  * MEI version with disconnect on connection timeout support
55  */
56 #define MEI_HBM_MINOR_VERSION_DOT              0
57 #define MEI_HBM_MAJOR_VERSION_DOT              2
58 
59 /*
60  * MEI version with notification support
61  */
62 #define MEI_HBM_MINOR_VERSION_EV               0
63 #define MEI_HBM_MAJOR_VERSION_EV               2
64 
65 /*
66  * MEI version with fixed address client support
67  */
68 #define MEI_HBM_MINOR_VERSION_FA               0
69 #define MEI_HBM_MAJOR_VERSION_FA               2
70 
71 /*
72  * MEI version with OS ver message support
73  */
74 #define MEI_HBM_MINOR_VERSION_OS              0
75 #define MEI_HBM_MAJOR_VERSION_OS              2
76 
77 /*
78  * MEI version with dma ring support
79  */
80 #define MEI_HBM_MINOR_VERSION_DR              1
81 #define HMEI_BM_MAJOR_VERSION_DR              2
82 
83 /* Host bus message command opcode */
84 #define MEI_HBM_CMD_OP_MSK                 0x7f
85 /* Host bus message command RESPONSE */
86 #define MEI_HBM_CMD_RES_MSK                0x80
87 
88 #define MEI_HBM_HOST_START                 0x01
89 #define MEI_HBM_HOST_START_RES             0x81
90 
91 #define MEI_HBM_HOST_STOP                  0x02
92 #define MEI_HBM_HOST_STO_RES               0x82
93 
94 #define MEI_HBM_ME_STOP                    0x03
95 
96 #define MEI_HBM_HOST_ENUM                  0x04
97 #define MEI_HBM_HOST_ENUM_RES              0x84
98 
99 #define MEI_HBM_HOST_CLIENT_PROP           0x05
100 #define MEI_HBM_HOST_CLIENT_PROP_RES       0x85
101 
102 #define MEI_HBM_CLIENT_CONNECT             0x06
103 #define MEI_HBM_CLIENT_CONNECT_RES         0x86
104 
105 #define MEI_HBM_CLIENT_DISCONNECT          0x07
106 #define MEI_HBM_CLIENT_DISCONNECT_RES      0x87
107 
108 #define MEI_HBM_FLOW_CONTROL               0x08
109 
110 #define MEI_HBM_CLIENT_CONNECTION_RESET    0x09
111 
112 #define MEI_HBM_PG_ISOLATION_ENTRY         0x0a
113 #define MEI_HBM_PG_ISOLATION_ENTRY_RES     0x8a
114 
115 #define MEI_HBM_PG_ISOLATION_EXIT          0x0b
116 #define MEI_HBM_PG_ISOLATION_EXIT_RES      0x8b
117 
118 #define MEI_HBM_CLIENT_ADD                 0x0f
119 #define MEI_HBM_CLIENT_ADD_RES             0x8f
120 
121 #define MEI_HBM_NOTIFY                     0x10
122 #define MEI_HBM_NOTIFY_RES                 0x90
123 #define MEI_HBM_NOTIFICATION               0x11
124 
125 #define MEI_HBM_DMA_SETUP                  0x12
126 #define MEI_HBM_DMA_SETUP_RES              0x92
127 
128 /*
129  * MEI Stop Reason
130  * used by hbm_host_stop_request.reason
131  */
132 enum mei_stop_reason_types {
133 	DRIVER_STOP_REQUEST = 0x00,
134 	DEVICE_D1_ENTRY = 0x01,
135 	DEVICE_D2_ENTRY = 0x02,
136 	DEVICE_D3_ENTRY = 0x03,
137 	SYSTEM_S1_ENTRY = 0x04,
138 	SYSTEM_S2_ENTRY = 0x05,
139 	SYSTEM_S3_ENTRY = 0x06,
140 	SYSTEM_S4_ENTRY = 0x07,
141 	SYSTEM_S5_ENTRY = 0x08
142 };
143 
144 /*
145  * enum mei_hbm_status  - mei host bus messages return values
146  *
147  * @MEI_HBM_SUCCESS           : status success
148  * @MEI_HBM_CLIENT_NOT_FOUND  : client not found
149  * @MEI_HBM_ALREADY_EXISTS    : connection already established
150  * @MEI_HBM_REJECTED          : connection is rejected
151  * @MEI_HBM_INVALID_PARAMETER : invalid parameter
152  * @MEI_HBM_NOT_ALLOWED       : operation not allowed
153  * @MEI_HBM_ALREADY_STARTED   : system is already started
154  * @MEI_HBM_NOT_STARTED       : system not started
155  *
156  */
157 enum mei_hbm_status {
158 	MEI_HBM_SUCCESS           = 0,
159 	MEI_HBM_CLIENT_NOT_FOUND  = 1,
160 	MEI_HBM_ALREADY_EXISTS    = 2,
161 	MEI_HBM_REJECTED          = 3,
162 	MEI_HBM_INVALID_PARAMETER = 4,
163 	MEI_HBM_NOT_ALLOWED       = 5,
164 	MEI_HBM_ALREADY_STARTED   = 6,
165 	MEI_HBM_NOT_STARTED       = 7,
166 
167 	MEI_HBM_MAX
168 };
169 
170 /*
171  * Client Connect Status
172  * used by hbm_client_connect_response.status
173  */
174 enum mei_cl_connect_status {
175 	MEI_CL_CONN_SUCCESS          = MEI_HBM_SUCCESS,
176 	MEI_CL_CONN_NOT_FOUND        = MEI_HBM_CLIENT_NOT_FOUND,
177 	MEI_CL_CONN_ALREADY_STARTED  = MEI_HBM_ALREADY_EXISTS,
178 	MEI_CL_CONN_OUT_OF_RESOURCES = MEI_HBM_REJECTED,
179 	MEI_CL_CONN_MESSAGE_SMALL    = MEI_HBM_INVALID_PARAMETER,
180 	MEI_CL_CONN_NOT_ALLOWED      = MEI_HBM_NOT_ALLOWED,
181 };
182 
183 /*
184  * Client Disconnect Status
185  */
186 enum  mei_cl_disconnect_status {
187 	MEI_CL_DISCONN_SUCCESS = MEI_HBM_SUCCESS
188 };
189 
190 struct mei_enumerate_me_clients {
191 	uint8_t valid_addresses[32];
192 };
193 
194 struct mei_client_properties {
195 	guid_t   protocol_name;
196 	uint8_t  protocol_version;
197 	uint8_t  max_connections;
198 	uint8_t  fixed_address;
199 	uint8_t  single_recv_buf;
200 	uint32_t max_msg_length;
201 } __attribute__((packed));
202 
203 /* message header is same in native and virtual */
204 struct mei_msg_hdr {
205 	uint32_t me_addr:8;
206 	uint32_t host_addr:8;
207 	uint32_t length:9;
208 	uint32_t reserved:5;
209 	uint32_t internal:1;
210 	uint32_t msg_complete:1;
211 } __attribute__((packed));
212 
213 struct mei_hbm_cmd {
214 	uint8_t cmd:7;
215 	uint8_t is_response:1;
216 } __attribute__((packed));
217 
218 struct mei_hbm_host_ver_req {
219 	struct mei_hbm_cmd hbm_cmd;
220 	uint8_t reserved;
221 	uint8_t minor;
222 	uint8_t major;
223 } __attribute__((packed));
224 
225 struct mei_hbm_host_ver_res {
226 	struct mei_hbm_cmd hbm_cmd;
227 	uint8_t host_ver_support;
228 	uint8_t minor;
229 	uint8_t major;
230 } __attribute__((packed));
231 
232 struct mei_hbm_host_stop_req {
233 	struct mei_hbm_cmd hbm_cmd;
234 	uint8_t reason;
235 	uint8_t reserved[2];
236 } __attribute__((packed));
237 
238 struct mei_hbm_host_stop_res {
239 	struct mei_hbm_cmd hbm_cmd;
240 	uint8_t reserved[3];
241 } __attribute__((packed));
242 
243 struct mei_hbm_me_stop_res {
244 	struct mei_hbm_cmd hbm_cmd;
245 	uint8_t reason;
246 	uint8_t reserved[2];
247 } __attribute__((packed));
248 
249 struct mei_hbm_me_stop_req {
250 	struct mei_hbm_cmd hbm_cmd;
251 	uint8_t reserved[3];
252 } __attribute__((packed));
253 
254 /**
255  * enum hbm_host_enum_flags - enumeration request flags (HBM version >= 2.0)
256  *
257  * @MEI_HBM_ENUM_F_ALLOW_ADD: allow dynamic clients add
258  * @MEI_HBM_ENUM_F_IMMEDIATE_ENUM: allow FW to send answer immediately
259  */
260 enum mei_hbm_host_enum_flags {
261 	MEI_HBM_ENUM_F_ALLOW_ADD = 0,
262 	MEI_HBM_ENUM_F_IMMEDIATE_ENUM = 1,
263 };
264 
265 struct mei_hbm_host_enum_req {
266 	struct mei_hbm_cmd hbm_cmd;
267 	uint8_t flags;
268 	uint8_t reserved[2];
269 } __attribute__((packed));
270 
271 struct mei_hbm_host_enum_res {
272 	struct mei_hbm_cmd hbm_cmd;
273 	uint8_t reserved[3];
274 	uint8_t valid_addresses[32];
275 };
276 
277 struct mei_hbm_host_client_prop_req {
278 	struct mei_hbm_cmd hbm_cmd;
279 	uint8_t address;
280 	uint8_t reserved[2];
281 } __attribute__((packed));
282 
283 
284 struct mei_hbm_host_client_prop_res {
285 	struct mei_hbm_cmd hbm_cmd;
286 	uint8_t address;
287 	uint8_t status;
288 	uint8_t reserved[1];
289 	struct mei_client_properties props;
290 } __attribute__((packed));
291 
292 /**
293  * struct mei_hbm_add_client_req - request to add a client
294  *     might be sent by fw after enumeration has already completed
295  *
296  * @hbm_cmd: bus message command header
297  * @me_addr: address of the client in ME
298  * @reserved: reserved
299  * @client_properties: client properties
300  */
301 struct mei_hbm_add_client_req {
302 	struct mei_hbm_cmd hbm_cmd;
303 	uint8_t me_addr;
304 	uint8_t reserved[2];
305 	struct mei_client_properties client_properties;
306 } __attribute__((packed));
307 
308 /**
309  * struct mei_hbm_add_client_res - response to add a client
310  *     sent by the host to report client addition status to fw
311  *
312  * @hbm_cmd: bus message command header
313  * @me_addr: address of the client in ME
314  * @status: if HBM_SUCCESS then the client can now accept connections.
315  * @reserved: reserved
316  */
317 struct hbm_add_client_res {
318 	struct mei_hbm_cmd hbm_cmd;
319 	uint8_t me_addr;
320 	uint8_t status;
321 	uint8_t reserved[1];
322 } __attribute__((packed));
323 
324 /**
325  * struct mei_hbm_power_gate - power gate request/response
326  *
327  * @hbm_cmd: bus message command header
328  * @reserved: reserved
329  */
330 struct mei_hbm_power_gate {
331 	struct mei_hbm_cmd hbm_cmd;
332 	uint8_t reserved[3];
333 } __attribute__((packed));
334 
335 struct mei_hbm_client_connect_req {
336 	struct mei_hbm_cmd hbm_cmd;
337 	uint8_t me_addr;
338 	uint8_t host_addr;
339 	uint8_t reserved;
340 } __attribute__((packed));
341 
342 struct mei_hbm_client_connect_res {
343 	struct mei_hbm_cmd hbm_cmd;
344 	uint8_t me_addr;
345 	uint8_t host_addr;
346 	uint8_t status;
347 } __attribute__((packed));
348 
349 struct mei_hbm_client_disconnect_req {
350 	struct mei_hbm_cmd hbm_cmd;
351 	uint8_t me_addr;
352 	uint8_t host_addr;
353 	uint8_t status;
354 } __attribute__((packed));
355 
356 struct mei_hbm_client_disconnect_res {
357 	struct mei_hbm_cmd hbm_cmd;
358 	uint8_t me_addr;
359 	uint8_t host_addr;
360 	uint8_t status;
361 } __attribute__((packed));
362 
363 struct mei_hbm_flow_ctl {
364 	struct mei_hbm_cmd hbm_cmd;
365 	uint8_t me_addr;
366 	uint8_t host_addr;
367 	uint8_t reserved[5];
368 } __attribute__((packed));
369 
370 /**
371  * struct mei_hbm_notification_req - start/stop notification request
372  *
373  * @hbm_cmd: bus message command header
374  * @me_addr: address of the client in ME
375  * @host_addr: address of the client in the driver
376  * @start:  start = 1 or stop = 0 asynchronous notifications
377  */
378 
379 struct mei_hbm_notification_req {
380 	struct mei_hbm_cmd hbm_cmd;
381 	uint8_t me_addr;
382 	uint8_t host_addr;
383 	uint8_t start;
384 } __attribute__((packed));
385 
386 /**
387  * struct mei_hbm_notification_res - start/stop notification response
388  *
389  * @hbm_cmd: bus message command header
390  * @me_addr: address of the client in ME
391  * @host_addr: - address of the client in the driver
392  * @status: (mei_hbm_status) response status for the request
393  *  - MEI_HBM_SUCCESS: successful stop/start
394  *  - MEI_HBM_CLIENT_NOT_FOUND: if the connection could not be found.
395  *  - MEI_HBM_ALREADY_STARTED: for start requests for a previously
396  *                         started notification.
397  *  - MEI_HBM_NOT_STARTED: for stop request for a connected client for whom
398  *                         asynchronous notifications are currently disabled.
399  *
400  * @start:  start = 1 or stop = 0 asynchronous notifications
401  * @reserved: reserved
402  */
403 struct mei_hbm_notification_res {
404 	struct mei_hbm_cmd hbm_cmd;
405 	uint8_t me_addr;
406 	uint8_t host_addr;
407 	uint8_t status;
408 	uint8_t start;
409 	uint8_t reserved[3];
410 } __attribute__((packed));
411 
412 /**
413  * struct mei_hbm_notification - notification event
414  *
415  * @hbm_cmd: bus message command header
416  * @me_addr:  address of the client in ME
417  * @host_addr:  address of the client in the driver
418  * @reserved: reserved for alignment
419  */
420 struct mei_hbm_notification {
421 	struct mei_hbm_cmd hbm_cmd;
422 	uint8_t me_addr;
423 	uint8_t host_addr;
424 	uint8_t reserved[1];
425 } __attribute__((packed));
426 
427 /**
428  * struct mei_hbm_dma_mem_dscr - dma ring
429  *
430  * @addr_hi: the high 32bits of 64 bit address
431  * @addr_lo: the low  32bits of 64 bit address
432  * @size   : size in bytes (must be power of 2)
433  */
434 struct mei_hbm_dma_mem_dscr {
435 	uint32_t addr_hi;
436 	uint32_t addr_lo;
437 	uint32_t size;
438 } __attribute__((packed));
439 
440 enum {
441 	MEI_DMA_DSCR_HOST = 0,
442 	MEI_DMA_DSCR_DEVICE = 1,
443 	MEI_DMA_DSCR_CTRL = 2,
444 	MEI_DMA_DSCR_NUM,
445 };
446 
447 /**
448  * struct mei_hbm_dma_setup_req - dma setup request
449  *
450  * @hbm_cmd: bus message command header
451  * @reserved: reserved for alignment
452  * @dma_dscr: dma descriptor for HOST, DEVICE, and CTRL
453  */
454 struct mei_hbm_dma_setup_req {
455 	struct mei_hbm_cmd hbm_cmd;
456 	uint8_t reserved[3];
457 	struct mei_hbm_dma_mem_dscr dma_dscr[MEI_DMA_DSCR_NUM];
458 } __attribute__((packed));
459 
460 /**
461  * struct mei_hbm_dma_setup_res - dma setup response
462  *
463  * @hbm_cmd: bus message command header
464  * @status: 0 on success; otherwise DMA setup failed.
465  * @reserved: reserved for alignment
466  */
467 struct mei_hbm_dma_setup_res {
468 	struct mei_hbm_cmd hbm_cmd;
469 	uint8_t status;
470 	uint8_t reserved[2];
471 } __attribute__((packed));
472 
473 #ifndef IOCTL_MEI_CONNECT_CLIENT_VTAG
474 /*
475  * IOCTL Connect Client Data structure with vtag
476  */
477 struct mei_connect_client_vtag {
478 	uuid_le in_client_uuid;
479 	__u8 vtag;
480 	__u8 reserved[3];
481 };
482 
483 struct mei_connect_client_data_vtag {
484 	union {
485 		struct mei_connect_client_vtag connect;
486 		struct mei_client out_client_properties;
487 	};
488 };
489 
490 #define IOCTL_MEI_CONNECT_CLIENT_VTAG \
491 	_IOWR('H', 0x04, struct mei_connect_client_data_vtag)
492 
493 #endif /* IOCTL_MEI_CONNECT_CLIENT_VTAG */
494 
495 #endif    /* _MEI_HBM_H_ */
496