xref: /titanic_41/usr/src/uts/intel/io/heci/heci_data_structures.h (revision 617e2443dfc17fe44fd44c0675d6aad2ffc9df42)
1 /*
2  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Part of Intel(R) Manageability Engine Interface Linux driver
8  *
9  * Copyright (c) 2003 - 2008 Intel Corp.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions, and the following disclaimer,
17  *    without modification.
18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19  *    substantially similar to the "NO WARRANTY" disclaimer below
20  *    ("Disclaimer") and any redistribution must be conditioned upon
21  *    including a substantially similar Disclaimer requirement for further
22  *    binary redistribution.
23  * 3. Neither the names of the above-listed copyright holders nor the names
24  *    of any contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * Alternatively, this software may be distributed under the terms of the
28  * GNU General Public License ("GPL") version 2 as published by the Free
29  * Software Foundation.
30  *
31  * NO WARRANTY
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42  * POSSIBILITY OF SUCH DAMAGES.
43  *
44  */
45 
46 #ifndef _HECI_DATA_STRUCTURES_H_
47 #define	_HECI_DATA_STRUCTURES_H_
48 
49 #include <sys/varargs.h>
50 #include <sys/types.h>
51 
52 #ifndef SUNOS
53 #define	SUNOS
54 #endif
55 
56 /*
57  * error code definition
58  */
59 #define	ESLOTS_OVERFLOW	1
60 #define	ECORRUPTED_MESSAGE_HEADER	1000
61 #define	ECOMPLETE_MESSAGE	1001
62 
63 #define	HECI_FC_MESSAGE_RESERVED_LENGTH	5
64 
65 /*
66  * Number of queue lists used by this driver
67  */
68 #define	HECI_IO_LISTS_NUMBER	7
69 
70 /*
71  * Maximum transmission unit (MTU) of heci messages
72  */
73 #define	IAMTHIF_MTU	4160
74 #pragma pack(1)
75 
76 
77 /*
78  * HECI HW Section
79  */
80 
81 /* HECI registers */
82 /* H_CB_WW - Host Circular Buffer (CB) Write Window register */
83 #define	H_CB_WW	0
84 /* H_CSR - Host Control Status register */
85 #define	H_CSR	4
86 /* ME_CB_RW - ME Circular Buffer Read Window register (read only) */
87 #define	ME_CB_RW	8
88 /* ME_CSR_HA - ME Control Status Host Access register (read only) */
89 #define	ME_CSR_HA	0xC
90 
91 
92 /* register bits of H_CSR (Host Control Status register) */
93 /* Host Circular Buffer Depth - maximum number of 32-bit entries in CB */
94 #define	H_CBD	0xFF000000
95 /* Host Circular Buffer Write Pointer */
96 #define	H_CBWP	0x00FF0000
97 /* Host Circular Buffer Read Pointer */
98 #define	H_CBRP	0x0000FF00
99 /* Host Reset */
100 #define	H_RST	0x00000010
101 /* Host Ready */
102 #define	H_RDY	0x00000008
103 /* Host Interrupt Generate */
104 #define	H_IG	0x00000004
105 /* Host Interrupt Status */
106 #define	H_IS	0x00000002
107 /* Host Interrupt Enable */
108 #define	H_IE	0x00000001
109 
110 
111 /*
112  * register bits of ME_CSR_HA (ME Control Status Host Access register)
113  * ME CB (Circular Buffer) Depth HRA (Host Read Access)
114  *  - host read only access to ME_CBD
115  */
116 #define	ME_CBD_HRA	0xFF000000
117 /* ME CB Write Pointer HRA - host read only access to ME_CBWP */
118 #define	ME_CBWP_HRA	0x00FF0000
119 /* ME CB Read Pointer HRA - host read only access to ME_CBRP */
120 #define	ME_CBRP_HRA	0x0000FF00
121 /* ME Reset HRA - host read only access to ME_RST */
122 #define	ME_RST_HRA	0x00000010
123 /* ME Ready HRA - host read only access to ME_RDY */
124 #define	ME_RDY_HRA	0x00000008
125 /* ME Interrupt Generate HRA - host read only access to ME_IG */
126 #define	ME_IG_HRA	0x00000004
127 /* ME Interrupt Status HRA - host read only access to ME_IS */
128 #define	ME_IS_HRA	0x00000002
129 /* ME Interrupt Enable HRA - host read only access to ME_IE */
130 #define	ME_IE_HRA	0x00000001
131 
132 #define	HECI_MINOR_NUMBER	1
133 /* #define  HECI_PTHI_MINOR_NUMBER	0 */
134 #define	MAKE_MINOR_NUM(minor, instance)	(((uint_t)(minor) << 8) \
135 				    | ((instance) & 0xFF))
136 #define	HECI_MINOR_TO_INSTANCE(x)	((x) & 0xFF)
137 #define	HECI_MINOR_TO_IFNUM(x)		(((x) >> 8) & 0xFF)
138 
139 #define	HECI_MAX_OPEN_HANDLE_COUNT	253
140 
141 /*
142  * debug kernel print macro define
143  */
144 #define	PRN(...)	_PRN("%s():  "__VA_ARGS__, "")
145 #define	_PRN(format, ...)					\
146 	cmn_err(CE_CONT, format"%s", __func__, __VA_ARGS__)
147 
148 #ifdef DEBUG
149 extern int heci_debug;
150 #define	DBG(...) { if (heci_debug) PRN(__VA_ARGS__); }
151 #else
152 #define	DBG
153 #endif
154 
155 #define	assert(expr) \
156 	if (!(expr)) {                                   \
157 		cmn_err(CE_WARN, "Assertion failed! %s,%s,line=%d", #expr, \
158 		__FILE__, __LINE__);          \
159 	}
160 
161 #define	list_next(p)	((p)->list_next)
162 
163 #define	walk_list(p, n, h) \
164 	for (p = list_next(h), n = list_next(p);	\
165 		p != (h); \
166 		p = n, n = list_next(p))
167 
168 
169 #define	list_init(ptr) { \
170 	(ptr)->list_next = (ptr); (ptr)->list_prev = (ptr); \
171 }
172 
173 #define	LIST_INIT_HEAD	list_init
174 #define	list_del_init(n)	{ \
175 	    list_del(n); \
176 	    list_init(n); \
177 	}
178 
179 #define	list_empty(l)	((l)->list_next == (l))
180 #define	list_del(p)	{ (p)->list_next->list_prev = (p)->list_prev; \
181 	(p)->list_prev->list_next = (p)->list_next; }
182 #define	list_add_tail(newnode, head) { \
183 		(head)->list_prev->list_next = (newnode); \
184 		(newnode)->list_prev = (head)->list_prev; \
185 		(head)->list_prev = (newnode); \
186 		(newnode)->list_next = (head); \
187 	}
188 #define	list_relink_node(newnode, head)	{ \
189 		list_del(newnode); \
190 		list_add_tail(newnode, head); \
191 	}
192 
193 #ifdef __GNUC__
194 
195 #define	find_struct(ptr, type, member) ( \
196 	{ \
197 	const __typeof(((type *)0)->member) *__tmpp = (ptr);  \
198 	(type *)(void *)((char *)__tmpp - ((size_t)&((type *)0)->member)); \
199 	})
200 #else
201 /* type unsafe version */
202 #define	find_struct(ptr, type, member) \
203 		((type *)(void *)((char *)(ptr) \
204 		- ((size_t)&((type *)0)->member)))
205 
206 #endif
207 
208 #define	list_for_each_entry_safe(pos, n, head, member, type)                  \
209 	for (pos = find_struct((head)->list_next, type, member),      \
210 		n = find_struct(pos->member.list_next, type, member); \
211 		&pos->member != (head);                                    \
212 		pos = n, n = find_struct(n->member.list_next, type, member))
213 
214 #define	HZ		drv_usectohz(1000000)
215 /*
216  * time to wait HECI become ready after init
217  */
218 #define	HECI_INTEROP_TIMEOUT    (HZ * 7)
219 
220 /*
221  * watch dog definition
222  */
223 #define	HECI_WATCHDOG_DATA_SIZE	16
224 #define	HECI_START_WD_DATA_SIZE	20
225 #define	HECI_WD_PARAMS_SIZE	4
226 #define	HECI_WD_STATE_INDEPENDENCE_MSG_SENT	(1 << 0)
227 
228 #define	HECI_WD_HOST_CLIENT_ID	1
229 #define	HECI_IAMTHIF_HOST_CLIENT_ID	2
230 
231 struct guid {
232 	uint32_t data1;
233 	uint16_t data2;
234 	uint16_t data3;
235 	uint8_t data4[8];
236 };
237 
238 /* File state */
239 enum file_state {
240 	HECI_FILE_INITIALIZING = 0,
241 	HECI_FILE_CONNECTING,
242 	HECI_FILE_CONNECTED,
243 	HECI_FILE_DISCONNECTING,
244 	HECI_FILE_DISCONNECTED
245 };
246 
247 /* HECI device states */
248 enum heci_states {
249 	HECI_INITIALIZING = 0,
250 	HECI_ENABLED,
251 	HECI_RESETING,
252 	HECI_DISABLED,
253 	HECI_RECOVERING_FROM_RESET,
254 	HECI_POWER_DOWN,
255 	HECI_POWER_UP
256 };
257 
258 enum iamthif_states {
259 	HECI_IAMTHIF_IDLE,
260 	HECI_IAMTHIF_WRITING,
261 	HECI_IAMTHIF_FLOW_CONTROL,
262 	HECI_IAMTHIF_READING,
263 	HECI_IAMTHIF_READ_COMPLETE
264 };
265 
266 enum heci_file_transaction_states {
267 	HECI_IDLE,
268 	HECI_WRITING,
269 	HECI_WRITE_COMPLETE,
270 	HECI_FLOW_CONTROL,
271 	HECI_READING,
272 	HECI_READ_COMPLETE
273 };
274 
275 /* HECI CB */
276 enum heci_cb_major_types {
277 	HECI_READ = 0,
278 	HECI_WRITE,
279 	HECI_IOCTL,
280 	HECI_OPEN,
281 	HECI_CLOSE
282 };
283 
284 /* HECI user data struct */
285 struct heci_message_data {
286 	uint32_t size;
287 	char *data;
288 #ifndef  _LP64
289 	char *pad;
290 #endif
291 };
292 
293 #define	HECI_CONNECT_TIMEOUT	3	/* at least 2 seconds */
294 
295 #define	IAMTHIF_STALL_TIMER	12	/* seconds */
296 #define	IAMTHIF_READ_TIMER	15	/* seconds */
297 struct heci_file {
298 	void * private_data;
299 };
300 
301 struct heci_cb_private {
302 	struct list_node cb_list;
303 	enum heci_cb_major_types major_file_operations;
304 	void *file_private;
305 	struct heci_message_data request_buffer;
306 	struct heci_message_data response_buffer;
307 	unsigned long information;
308 	unsigned long read_time;
309 	struct heci_file *file_object;
310 };
311 
312 
313 struct io_heci_list {
314 	struct heci_cb_private heci_cb;
315 	int status;
316 	struct iamt_heci_device *device_extension;
317 };
318 
319 struct heci_driver_version {
320 	uint8_t major;
321 	uint8_t minor;
322 	uint8_t hotfix;
323 	uint16_t build;
324 };
325 
326 struct heci_client {
327 	uint32_t max_message_length;
328 	uint8_t protocol_version;
329 };
330 
331 /*
332  *  HECI BUS Interface Section
333  */
334 struct heci_msg_hdr {
335 	uint32_t me_addr:8;
336 	uint32_t host_addr:8;
337 	uint32_t length:9;
338 	uint32_t reserved:6;
339 	uint32_t msg_complete:1;
340 };
341 
342 
343 struct hbm_cmd {
344 	uint8_t cmd:7;
345 	uint8_t is_response:1;
346 };
347 
348 
349 struct heci_bus_message {
350 	struct hbm_cmd cmd;
351 	uint8_t command_specific_data[];
352 };
353 
354 struct hbm_version {
355 	uint8_t minor_version;
356 	uint8_t major_version;
357 };
358 
359 struct hbm_host_version_request {
360 	struct hbm_cmd cmd;
361 	uint8_t reserved;
362 	struct hbm_version host_version;
363 };
364 
365 struct hbm_host_version_response {
366 	struct hbm_cmd cmd;
367 	int host_version_supported;
368 	struct hbm_version me_max_version;
369 };
370 
371 struct hbm_host_stop_request {
372 	struct hbm_cmd cmd;
373 	uint8_t reason;
374 	uint8_t reserved[2];
375 };
376 
377 struct hbm_host_stop_response {
378 	struct hbm_cmd cmd;
379 	uint8_t reserved[3];
380 };
381 
382 struct hbm_me_stop_request {
383 	struct hbm_cmd cmd;
384 	uint8_t reason;
385 	uint8_t reserved[2];
386 };
387 
388 struct hbm_host_enum_request {
389 	struct hbm_cmd cmd;
390 	uint8_t reserved[3];
391 };
392 
393 struct hbm_host_enum_response {
394 	struct hbm_cmd cmd;
395 	uint8_t reserved[3];
396 	uint8_t valid_addresses[32];
397 };
398 
399 struct heci_client_properties {
400 	struct guid protocol_name;
401 	uint8_t protocol_version;
402 	uint8_t max_number_of_connections;
403 	uint8_t fixed_address;
404 	uint8_t single_recv_buf;
405 	uint32_t max_msg_length;
406 };
407 
408 struct hbm_props_request {
409 	struct hbm_cmd cmd;
410 	uint8_t address;
411 	uint8_t reserved[2];
412 };
413 
414 
415 struct hbm_props_response {
416 	struct hbm_cmd cmd;
417 	uint8_t address;
418 	uint8_t status;
419 	uint8_t reserved[1];
420 	struct heci_client_properties client_properties;
421 };
422 
423 struct hbm_client_connect_request {
424 	struct hbm_cmd cmd;
425 	uint8_t me_addr;
426 	uint8_t host_addr;
427 	uint8_t reserved;
428 };
429 
430 struct hbm_client_connect_response {
431 	struct hbm_cmd cmd;
432 	uint8_t me_addr;
433 	uint8_t host_addr;
434 	uint8_t status;
435 };
436 
437 struct hbm_client_disconnect_request {
438 	struct hbm_cmd cmd;
439 	uint8_t me_addr;
440 	uint8_t host_addr;
441 	uint8_t reserved[1];
442 };
443 
444 struct hbm_flow_control {
445 	struct hbm_cmd cmd;
446 	uint8_t me_addr;
447 	uint8_t host_addr;
448 	uint8_t reserved[HECI_FC_MESSAGE_RESERVED_LENGTH];
449 };
450 
451 struct heci_me_client {
452 	struct heci_client_properties props;
453 	uint8_t client_id;
454 	uint8_t flow_ctrl_creds;
455 };
456 
457 #pragma pack()
458 /* Private file struct */
459 struct heci_file_private {
460 	struct list_node link;
461 	struct heci_file *file;
462 	enum file_state state;
463 	struct pollhead tx_pollwait;
464 	kcondvar_t	rx_wait;
465 	struct pollhead pollwait;
466 	kmutex_t file_lock;
467 	kmutex_t read_io_lock;
468 	kmutex_t write_io_lock;
469 	int read_pending;
470 	int status;
471 	/* ID of client connected */
472 	uint8_t host_client_id;
473 	uint8_t me_client_id;
474 	uint8_t flow_ctrl_creds;
475 	uint8_t timer_count;
476 	enum heci_file_transaction_states reading_state;
477 	enum heci_file_transaction_states writing_state;
478 	int sm_state;
479 	struct heci_cb_private *read_cb;
480 };
481 
482 /* private device struct */
483 struct iamt_heci_device {
484 	dev_info_t	*dip;
485 	ddi_acc_handle_t io_handle;
486 	ddi_iblock_cookie_t sc_iblk;
487 
488 	/*
489 	 * lists of queues
490 	 */
491 
492 	/* array of pointers to  aio lists */
493 	struct io_heci_list *io_list_array[HECI_IO_LISTS_NUMBER];
494 	struct io_heci_list read_list;	/* driver read queue */
495 	struct io_heci_list write_list;	/* driver write queue */
496 	struct io_heci_list write_waiting_list;	/* write waiting queue */
497 	struct io_heci_list ctrl_wr_list;	/* managed write IOCTL list */
498 	struct io_heci_list ctrl_rd_list;	/* managed read IOCTL list */
499 	struct io_heci_list pthi_cmd_list;	/* PTHI list for cmd waiting */
500 
501 	/* driver managed PTHI list for reading completed pthi cmd data */
502 	struct io_heci_list pthi_read_complete_list;
503 	/*
504 	 * list of files
505 	 */
506 	struct list_node file_list;
507 	/*
508 	 * memory of device
509 	 */
510 	char *mem_addr;
511 	/*
512 	 * lock for the device
513 	 */
514 	kmutex_t device_lock;
515 	ddi_taskq_t	*work;
516 	int recvd_msg;
517 
518 	ddi_taskq_t *reinit_tsk;
519 	timeout_id_t wd_timer;
520 	/*
521 	 * hw states of host and fw(ME)
522 	 */
523 	uint32_t host_hw_state;
524 	uint32_t me_hw_state;
525 	/*
526 	 * waiting queue for receive message from FW
527 	 */
528 	kcondvar_t wait_recvd_msg;
529 	kcondvar_t wait_stop_wd;
530 	/*
531 	 * heci device  states
532 	 */
533 	enum heci_states heci_state;
534 	int stop;
535 
536 	uint32_t extra_write_index;
537 	uint32_t rd_msg_buf[128];	/* used for control messages */
538 	uint32_t wr_msg_buf[128];	/* used for control messages */
539 	uint32_t ext_msg_buf[8];	/* for control responses    */
540 	uint32_t rd_msg_hdr;
541 
542 	struct hbm_version version;
543 
544 	int host_buffer_is_empty;
545 	struct heci_file_private wd_file_ext;
546 	struct heci_me_client *me_clients; /* Note: need to be allocated */
547 	uint8_t heci_me_clients[32];	/* list of existing clients */
548 	uint8_t num_heci_me_clients;
549 	uint8_t heci_host_clients[32];	/* list of existing clients */
550 	uint8_t current_host_client_id;
551 
552 	int wd_pending;
553 	int wd_stoped;
554 	uint16_t wd_timeout;	/* seconds ((wd_data[1] << 8) + wd_data[0]) */
555 	unsigned char wd_data[HECI_START_WD_DATA_SIZE];
556 
557 
558 	uint16_t wd_due_counter;
559 	int asf_mode;
560 	int wd_bypass;	/* if 1, don't refresh watchdog ME client */
561 
562 	struct heci_file *iamthif_file_object;
563 	struct heci_file_private iamthif_file_ext;
564 	int iamthif_ioctl;
565 	int iamthif_canceled;
566 	uint32_t iamthif_timer;
567 	uint32_t iamthif_stall_timer;
568 	struct heci_file files[256]; /* a file handle for each client */
569 	unsigned char iamthif_msg_buf[IAMTHIF_MTU];
570 	uint32_t iamthif_msg_buf_size;
571 	uint32_t iamthif_msg_buf_index;
572 	int iamthif_flow_control_pending;
573 	enum iamthif_states iamthif_state;
574 
575 	struct heci_cb_private *iamthif_current_cb;
576 	uint8_t write_hang;
577 	int need_reset;
578 	long open_handle_count;
579 
580 };
581 
582 /*
583  * read_heci_register - Read a byte from the heci device
584  *
585  * @device: the device structure
586  * @offset: offset from which to read the data
587  *
588  * @return the byte read.
589  */
590 uint32_t read_heci_register(struct iamt_heci_device *device,
591 			    unsigned long offset);
592 
593 /*
594  * write_heci_register - Write  4 bytes to the heci device
595  *
596  * @device: the device structure
597  * @offset: offset from which to write the data
598  * @value: the byte to write
599  */
600 void write_heci_register(struct iamt_heci_device *device, unsigned long offset,
601 		uint32_t value);
602 
603 #define	UIO_OFFSET(p)	(((struct uio *)p)->uio_offset)
604 #define	UIO_LENGTH(p)	(((struct uio *)p)->uio_resid)
605 #define	UIO_BUFF(p)	((char *)((struct uio *)p)->uio_iov->iov_base)
606 
607 #endif /* _HECI_DATA_STRUCTURES_H_ */
608