1 /************************************************************************
2  *
3  *	IONSP.H		Definitions for I/O Networks Serial Protocol
4  *
5  *	Copyright (C) 1997-1998 Inside Out Networks, Inc.
6  *
7  *	This program is free software; you can redistribute it and/or modify
8  *	it under the terms of the GNU General Public License as published by
9  *	the Free Software Foundation; either version 2 of the License, or
10  *	(at your option) any later version.
11  *
12  *	These definitions are used by both kernel-mode driver and the
13  *	peripheral firmware and MUST be kept in sync.
14  *
15  ************************************************************************/
16 
17 /************************************************************************
18 
19 The data to and from all ports on the peripheral is multiplexed
20 through a single endpoint pair (EP1 since it supports 64-byte
21 MaxPacketSize). Therefore, the data, commands, and status for
22 each port must be preceeded by a short header identifying the
23 destination port. The header also identifies the bytes that follow
24 as data or as command/status info.
25 
26 Header format, first byte:
27 
28     CLLLLPPP
29     --------
30     | |	 |------ Port Number:	0-7
31     | |--------- Length:	MSB bits of length
32     |----------- Data/Command:	0 = Data header
33 				1 = Cmd / Status (Cmd if OUT, Status if IN)
34 
35 This gives 2 possible formats:
36 
37 
38     Data header:		0LLLLPPP	LLLLLLLL
39     ============
40 
41     Where (LLLL,LLLLLLL) is 12-bit length of data that follows for
42     port number (PPP). The length is 0-based (0-FFF means 0-4095
43     bytes). The ~4K limit allows the host driver (which deals in
44     transfer requests instead of individual packets) to write a
45     large chunk of data in a single request. Note, however, that
46     the length must always be <= the current TxCredits for a given
47     port due to buffering limitations on the peripheral.
48 
49 
50     Cmd/Status header:		1ccccPPP	[ CCCCCCCC,	 Params ]...
51     ==================
52 
53     Where (cccc) or (cccc,CCCCCCCC) is the cmd or status identifier.
54     Frequently-used values are encoded as (cccc), longer ones using
55     (cccc,CCCCCCCC). Subsequent bytes are optional parameters and are
56     specific to the cmd or status code. This may include a length
57     for command and status codes that need variable-length parameters.
58 
59 
60 In addition, we use another interrupt pipe (endpoint) which the host polls
61 periodically for flow control information. The peripheral, when there has
62 been a change, sends the following 10-byte packet:
63 
64 	RRRRRRRRRRRRRRRR
65 	T0T0T0T0T0T0T0T0
66 	T1T1T1T1T1T1T1T1
67 	T2T2T2T2T2T2T2T2
68 	T3T3T3T3T3T3T3T3
69 
70 The first field is the 16-bit RxBytesAvail field, which indicates the
71 number of bytes which may be read by the host from EP1. This is necessary:
72 (a) because OSR2.1 has a bug which causes data loss if the peripheral returns
73 fewer bytes than the host expects to read, and (b) because, on Microsoft
74 platforms at least, an outstanding read posted on EP1 consumes about 35% of
75 the CPU just polling the device for data.
76 
77 The next 4 fields are the 16-bit TxCredits for each port, which indicate how
78 many bytes the host is allowed to send on EP1 for transmit to a given port.
79 After an OPEN_PORT command, the Edgeport sends the initial TxCredits for that
80 port.
81 
82 All 16-bit fields are sent in little-endian (Intel) format.
83 
84 ************************************************************************/
85 
86 //
87 // Define format of InterruptStatus packet returned from the
88 // Interrupt pipe
89 //
90 
91 struct int_status_pkt {
92 	__u16      RxBytesAvail;		    // Additional bytes available to
93 						    // be read from Bulk IN pipe
94 	__u16      TxCredits[ MAX_RS232_PORTS ];   // Additional space available in
95 						    // given port's TxBuffer
96 };
97 
98 
99 #define GET_INT_STATUS_SIZE(NumPorts) (sizeof(__u16) + (sizeof(__u16) * (NumPorts)))
100 
101 
102 
103 //
104 // Define cmd/status header values and macros to extract them.
105 //
106 //	Data:		0LLLLPPP LLLLLLLL
107 //	Cmd/Stat:	1ccccPPP CCCCCCCC
108 
109 #define	IOSP_DATA_HDR_SIZE		2
110 #define	IOSP_CMD_HDR_SIZE		2
111 
112 #define	IOSP_MAX_DATA_LENGTH		0x0FFF		// 12 bits -> 4K
113 
114 #define	IOSP_PORT_MASK			0x07		// Mask to isolate port number
115 #define	IOSP_CMD_STAT_BIT		0x80		// If set, this is command/status header
116 
117 #define IS_CMD_STAT_HDR(Byte1)		((Byte1) & IOSP_CMD_STAT_BIT)
118 #define IS_DATA_HDR(Byte1)		(! IS_CMD_STAT_HDR(Byte1))
119 
120 #define	IOSP_GET_HDR_PORT(Byte1)		((__u8) ((Byte1) & IOSP_PORT_MASK))
121 #define	IOSP_GET_HDR_DATA_LEN(Byte1, Byte2)	((__u16) ( ((__u16)((Byte1) & 0x78)) << 5) | (Byte2))
122 #define	IOSP_GET_STATUS_CODE(Byte1)		((__u8) (((Byte1) &  0x78) >> 3))
123 
124 
125 //
126 // These macros build the 1st and 2nd bytes for a data header
127 //
128 #define	IOSP_BUILD_DATA_HDR1(Port, Len)		((__u8) (((Port) | ((__u8) (((__u16) (Len)) >> 5) & 0x78 ))))
129 #define	IOSP_BUILD_DATA_HDR2(Port, Len)		((__u8) (Len))
130 
131 
132 //
133 // These macros build the 1st and 2nd bytes for a command header
134 //
135 #define	IOSP_BUILD_CMD_HDR1(Port, Cmd)		((__u8) ( IOSP_CMD_STAT_BIT | (Port) |	((__u8) ((Cmd) << 3)) ))
136 
137 
138 //--------------------------------------------------------------
139 //
140 //	Define values for commands and command parameters
141 //	(sent from Host to Edgeport)
142 //
143 //	1ccccPPP P1P1P1P1 [ P2P2P2P2P2 ]...
144 //
145 //	cccc:	00-07	2-byte commands. Write UART register 0-7 with
146 //					value in P1. See 16650.H for definitions of
147 //					UART register numbers and contents.
148 //
149 //		08-0B	3-byte commands:					==== P1 ====	==== P2 ====
150 //					08	available for expansion
151 //					09	1-param commands		Command Code	Param
152 //					0A	available for expansion
153 //					0B	available for expansion
154 //
155 //		0C-0D	4-byte commands.	P1 = extended cmd and P2,P3 = params
156 //						Currently unimplemented.
157 //
158 //		0E-0F	N-byte commands:	P1 = num bytes after P1 (ie, TotalLen - 2)
159 //						P2 = extended cmd, P3..Pn = parameters.
160 //						Currently unimplemented.
161 //
162 
163 #define	IOSP_WRITE_UART_REG(n)	((n) & 0x07)	// UartReg[ n ] := P1
164 
165 // Register numbers and contents
166 // defined in 16554.H.
167 
168 //					0x08		// Available for expansion.
169 #define	IOSP_EXT_CMD			0x09		// P1 = Command code (defined below)
170 
171 // P2 = Parameter
172 
173 //
174 // Extended Command values, used with IOSP_EXT_CMD, may
175 // or may not use parameter P2.
176 //
177 
178 #define	IOSP_CMD_OPEN_PORT		0x00		// Enable ints, init UART. (NO PARAM)
179 #define	IOSP_CMD_CLOSE_PORT		0x01		// Disable ints, flush buffers. (NO PARAM)
180 #define	IOSP_CMD_CHASE_PORT		0x02		// Wait for Edgeport TX buffers to empty. (NO PARAM)
181 #define IOSP_CMD_SET_RX_FLOW		0x03		// Set Rx Flow Control in Edgeport
182 #define IOSP_CMD_SET_TX_FLOW		0x04		// Set Tx Flow Control in Edgeport
183 #define IOSP_CMD_SET_XON_CHAR		0x05		// Set XON Character in Edgeport
184 #define IOSP_CMD_SET_XOFF_CHAR		0x06		// Set XOFF Character in Edgeport
185 #define IOSP_CMD_RX_CHECK_REQ		0x07		// Request Edgeport to insert a Checkpoint into
186 
187 // the receive data stream (Parameter = 1 byte sequence number)
188 
189 #define IOSP_CMD_SET_BREAK		0x08		// Turn on the BREAK (LCR bit 6)
190 #define IOSP_CMD_CLEAR_BREAK		0x09		// Turn off the BREAK (LCR bit 6)
191 
192 
193 //
194 // Define macros to simplify building of IOSP cmds
195 //
196 
197 #define	MAKE_CMD_WRITE_REG(ppBuf, pLen, Port, Reg, Val)						\
198 	do {											\
199 		(*(ppBuf))[0] = IOSP_BUILD_CMD_HDR1( (Port), IOSP_WRITE_UART_REG(Reg) );	\
200 		(*(ppBuf))[1] = (Val);								\
201 												\
202 		*ppBuf += 2;									\
203 		*pLen  += 2;									\
204 	} while (0)
205 
206 #define	MAKE_CMD_EXT_CMD(ppBuf, pLen, Port, ExtCmd, Param)					\
207 	do {											\
208 		(*(ppBuf))[0] = IOSP_BUILD_CMD_HDR1( (Port), IOSP_EXT_CMD );			\
209 		(*(ppBuf))[1] = (ExtCmd);							\
210 		(*(ppBuf))[2] = (Param);							\
211 												\
212 		*ppBuf += 3;									\
213 		*pLen  += 3;									\
214 	} while (0)
215 
216 
217 
218 //--------------------------------------------------------------
219 //
220 //	Define format of flow control commands
221 //	(sent from Host to Edgeport)
222 //
223 //	11001PPP FlowCmd FlowTypes
224 //
225 //	Note that the 'FlowTypes' parameter is a bit mask; that is,
226 //	more than one flow control type can be active at the same time.
227 //	FlowTypes = 0 means 'no flow control'.
228 //
229 
230 //
231 //	IOSP_CMD_SET_RX_FLOW
232 //
233 //	Tells Edgeport how it can stop incoming UART data
234 //
235 //  Example for Port 0
236 //	P0 = 11001000
237 //  P1 = IOSP_CMD_SET_RX_FLOW
238 //  P2 = Bit mask as follows:
239 
240 #define IOSP_RX_FLOW_RTS		0x01	// Edgeport drops RTS to stop incoming data
241 #define IOSP_RX_FLOW_DTR		0x02	// Edgeport drops DTR to stop incoming data
242 #define IOSP_RX_FLOW_DSR_SENSITIVITY	0x04	// Ignores Rx data unless DSR high
243 
244 // Not currently implemented by firmware.
245 #define IOSP_RX_FLOW_XON_XOFF		0x08	// Edgeport sends XOFF char to stop incoming data.
246 
247 // Host must have previously programmed the
248 // XON/XOFF values with SET_XON/SET_XOFF
249 // before enabling this bit.
250 
251 //
252 //	IOSP_CMD_SET_TX_FLOW
253 //
254 //	Tells Edgeport what signal(s) will stop it from transmitting UART data
255 //
256 //  Example for Port 0
257 //	P0 = 11001000
258 //  P1 = IOSP_CMD_SET_TX_FLOW
259 //  P2 = Bit mask as follows:
260 
261 #define IOSP_TX_FLOW_CTS		0x01	// Edgeport stops Tx if CTS low
262 #define IOSP_TX_FLOW_DSR		0x02	// Edgeport stops Tx if DSR low
263 #define IOSP_TX_FLOW_DCD		0x04	// Edgeport stops Tx if DCD low
264 #define IOSP_TX_FLOW_XON_XOFF		0x08	// Edgeport stops Tx upon receiving XOFF char.
265 
266 // Host must have previously programmed the
267 // XON/XOFF values with SET_XON/SET_XOFF
268 // before enabling this bit.
269 #define IOSP_TX_FLOW_XOFF_CONTINUE	0x10	// If not set, Edgeport stops Tx when
270 
271 // sending XOFF in order to fix broken
272 // systems that interpret the next
273 // received char as XON.
274 // If set, Edgeport continues Tx
275 // normally after transmitting XOFF.
276 // Not currently implemented by firmware.
277 #define IOSP_TX_TOGGLE_RTS		0x20	// Edgeport drives RTS as a true half-duplex
278 
279 // Request-to-Send signal: it is raised before
280 // beginning transmission and lowered after
281 // the last Tx char leaves the UART.
282 // Not currently implemented by firmware.
283 
284 //
285 //	IOSP_CMD_SET_XON_CHAR
286 //
287 //	Sets the character which Edgeport transmits/interprets as XON.
288 //	Note: This command MUST be sent before sending a SET_RX_FLOW or
289 //	SET_TX_FLOW with the XON_XOFF bit set.
290 //
291 //  Example for Port 0
292 //	P0 = 11001000
293 //  P1 = IOSP_CMD_SET_XON_CHAR
294 //  P2 = 0x11
295 
296 
297 //
298 //	IOSP_CMD_SET_XOFF_CHAR
299 //
300 //	Sets the character which Edgeport transmits/interprets as XOFF.
301 //	Note: This command must be sent before sending a SET_RX_FLOW or
302 //	SET_TX_FLOW with the XON_XOFF bit set.
303 //
304 //  Example for Port 0
305 //	P0 = 11001000
306 //  P1 = IOSP_CMD_SET_XOFF_CHAR
307 //  P2 = 0x13
308 
309 
310 //
311 //	IOSP_CMD_RX_CHECK_REQ
312 //
313 //  This command is used to assist in the implementation of the
314 //  IOCTL_SERIAL_PURGE Windows IOCTL.
315 //  This IOSP command tries to place a marker at the end of the RX
316 //  queue in the Edgeport. If the Edgeport RX queue is full then
317 //  the Check will be discarded.
318 //  It is up to the device driver to timeout waiting for the
319 //  RX_CHECK_RSP.  If a RX_CHECK_RSP is received, the driver is
320 //	sure that all data has been received from the edgeport and
321 //	may now purge any internal RX buffers.
322 //  Note tat the sequence numbers may be used to detect lost
323 //  CHECK_REQs.
324 
325 //  Example for Port 0
326 //	P0 = 11001000
327 //  P1 = IOSP_CMD_RX_CHECK_REQ
328 //  P2 = Sequence number
329 
330 
331 //  Response will be:
332 //  P1 = IOSP_EXT_RX_CHECK_RSP
333 //  P2 = Request Sequence number
334 
335 
336 
337 //--------------------------------------------------------------
338 //
339 //	Define values for status and status parameters
340 //	(received by Host from Edgeport)
341 //
342 //	1ssssPPP P1P1P1P1 [ P2P2P2P2P2 ]...
343 //
344 // 	ssss:	00-07	2-byte status.	ssss identifies which UART register
345 //					has changed value, and the new value is in P1.
346 //					Note that the ssss values do not correspond to the
347 //					16554 register numbers given in 16554.H. Instead,
348 //					see below for definitions of the ssss numbers
349 //					used in this status message.
350 //
351 //		08-0B	3-byte status:					==== P1 ====	==== P2 ====
352 //					08	LSR_DATA:		New LSR		Errored byte
353 //					09	1-param responses	Response Code	Param
354 //					0A	OPEN_RSP:		InitialMsr	TxBufferSize
355 //					0B	available for expansion
356 //
357 //		0C-0D	4-byte status.	P1 = extended status code and P2,P3 = params
358 //					Not currently implemented.
359 //
360 //		0E-0F	N-byte status:	P1 = num bytes after P1 (ie, TotalLen - 2)
361 //					P2 = extended status, P3..Pn = parameters.
362 //					Not currently implemented.
363 //
364 
365 /****************************************************
366  *	SSSS values for 2-byte status messages (0-8)
367  ****************************************************/
368 
369 #define	IOSP_STATUS_LSR			0x00	// P1 is new value of LSR register.
370 
371 // Bits defined in 16554.H. Edgeport
372 // returns this in order to report
373 // line status errors (overrun,
374 // parity, framing, break). This form
375 // is used when a errored receive data
376 // character was NOT present in the
377 // UART when the LSR error occurred
378 // (ie, when LSR bit 0 = 0).
379 
380 #define	IOSP_STATUS_MSR			0x01	// P1 is new value of MSR register.
381 
382 // Bits defined in 16554.H. Edgeport
383 // returns this in order to report
384 // changes in modem status lines
385 // (CTS, DSR, RI, CD)
386 //
387 
388 //					0x02	// Available for future expansion
389 //					0x03	//
390 //					0x04	//
391 //					0x05	//
392 //					0x06	//
393 //					0x07	//
394 
395 
396 /****************************************************
397  *	SSSS values for 3-byte status messages (8-A)
398  ****************************************************/
399 
400 #define	IOSP_STATUS_LSR_DATA		0x08	// P1 is new value of LSR register (same as STATUS_LSR)
401 
402 // P2 is errored character read from
403 //    RxFIFO after LSR reported an error.
404 
405 #define	IOSP_EXT_STATUS			0x09	// P1 is status/response code, param in P2.
406 
407 
408 // Response Codes (P1 values) for 3-byte status messages
409 
410 #define	IOSP_EXT_STATUS_CHASE_RSP	0	// Reply to CHASE_PORT cmd. P2 is outcome:
411 #define	IOSP_EXT_STATUS_CHASE_PASS	0	// 	P2 = 0: All Tx data drained successfully
412 #define	IOSP_EXT_STATUS_CHASE_FAIL	1	//	P2 = 1: Timed out (stuck due to flow
413 
414 //			control from remote device).
415 
416 #define	IOSP_EXT_STATUS_RX_CHECK_RSP	1	// Reply to RX_CHECK cmd. P2 is sequence number
417 
418 
419 #define IOSP_STATUS_OPEN_RSP		0x0A	// Reply to OPEN_PORT cmd.
420 
421 // P1 is Initial MSR value
422 // P2 is encoded TxBuffer Size:
423 //	TxBufferSize = (P2 + 1) * 64
424 
425 //					0x0B	// Available for future expansion
426 
427 #define GET_TX_BUFFER_SIZE(P2) (((P2) + 1) * 64)
428 
429 
430 
431 
432 /****************************************************
433  *	SSSS values for 4-byte status messages
434  ****************************************************/
435 
436 #define IOSP_EXT4_STATUS		0x0C	// Extended status code in P1,
437 
438 // Params in P2, P3
439 // Currently unimplemented.
440 
441 //					0x0D	// Currently unused, available.
442 
443 
444 
445 //
446 // Macros to parse status messages
447 //
448 
449 #define	IOSP_GET_STATUS_LEN(code)	( (code) < 8 ? 2 : ((code) < 0x0A ? 3 : 4) )
450 
451 #define	IOSP_STATUS_IS_2BYTE(code)	( (code) < 0x08 )
452 #define	IOSP_STATUS_IS_3BYTE(code)	( ((code) >= 0x08) && ((code) <= 0x0B) )
453 #define	IOSP_STATUS_IS_4BYTE(code)	( ((code) >= 0x0C) && ((code) <= 0x0D) )
454 
455