1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef	_SYS_RMC_COMM_H
28#define	_SYS_RMC_COMM_H
29
30#pragma ident	"%Z%%M%	%I%	%E% SMI"
31
32#ifdef	__cplusplus
33extern "C" {
34#endif
35
36/*
37 * Hardware: serial chip register numbers
38 */
39#define	SIO_RXD			0	/* read		*/
40#define	SIO_TXD			0	/* write	*/
41#define	SIO_IER			1
42#define	SIO_EIR			2	/* read		*/
43#define	SIO_FCR			2	/* write	*/
44#define	SIO_LCR			3
45#define	SIO_BSR			3	/* wierd	*/
46#define	SIO_MCR			4
47#define	SIO_LSR			5
48#define	SIO_MSR			6
49#define	SIO_SCR			7
50
51#define	SIO_LBGDL		0	/* bank 1	*/
52#define	SIO_LBGDH		1	/* bank 1	*/
53
54/*
55 * Hardware: serial chip register bits
56 */
57#define	SIO_IER_RXHDL_IE	0x01
58#define	SIO_IER_STD		0x00
59
60#define	SIO_FCR_FIFO_EN		0x01
61#define	SIO_FCR_RXSR		0x02
62#define	SIO_FCR_TXSR		0x04
63#define	SIO_FCR_RXFTH0		0x40
64#define	SIO_FCR_STD		(SIO_FCR_RXFTH0|SIO_FCR_FIFO_EN)
65
66#define	SIO_LCR_WLS0		0x01
67#define	SIO_LCR_WLS1		0x02
68#define	SIO_LCR_PEN		0x08
69#define	SIO_LCR_EPS		0x10
70#define	SIO_LCR_BKSE		0x80
71#define	SIO_LCR_8BIT		(SIO_LCR_WLS0|SIO_LCR_WLS1)
72#define	SIO_LCR_STD		(SIO_LCR_8BIT)
73#define	SIO_BSR_BANK0		(SIO_LCR_STD)
74#define	SIO_BSR_BANK1		(SIO_LCR_BKSE|SIO_LCR_STD)
75
76#define	SIO_MCR_ISEN		0x08
77#define	SIO_MCR_STD		(SIO_MCR_ISEN)
78
79/* Line Status Register */
80#define	SIO_LSR_RXDA		0x01	/* data ready */
81#define	SIO_LSR_OVRRUN		0x02	/* overrun error */
82#define	SIO_LSR_PARERR		0x04	/* parity error */
83#define	SIO_LSR_FRMERR		0x08	/* framing error */
84#define	SIO_LSR_BRKDET		0x10	/* a break has arrived */
85#define	SIO_LSR_XHRE		0x20	/* tx hold reg is now empty */
86#define	SIO_LSR_XSRE		0x40	/* tx shift reg is now empty */
87#define	SIO_LSR_RFBE		0x80	/* rx FIFO Buffer error */
88
89/*
90 * Min/max/default baud rates, and a macro to convert from a baud
91 * rate to the number (divisor) to put in the baud rate registers
92 */
93#define	SIO_BAUD_MIN		50
94#define	SIO_BAUD_MAX		115200
95#define	SIO_BAUD_DEFAULT	115200
96#define	SIO_BAUD_TO_DIVISOR(b)	(115200 / (b))
97#define	SIO_BAUD_DIVISOR_MIN	1
98#define	SIO_BAUD_DIVISOR_MAX	64
99
100/*
101 * serial rx buffer size: set to maximum message size + 'bits'
102 * (protocol overhead)
103 */
104
105#define	SIO_MAX_RXBUF_SIZE	(DP_MAX_MSGLEN + 128)
106
107/*
108 * protocol status struct
109 */
110
111typedef struct rmc_comm_serdev_state {
112
113	ddi_acc_handle_t sio_handle;
114	uint8_t *sio_regs;
115	ddi_softintr_t softid;
116	ddi_periodic_t cycid; /* periodical callback */
117
118	/*
119	 * Hardware mutex (initialised using <hw_iblk>),
120	 * used to prevent retriggering the softint while
121	 * it's still fetching data out of the chip FIFO.
122	 */
123	kmutex_t hw_mutex[1];
124	ddi_iblock_cookie_t hw_iblk;
125	boolean_t hw_int_enabled;
126
127	/*
128	 * Flag to indicate that we've incurred a hardware fault on
129	 * accesses to the SIO; once this is set, we fake all further
130	 * accesses in order not to provoke additional bus errors.
131	 */
132	boolean_t sio_fault;
133
134	/*
135	 * serial device receive buffer
136	 */
137	char serdev_rx_buf[SIO_MAX_RXBUF_SIZE];
138	uint16_t serdev_rx_count;
139
140} rmc_comm_serdev_state_t;
141
142/*
143 * This driver's soft-state structure
144 */
145struct rmc_comm_state {
146	/*
147	 * Configuration data, set during attach
148	 */
149	dev_info_t *dip;
150	major_t majornum;
151	int instance;
152	int n_registrations;
153	boolean_t is_attached;
154
155	/*
156	 * Parameters derived from .conf properties
157	 */
158	int baud;
159	uint32_t debug;
160	int baud_divisor_factor;
161
162	/*
163	 * serial device status...
164	 */
165	rmc_comm_serdev_state_t sd_state;
166
167	/*
168	 * protocol status struct
169	 */
170	rmc_comm_dp_state_t dp_state;
171
172	/*
173	 * driver interface status struct
174	 */
175	rmc_comm_drvintf_state_t drvi_state;
176};
177
178
179/*
180 * Time periods, in nanoseconds
181 */
182#define	RMC_COMM_ONE_SEC	1000000000LL
183
184/*
185 * debugging
186 */
187
188#define	DSER	0x01	/* serial device */
189#define	DPRO	0x02	/* protocol */
190#define	DAPI	0x04	/* API */
191#define	DPKT	0x08	/* packet handling routine */
192#define	DGEN	0x10	/* generic */
193#define	DDSC	0x20	/* datascope */
194#define	DMEM	0x40	/* memory alloc/release */
195
196#ifdef  DEBUG
197#define	DPRINTF(rcs, d, ARGLIST)	{ if (rcs->debug & d) cmn_err ARGLIST; }
198#define	DATASCOPE(rcs, c, b, l)	{ int i, j; char s[80]; \
199				s[0] = (c); \
200				s[1] = '\0'; \
201				for (i = 1; i < (l)+1; i++) { \
202					j = strlen(s); \
203					(void) sprintf(s+j, "%02x ", \
204						(uchar_t)b[i-1]); \
205					if (i%24 == 0) { \
206						DPRINTF(rcs, DDSC, \
207							(CE_CONT, "%s\n", s)); \
208						s[0] = (c); \
209						s[1] = '\0'; \
210					} \
211				} \
212				if (i%24 != 0) \
213					DPRINTF(rcs, DDSC, \
214							(CE_CONT, "%s\n", s)); \
215				}
216#else
217#define	DPRINTF(rcs, d, ARGLIST)
218#define	DATASCOPE(rcs, c, b, l)
219#endif  /* DEBUG */
220
221
222/*
223 * function prototypes
224 */
225
226int rmc_comm_serdev_init(struct rmc_comm_state *, dev_info_t *);
227void rmc_comm_serdev_fini(struct rmc_comm_state *, dev_info_t *);
228void rmc_comm_serdev_receive(struct rmc_comm_state *);
229void rmc_comm_serdev_send(struct rmc_comm_state *, char *, int);
230void rmc_comm_serdev_drain(struct rmc_comm_state *);
231struct rmc_comm_state *rmc_comm_getstate(dev_info_t *, int, const char *);
232int rmc_comm_register(void);
233void rmc_comm_unregister(void);
234
235void rmc_comm_dp_init(struct rmc_comm_state *);
236void rmc_comm_dp_fini(struct rmc_comm_state *);
237void rmc_comm_dp_drecv(struct rmc_comm_state *, uint8_t *, int);
238void rmc_comm_dp_mrecv(struct rmc_comm_state *, uint8_t *);
239int rmc_comm_dp_msend(struct rmc_comm_state *, dp_message_t *);
240void rmc_comm_bp_msend(struct rmc_comm_state *, bp_msg_t *);
241void rmc_comm_bp_srecsend(struct rmc_comm_state *, char *, int);
242int rmc_comm_dp_ctlsend(struct rmc_comm_state *, uint8_t);
243void rmc_comm_dp_mcleanup(struct rmc_comm_state *);
244
245int rmc_comm_drvintf_init(struct rmc_comm_state *);
246void rmc_comm_drvintf_fini(struct rmc_comm_state *);
247
248#ifdef	__cplusplus
249}
250#endif
251
252#endif	/* _SYS_RMC_COMM_H */
253