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
500
501
|
/*
*
* ===================================
* 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.
*
* @(#) $FreeBSD$
*
*/
/*
* 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 */
#ifdef COMPAT_OLDPCI
pcici_t eu_pcitag; /* PCI tag */
#endif
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 */
|