summaryrefslogtreecommitdiff
path: root/usr/src/uts/sun4u/sys/rmc_comm_dp.h
blob: fac3aff675e5e5b60816e5de59730965b9467ef5 (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
230
231
232
233
234
235
236
237
238
239
240
241
242
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_SYS_RMC_COMM_DP_H
#define	_SYS_RMC_COMM_DP_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"


#include <sys/rmc_comm_lproto.h>

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * buffer size (used for tx/rx operations)
 */
#define	DP_BUFFER_SIZE	2048

/*
 * Number of tx/rx buffers. there are 2 (static) buffers: receive buffer and
 * send buffer. These buffers are basically used by the protocol to packetize
 * a message to be sent OR to collect data received from the serial device.
 * Currently, we just need two for send and receive operations respectively
 * since there is only one request/response session per time (i.e. a new
 * session is not started until the previous one has not finished)
 */
#define	DP_BUFFER_COUNT		2

#define	DP_TX_BUFFER		0
#define	DP_RX_BUFFER		1

/*
 * Tx/Rx buffers.
 */
typedef struct dp_buffer {
	boolean_t in_use;
	uint8_t buf[DP_BUFFER_SIZE];
} dp_buffer_t;

/*
 * Data structure used to collect data from the serial device and to
 * assemble protocol packets
 */

/*
 * The possible states the message receiver can be in:
 */
#define	WAITING_FOR_SYNC	0
#define	WAITING_FOR_SYNC_ESC	1
#define	WAITING_FOR_HDR		2
#define	RECEIVING_HDR		3
#define	RECEIVING_HDR_ESC	4
#define	RECEIVING_BODY		5
#define	RECEIVING_BODY_ESC	6
#define	N_RX_STATES		7

/*
 * This is the structure passed between the message receiver state routines.
 * It keeps track of all the state of a message that is in the process of
 * being received.
 */
typedef struct dp_packet {
	uint8_t rx_state;	/* Current state of receive engine. */
	uint8_t *inbuf;		/* Input characters to be processed. */
	int16_t inbuflen;	/* Number of input characters. */
	uint8_t *buf;		/* Buffer used to receive current message. */
	int16_t bufpos;		/* Position in buffer. */
	int16_t full_length;	/* Full length of this message. */
} dp_packet_t;


/*
 * message data structure used to send/receive data
 */
typedef struct dp_message {

	uint8_t   msg_type;	/* message type */
	uint8_t  *msg_buf;	/* message buffer */
	uint16_t  msg_bufsiz;	/* size of the buffer */
	int16_t   msg_msglen;	/* message length */

} dp_message_t;

/*
 * structure used by the protocol to send (and, eventually re-send...)
 * messages to the remote side. It keeps the status of the data transfer
 * (message sent, reply received, etc.). It is also used to match
 * request/response
 */

typedef struct dp_req_resp {

	uint8_t		flags;		/* status of the data transfer */

#define	MSG_ERROR 	0x01
#define	MSG_SENT 	0x02
#define	MSG_ACKED 	0x04
#define	MSG_REPLY_RXED	0x08
#define	MSG_NAKED	0x10
#define	MSG_RESET	0x20
#define	MSG_SENT_BP	0x40
#define	MSG_RXED_BP	0x80

	int		error_status;   /* error code */

	uint8_t		retries_left;   /* number of retries left */

	kcondvar_t  	cv_wait_reply[1];	/* cv variable used to signal */
						/* threads waiting for a */
						/* reply */

	dp_message_t	request;	/* request buffer */

	dp_message_t	response;	/* response buffer */

} dp_req_resp_t;


/*
 * interrupt handler prototype (asynchronous messages notification)
 */
typedef uint_t (*rmc_comm_intrfunc_t)(caddr_t);

/*
 * data structure used to deal with asynchronous notification (requests)
 * from the remote side
 */
typedef struct dp_msg_intr {

	rmc_comm_intrfunc_t	intr_handler;	/* interrupt handler */

	ddi_softintr_t		intr_id;	/* soft intr. id */

	uint8_t			intr_msg_type;	/* message type */

	caddr_t			intr_arg;	/* message buffer containing */
						/* the expected message type */

	kmutex_t		*intr_lock;	/* for state flag below */
	uint_t			*intr_state;	/* interrupt handler state */

} dp_msg_intr_t;

/*
 * data protocol structure
 */

typedef struct rmc_comm_dp_state {

	/*
	 * data protcol mutex (initialized using <dp_iblk>)
	 */
	kmutex_t		dp_mutex[1];
	ddi_iblock_cookie_t	dp_iblk;

	boolean_t	data_link_ok;	/* tells whether the data link has */
					/* has been established */

	boolean_t	pending_request;	/* tells if a request is */
						/* already being processed */

	uint8_t		last_tx_seqid;	/* sequence ID of last message */
					/* transmitted */
	uint8_t		last_rx_seqid;  /* sequence ID of last message */
					/* received */
	uint8_t		last_rx_ack;    /* last message acknowledged by */
					/* remote side */

	timeout_id_t	timer_link_setup;	/* timer used to set up the */
						/* data link at regular */
						/* intervals when the link is */
						/* down */
	timeout_id_t	timer_delay_ack;	/* timer used to wait a 'bit' */
						/* before acknowledging a */
						/* received message. In the */
						/* meantime a request can be */
						/* sent from this side and, */
						/* hence, acnowledge that */
						/* message */

	kcondvar_t	cv_ok_to_send[1];	/* cv variable used to wait */
						/* until it is possible to */
						/* send the request (no */
						/* pending request */

	dp_packet_t	dp_packet;		/* used to assemble protocol */
						/* packet from data received */
						/* from the serial device */

	dp_req_resp_t	req_resp;		/* request/response data */
						/* structure */

	dp_msg_intr_t	msg_intr;		/* messages for which layered */
						/* drivers have registered */
						/* for an async notification */
						/* (soft.intr.) */

	dp_buffer_t	dp_buffers[DP_BUFFER_COUNT]; /* protocol buffer  */
						/* pool used for    */
						/* tx/rx operations */

	/* statistical information */

	uint16_t	reset_cnt;
	uint16_t	nak_cnt;
	uint16_t	start_cnt;
	uint16_t	stack_cnt;
	uint16_t	retries_cnt;
	uint16_t	crcerr_cnt;

} rmc_comm_dp_state_t;

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_RMC_COMM_DP_H */