summaryrefslogtreecommitdiffstats
path: root/sys/dev/hea/eni.h
blob: ff4a81b0c2c4f92198be7164284999c849a7cd0c (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
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
/*
 *
 * ===================================
 * HARP  |  Host ATM Research Platform
 * ===================================
 *
 *
 * This Host ATM Research Platform ("HARP") file (the "Software") is
 * made available by Network Computing Services, Inc. ("NetworkCS")
 * "AS IS".  NetworkCS does not provide maintenance, improvements or
 * support of any kind.
 *
 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
 * In no event shall NetworkCS be responsible for any damages, including
 * but not limited to consequential damages, arising from or relating to
 * any use of the Software or related support.
 *
 * Copyright 1994-1998 Network Computing Services, Inc.
 *
 * Copies of this Software may be made, however, the above copyright
 * notice must be reproduced on all copies.
 *
 *	@(#) $Id: eni.h,v 1.7 1998/06/29 19:45:14 jpt Exp $
 *
 */

/*
 * Efficient ENI Adapter Support
 *
 * Protocol and implementation definitions
 *
 */

#ifndef	_ENI_ENI_H
#define	_ENI_ENI_H

#include <pci/pcireg.h>
#include <pci/pcivar.h>

/*
 * Physical device name - used to configure HARP devices
 */
#ifndef	ENI_DEV_NAME
#define	ENI_DEV_NAME	"hea"		/* HARP Efficient ATM */
#endif

#define	ENI_MAX_UNITS	4

#define	ENI_IFF_MTU	9188
#define	ENI_MAX_VCI	1023		/* 0 - 1023 */
#define	ENI_MAX_VPI	0

#define	ENI_IFQ_MAXLEN	1000		/* rx/tx queue lengths */

#ifdef	BSD
/*
 * Size of small and large receive buffers
 */
#define	ENI_SMALL_BSIZE		64
#define	ENI_LARGE_BSIZE		MCLBYTES
#endif	/* BSD */

/*
 * ENI memory map offsets IN WORDS, not bytes
 *
 * The Efficient Adapter implements a 4 MB address space. The lower
 * 2 MB are used by bootprom (E)EPROM and by chipset registers such
 * as the MIDWAY and SUNI chips. The (upto) upper 2 MB is used for
 * RAM. Of the RAM, the lower 28 KB is used for fixed tables - the
 * VCI table, the RX and TX DMA queues, and the Service List queue.
 * Memory above the 28 KB range is available for RX and TX buffers.
 *
 * NOTE: Access to anything other then the (E)EPROM MUST be as a 32 bit
 * access. Also note that Efficient uses both byte addresses and word
 * addresses when describing offsets. BE CAREFUL or you'll get confused!
 */
/*
 * Size of memory space reserved for registers and expansion (e)eprom.
 */
#define	ENI_REG_SIZE	0x200000	/* Two megabytes */

#define	SUNI_OFFSET	0x008000	/* SUNI chip registers */
#define	MIDWAY_OFFSET	0x010000	/* MIDWAY chip registers */
#define	RAM_OFFSET	0x080000	/* Adapter RAM */
#define	VCITBL_OFFSET	0x080000	/* VCI Table offset */
#define	RXQUEUE_OFFSET	0x081000	/* RX DMA Queue offset */
#define	TXQUEUE_OFFSET	0x081400	/* TX DMA Queue offset */
#define	SVCLIST_OFFSET	0x081800	/* SVC List Queue offset */

#define	SEGBUF_BASE	0x007000	/* Base from start of RAM */

#define	DMA_LIST_SIZE	512		/* 1024 words / 2 words per entry */
#define	SVC_LIST_SIZE	1024		/* 1024 words / 1 word  per entry */

/*
 * Values for testing size of RAM on adapter
 *
 * Efficient has (at least) two different memory sizes available. One
 * is a client card which has either 128 KB or 512 KB RAM, the other
 * is a server card which has 2 MB RAM. The driver will size and test
 * the memory to correctly determine what's available.
 */
#define	MAX_ENI_MEM	0x200000	/* 2 MB - max. mem supported */
#define	TEST_STEP	0x000400	/* Look at 1 KB steps */
#define	TEST_PAT	0xA5A5A5A5	/* Test pattern */

/*
 * Values for memory allocator
 */
#define	ENI_BUF_PGSZ	1024		/* Allocation unit of buffers */
#define	ENI_BUF_NBIT	8		/* Number of bits to get from */
					/* min buffer (1KB) to max (128KB) */

/*
 * Values for allocating TX buffers
 */
#define	MAX_CLIENT_RAM	512		/* Most RAM a client card will have */
#define	TX_SMALL_BSIZE	32		/* Small buffer - 32KB */
#define	TX_LARGE_BSIZE	128		/* Large buffer - 128KB */

/*
 * Values for allocating RX buffers
 */
#define	RX_SIG_BSIZE	4		/* Signalling buffer - 4KB */
#define	RX_CLIENT_BSIZE	16		/* Client buffer - 16KB */
#define	RX_SERVER_BSIZE	32		/* Server buffer - 32KB */

/*
 * Adapter bases all addresses off of some power from 1KB. Thus, it
 * only needs to store the most sigificant bits and can drop the lower
 * 10 bits.
 */
#define	ENI_LOC_PREDIV	10		/* Bits location is shifted */
					/* Location is prescaled by 1KB */
					/* before use in various places */

#define	MIDWAY_DELAY	10		/* Time to wait for Midway finish */

/*
 * Define the MIDWAY register offsets and any interesting bits within
 * the register
 */
#define	MIDWAY_ID		0x00		/* ID/Reset register */
	#define	MIDWAY_RESET	0		/* iWrite of any value */
	#define	ID_SHIFT	27		/* Midway ID version */
	#define	ID_MASK		0x1F		/* ID mask */
	#define	MID_SHIFT	7		/* Mother board ID */
	#define	MID_MASK	0x7		/* MID mask */
	#define	DID_SHIFT	0		/* Daughter board ID */
	#define	DID_MASK	0x1F		/* DID mask */
	/*
	 * Efficient defines the following IDs for their adapters:
	 * 0x420/0x620 - SONET MMF, client memory size
	 * 0x430/0x630 - SONET MMF, server memory size
	 * 0x424/0x624 - UTP-5, client memory size
	 * 0x434/0x634 - UTP-5, server memory size
	 */
	#define	MEDIA_MASK	0x04		/* Mask off UTP-5/MMF media */

#define	MIDWAY_ISA		0x01		/* Interrupt Status Ack. */
						/* Reading this register */
						/* also acknowledges the */
						/* posted interrupt(s) */

#define	MIDWAY_IS		0x02		/* Interrupt Status */
						/* Reading this register */
						/* does NOT acknowledge the */
						/* posted interrupt(s) */
	/* Interrupt names */
	#define	ENI_INT_STAT		0x00000001
	#define	ENI_INT_SUNI		0x00000002
	#define	ENI_INT_SERVICE		0x00000004
	#define	ENI_INT_TX_DMA		0x00000008
	#define	ENI_INT_RX_DMA		0x00000010
	#define	ENI_INT_DMA_ERR		0x00000020
	#define	ENI_INT_DMA_LERR	0x00000040
	#define	ENI_INT_IDEN		0x00000080
	#define	ENI_INT_DMA_OVFL	0x00000100
	#define	ENI_INT_TX_MASK		0x0001FE00

#define	MIDWAY_IE		0x03		/* Interrupt Enable register */
	/* Interrupt enable bits are the same as the Interrupt names */

#define	MIDWAY_MASTER		0x04		/* Master Control */
	/* Master control bits */
	#define	ENI_M_WAIT500	0x00000001	/* Disable interrupts .5 ms */
	#define	ENI_M_WAIT1	0x00000002	/* Disable interrupts 1 ms */
	#define	ENI_M_RXENABLE	0x00000004	/* Enable RX engine */
	#define	ENI_M_TXENABLE	0x00000008	/* Enable TX engine */
	#define	ENI_M_DMAENABLE	0x00000010	/* Enable DMA */
	#define	ENI_M_TXLOCK	0x00000020	/* 0: Streaming, 1: Lock */
	#define	ENI_M_INTSEL	0x000001C0	/* Int Select mask */
	#define	ENI_ISEL_SHIFT	6		/* Bits to shift ISEL value */

#define	MIDWAY_STAT		0x05		/* Statistics register */

#define	MIDWAY_SVCWR		0x06		/* Svc List write pointer */
	#define	SVC_SIZE_MASK	0x3FF		/* Valid bits in svc pointer */

#define	MIDWAY_DMAADDR		0x07		/* Current virtual DMA addr */

#define	MIDWAY_RX_WR		0x08		/* Write ptr to RX DMA queue */

#define	MIDWAY_RX_RD		0x09		/* Read ptr to RX DMA queue */

#define	MIDWAY_TX_WR		0x0A		/* Write ptr to TX DMA queue */

#define	MIDWAY_TX_RD		0x0B		/* Read ptr to TX DMA queue */

/*
 * Registers 0x0C - 0x0F are unused
 */

/*
 * MIDWAY supports 8 transmit channels. Each channel has 3 registers
 * to control operation. Each new channel starts on N * 4 set. Thus,
 * channel 0 uses register 0x10 - 0x13, channel 1 uses 0x14 - 0x17, etc.
 * Register 0x13 + N * 4 is unused.
 */

#define	MIDWAY_TXPLACE		0x10		/* Channel N TX location */
	#define	TXSIZE_SHIFT	11		/* Bits to shift size by */
	#define	TX_PLACE_MASK	0x7FF		/* Valid bits in TXPLACE */

#define	MIDWAY_RDPTR		0x11		/* Channel N Read ptr */

#define	MIDWAY_DESCR		0x12		/* Channel N Descr ptr */

/*
 * Register 0x30 on up are unused
 */

/*
 * Part of PCI configuration registers but not defined in <pci/pcireg.h>
 */
#define	PCI_CONTROL_REG		0x60
#define	ENDIAN_SWAP_DMA		0x80		/* Enable endian swaps on DMA */

/*
 * The Efficient adapter references adapter RAM through the use of
 * location and size values. Eight sizes are defined. When allocating
 * buffers, there size must be rounded up to the next size which will
 * hold the requested size. Buffers are allocated on 'SIZE' boundaries.
 * See eni_buffer.c for more info.
 */

/*
 * Buffer SIZE definitions - in words, so from 1 KB to 128 KB
 */
#define	SIZE_256	0x00
#define	SIZE_512	0x01
#define	SIZE_1K		0x02
#define	SIZE_2K		0x03
#define	SIZE_4K		0x04
#define	SIZE_8K		0x05
#define	SIZE_16K	0x06
#define	SIZE_32K	0x07

/*
 * Define values for DMA type - DMA descriptors include a type field and a
 * count field except in the special case of JK (just-kidding). With type JK,
 * the count field should be set to the address which will be loaded
 * into the pointer, ie. where the pointer should next point to, since
 * JK doesn't have a "size" associated with it. JK DMA is used to skip
 * over descriptor words, and to strip off padding of AAL5 PDUs. The 
 * DMA_nWORDM types will do a n word DMA burst, but the count field
 * does not have to equal n. Any difference results in garbage filling
 * the remaining words of the DMA. These types could be used where a
 * particular burst size yields better DMA performance.
 */
#define	DMA_WORD	0x00
#define	DMA_BYTE	0x01
#define	DMA_HWORD	0x02
#define	DMA_JK		0x03
#define	DMA_4WORD	0x04
#define	DMA_8WORD	0x05
#define	DMA_16WORD	0x06
#define	DMA_2WORD	0x07
#define	DMA_4WORDM	0x0C
#define	DMA_8WORDM	0x0D
#define	DMA_16WORDM	0x0E
#define	DMA_2WORDM	0x0F

/*
 * Define the size of the local DMA list we'll build before
 * giving up on the PDU.
 */
#define	TEMP_DMA_SIZE	120		/* Enough for 58/59 buffers */

#define	DMA_COUNT_SHIFT	16		/* Number of bits to shift count */
					/* in DMA descriptor word */
#define	DMA_VCC_SHIFT	6		/* Number of bits to shift RX VCC or */
					/* TX channel in DMA descriptor word */
#define	DMA_END_BIT	0x20		/* Signal end of DMA list */

/*
 * Defines for VCI table
 *
 * The VCI table is a 1K by 4 word table allowing up to 1024 (0-1023)
 * VCIs. Entries into the table use the VCI number as the index.
 */
struct vci_table {
	u_long	vci_control;		/* Control word */
	u_long	vci_descr;		/* Descr/ReadPtr */
	u_long	vci_write;		/* WritePtr/State/Cell count */
	u_long	vci_crc;		/* ongoing CRC calculation */
};
typedef volatile struct vci_table VCI_Table;

#define	VCI_MODE_SHIFT	30		/* Shift to get MODE field */
#define	VCI_MODE_MASK	0x3FFFFFFF	/* Bits to strip MODE off */
#define	VCI_PTI_SHIFT	29		/* Shift to get PTI mode field */
#define	VCI_LOC_SHIFT	18		/* Shift to get location field */
#define	VCI_LOC_MASK	0x7FF		/* Valid bits in location field */
#define	VCI_SIZE_SHIFT	15		/* Shift to get size field */
#define	VCI_SIZE_MASK	7		/* Valid bits in size field */
#define	VCI_IN_SERVICE	1		/* Mask for IN_SERVICE field */

/*
 * Defines for VC mode
 */
#define	VCI_MODE_TRASH	0x00		/* Trash all cells for this VC */
#define	VCI_MODE_AAL0	0x01		/* Reassemble as AAL_0 PDU */
#define	VCI_MODE_AAL5	0x02		/* Reassemble as AAL_5 PDU */
/*
 * Defines for handling cells with PTI(2) set to 1.
 */
#define	PTI_MODE_TRASH	0x00		/* Trash cell */
#define	PTI_MODE_PRESV	0x01		/* Send cell to OAM channel */
/*
 * Current state of VC
 */
#define	VCI_STATE_IDLE	0x00		/* VC is idle */
#define	VCI_STATE_REASM	0x01		/* VC is reassembling PDU */
#define	VCI_STATE_TRASH	0x03		/* VC is trashing cells */

/*
 * RX Descriptor word values
 */
#define	DESCR_TRASH_BIT		0x1000	/* VCI was trashing cells */
#define	DESCR_CRC_ERR		0x0800	/* PDU has CRC error */
#define	DESCR_CELL_COUNT	0x07FF	/* Mask to get cell count */
/*
 * TX Descriptor word values
 */
#define	TX_IDEN_SHIFT	28		/* Unique identifier location */
#define	TX_MODE_SHIFT	27		/* AAL5 or AAL0 */
#define	TX_VCI_SHIFT	4		/* Bits to shift VCI value */

/*
 * When setting up descriptor words (at head of segmentation queues), there
 * is a unique identifier used to help detect sync problems.
 */
#define	MIDWAY_UNQ_ID	0x0B

/*
 * Defines for cell sizes
 */
#define	BYTES_PER_CELL	48		/* Number of data bytes per cell */
#define	WORDS_PER_CELL	12		/* Number of data words per cell */

/*
 * Access to Serial EEPROM [as opposed to expansion (E)PROM].
 *
 * This is a ATMEL AT24C01 serial EEPROM part.
 * See http://www.atmel.com/atmel/products/prod162.htm for timimg diagrams
 * for START/STOP/ACK/READ cycles.
 */
#define	SEEPROM		PCI_CONTROL_REG	/* Serial EEPROM is accessed thru */
					/* PCI control register 	  */
#define	SEPROM_DATA	0x02		/* SEEPROM DATA line */
#define	SEPROM_CLK	0x01		/* SEEPROM CLK line */
#define	SEPROM_SIZE	128		/* Size of Serial EEPROM */
#define	SEPROM_MAC_OFF	64		/* Offset to MAC address */
#define	SEPROM_SN_OFF	112		/* Offset to serial number */
#define	SEPROM_DELAY	10		/* Delay when strobing CLK/DATA lines */

/*
 * Host protocol control blocks
 *
 */

/*
 * Device VCC Entry
 *
 * Contains the common and ENI-specific information for each VCC
 * which is opened through a ENI device.
 */
struct eni_vcc {
	struct cmn_vcc	ev_cmn;		/* Common VCC stuff */
	caddr_t		ev_rxbuf;	/* Receive buffer */
	u_long		ev_rxpos;	/* Adapter buffer read pointer */
};
typedef	struct eni_vcc Eni_vcc;

#define	ev_next		ev_cmn.cv_next
#define	ev_toku		ev_cmn.cv_toku
#define	ev_upper	ev_cmn.cv_upper
#define	ev_connvc	ev_cmn.cv_connvc
#define	ev_state	ev_cmn.cv_state

typedef	volatile unsigned long *	Eni_mem;

/*
 * Define the ID's we'll look for in the PCI config
 * register when deciding if we'll support this device.
 * The DEV_ID will need to be turned into an array of
 * ID's in order to support multiple adapters with
 * the same driver.
 */
#define	EFF_VENDOR_ID	0x111A
#define	EFF_DEV_ID	0x0002

/*
 * Memory allocator defines and buffer descriptors
 */
#define	MEM_FREE	0
#define	MEM_INUSE	1

typedef struct mbd Mbd;
struct mbd {
	Mbd	*prev;
	Mbd	*next;
	caddr_t	base;			/* Adapter base address */
	int	size;			/* Size of buffer */
	int	state;			/* INUSE or FREE */
};

/*
 * We use a hack to allocate a smaller RX buffer for signalling
 * channels as they tend to have small MTU lengths.
 */
#define	UNI_SIG_VCI	5

/*
 * Device Unit Structure
 *
 * Contains all the information for a single device (adapter).
 */
struct eni_unit {
	Cmn_unit	eu_cmn;		/* Common unit stuff */
	pcici_t		eu_pcitag;	/* PCI tag */
	Eni_mem 	eu_base;	/* Adapter memory base */
	Eni_mem 	eu_ram;		/* Adapter RAM */
	u_long		eu_ramsize;

	Eni_mem		eu_suni;	/* SUNI registers */

	Eni_mem		eu_midway;	/* MIDWAY registers */

	VCI_Table	*eu_vcitbl;	/* VCI Table */
	Eni_mem		eu_rxdma;	/* Receive DMA queue */
	Eni_mem		eu_txdma;	/* Transmit DMA queue */
	Eni_mem		eu_svclist;	/* Service list */
	u_long		eu_servread;	/* Read pointer into Service list */

	caddr_t		eu_txbuf;	/* One large TX buff for everything */
	u_long		eu_txsize;	/* Size of TX buffer */
	u_long		eu_txpos;	/* Current word being stored in RAM */
	u_long		eu_txfirst;	/* First word of unack'ed data */

	u_long		eu_trash;
	u_long		eu_ovfl;

	struct ifqueue	eu_txqueue;
	u_long		eu_txdmawr;
	struct ifqueue	eu_rxqueue;
	u_long		eu_rxdmawr;	/* DMA list write pointer */

	u_char		eu_seeprom[SEPROM_SIZE]; /* Serial EEPROM contents */
	u_int		eu_sevar;	/* Unique (per unit) seeprom var. */

	Mbd		*eu_memmap;	/* Adapter RAM memory allocator map */
	int		eu_memclicks[ENI_BUF_NBIT];/* Count of INUSE buffers */

	Eni_stats	eu_stats;	/* Statistics */

};
typedef	struct eni_unit		Eni_unit;

#define	eu_pif		eu_cmn.cu_pif
#define	eu_unit		eu_cmn.cu_unit
#define	eu_flags	eu_cmn.cu_flags
#define	eu_mtu		eu_cmn.cu_mtu
#define	eu_open_vcc	eu_cmn.cu_open_vcc
#define	eu_vcc		eu_cmn.cu_vcc
#define	eu_vcc_pool	eu_cmn.cu_vcc_pool
#define	eu_nif_pool	eu_cmn.cu_nif_pool
#define	eu_ioctl	eu_cmn.cu_ioctl
#define	eu_instvcc	eu_cmn.cu_instvcc
#define	eu_openvcc	eu_cmn.cu_openvcc
#define	eu_closevcc	eu_cmn.cu_closevcc
#define	eu_output	eu_cmn.cu_output
#define	eu_config	eu_cmn.cu_config

#endif	/* _ENI_ENI_H */
OpenPOWER on IntegriCloud