|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1990 Microsoft Corporation
4:
5: Module Name:
6:
7: lance.c
8:
9: Abstract:
10:
11: The main program for a LANCE (Local Area Network Controller
12: Am 7990) MAC driver.
13:
14: Author:
15:
16: Anthony V. Ercolano (tonye) creation-date 19-Jun-1990
17:
18: Environment:
19:
20: This driver is expected to work in DOS, OS2 and NT at the equivalent
21: of kernal mode.
22:
23: Architecturally, there is an assumption in this driver that we are
24: on a little endian machine.
25:
26: Notes:
27:
28: optional-notes
29:
30: Revision History:
31:
32: 31-Jul-1992 R.D. Lanser:
33: Removed system implementation dependent defines for the DEC
34: TurboChannel option PMAD-AA (Lance ethernet).
35:
36: --*/
37:
38: #ifndef _LANCEHARDWARE_
39: #define _LANCEHARDWARE_
40:
41: #ifdef NDIS_DOS
42: #define i386 1
43: #endif
44:
45: //
46: // All registers on the LANCE are 16 bits.
47: //
48:
49: #define LANCE_SELECT_CSR0 ((USHORT)0)
50: #define LANCE_SELECT_CSR1 ((USHORT)1)
51: #define LANCE_SELECT_CSR2 ((USHORT)2)
52: #define LANCE_SELECT_CSR3 ((USHORT)3)
53:
54: #define LANCE_CSR0_INITIALIZE ((USHORT)(0x0001))
55: #define LANCE_CSR0_START ((USHORT)(0x0002))
56: #define LANCE_CSR0_STOP ((USHORT)(0x0004))
57: #define LANCE_CSR0_TRANSMIT_DEMAND ((USHORT)(0x0008))
58: #define LANCE_CSR0_TRANSMITTER_ON ((USHORT)(0x0010))
59: #define LANCE_CSR0_RECEIVER_ON ((USHORT)(0x0020))
60: #define LANCE_CSR0_INTERRUPT_ENABLE ((USHORT)(0x0040))
61: #define LANCE_CSR0_INTERRUPT_FLAG ((USHORT)(0x0080))
62: #define LANCE_CSR0_INITIALIZATION_DONE ((USHORT)(0x0100))
63: #define LANCE_CSR0_TRANSMITTER_INTERRUPT ((USHORT)(0x0200))
64: #define LANCE_CSR0_RECEIVER_INTERRUPT ((USHORT)(0x0400))
65: #define LANCE_CSR0_MEMORY_ERROR ((USHORT)(0x0800))
66: #define LANCE_CSR0_MISSED_PACKET ((USHORT)(0x1000))
67: #define LANCE_CSR0_COLLISION_ERROR ((USHORT)(0x2000))
68: #define LANCE_CSR0_BABBLE ((USHORT)(0x4000))
69: #define LANCE_CSR0_ERROR_SUMMARY ((USHORT)(0x8000))
70: #define LANCE_CSR0_ERROR_BITS ((USHORT)(0xf800))
71:
72:
73: //
74: // We define a constant csr3 value that is useful for setting the ACON
75: // bit in csr3.
76: //
77: #define LANCE_CSR3_ACON ((USHORT)0x02)
78:
79:
80: #define LANCE_NICSR_LED_ON ((USHORT)(0x0001))
81: #define LANCE_NICSR_INT_ON ((USHORT)(0x0002))
82: #define LANCE_NICSR_IMASK ((USHORT)(0x0004))
83: #define LANCE_NICSR_128K ((USHORT)(0x0008))
84: #define LANCE_NICSR_BUFFER_SIZE ((USHORT)(0x0020))
85:
86:
87: //
88: // Definitions for the many different lance card types.
89: //
90:
91: #define LANCE_DEPCA_INTERRUPT_VECTOR 5
92: #define LANCE_DEPCA_INTERRUPT_IRQL 5
93:
94: #define LANCE_DE201_INTERRUPT_VECTOR ((CCHAR)5)
95: #define LANCE_DE201_INTERRUPT_IRQL LANCE_DE201_INTERRUPT_VECTOR
96:
97: #define LANCE_DE100_INTERRUPT_VECTOR ((CCHAR)3)
98: #define LANCE_DE100_INTERRUPT_IRQL LANCE_DE100_INTERRUPT_VECTOR
99:
100:
101:
102:
103: #define LANCE_DEPCA_HARDWARE_MEMORY (0x10000) // 64K
104: #define LANCE_DEPCA_BASE ((PVOID)(0xD0000))
105: #define LANCE_DEPCA_RAP_ADDRESS ((ULONG)(0x206))
106: #define LANCE_DEPCA_RDP_ADDRESS ((ULONG)(0x204))
107: #define LANCE_DEPCA_EPROM_ADDRESS ((ULONG)(0x20c))
108: #define LANCE_DEPCA_LAN_CFG_ADDRESS ((ULONG)(0x800))
109: #define LANCE_DEPCA_NICSR_ADDRESS ((ULONG)(0x200))
110:
111: #define LANCE_DE201_HARDWARE_MEMORY (0x10000) // 64K
112: #define LANCE_DE201_BASE ((PVOID)(0xD0000))
113:
114: #define LANCE_DE201_PRI_NICSR_ADDRESS ((ULONG)(0x300))
115: #define LANCE_DE201_PRI_RAP_ADDRESS ((ULONG)(0x306))
116: #define LANCE_DE201_PRI_RDP_ADDRESS ((ULONG)(0x304))
117: #define LANCE_DE201_PRI_NETWORK_ADDRESS ((ULONG)(0x30C))
118:
119: #define LANCE_DE201_SEC_NICSR_ADDRESS ((ULONG)(0x200))
120: #define LANCE_DE201_SEC_RAP_ADDRESS ((ULONG)(0x206))
121: #define LANCE_DE201_SEC_RDP_ADDRESS ((ULONG)(0x204))
122: #define LANCE_DE201_SEC_NETWORK_ADDRESS ((ULONG)(0x20C))
123:
124: #define LANCE_DE422_NICSR_ADDRESS ((ULONG)(0xC00))
125: #define LANCE_DE422_RAP_ADDRESS ((ULONG)(0xC06))
126: #define LANCE_DE422_RDP_ADDRESS ((ULONG)(0xC04))
127: #define LANCE_DE422_NETWORK_ADDRESS ((ULONG)(0xC0C))
128: #define LANCE_DE422_EISA_CONFIGURATION ((ULONG)(0xC0C))
129: #define LANCE_DE422_EXTENDED_MEMORY_BASE_ADDRESS ((ULONG)(0xC08))
130: #define LANCE_DE422_EISA_IDENTIFICATION ((ULONG)(0xC80))
131: #define LANCE_DE422_EISA_CONTROL ((ULONG)(0xC84))
132:
133:
134:
135:
136:
137: #define LANCE_NUMBER_OF_TRANSMIT_RINGS ((UINT)64)
138: #define LANCE_LOG_TRANSMIT_RINGS ((UINT)6)
139:
140: #define LANCE_128K_NUMBER_OF_RECEIVE_RINGS ((UINT)128)
141: #define LANCE_128K_LOG_RECEIVE_RINGS ((UINT)7)
142:
143: #define LANCE_64K_NUMBER_OF_RECEIVE_RINGS ((UINT)128)
144: #define LANCE_64K_LOG_RECEIVE_RINGS ((UINT)7)
145:
146: #define LANCE_32K_NUMBER_OF_RECEIVE_RINGS ((UINT)32)
147: #define LANCE_32K_LOG_RECEIVE_RINGS ((UINT)5)
148:
149: #define LANCE_32K_SIZE_OF_RECEIVE_BUFFERS ((UINT)256)
150: #define LANCE_64K_SIZE_OF_RECEIVE_BUFFERS ((UINT)256)
151: #define LANCE_128K_SIZE_OF_RECEIVE_BUFFERS ((UINT)512)
152:
153: //
154: // Note: The value of LANCE_SIZE_OF_RECEIVE_BUFFERS should always be the
155: // largest of the receive buffers sizes. At this time, it is 512
156: // for the DEC TurboChannel card. If this size changes, recompile
157: // loopback.c.
158: //
159: #define LANCE_SIZE_OF_RECEIVE_BUFFERS ((UINT)256)
160: #ifndef i386
161: #define LANCE_LOOPBACK_SIZE_OF_RECEIVE_BUFFERS ((UINT)512)
162: #else
163: #define LANCE_LOOPBACK_SIZE_OF_RECEIVE_BUFFERS LANCE_SIZE_OF_RECEIVE_BUFFERS
164: #endif
165:
166:
167: #define LANCE_SMALL_BUFFER_SIZE ((UINT)64)
168: #define LANCE_MEDIUM_BUFFER_SIZE ((UINT)256)
169: #define LANCE_LARGE_BUFFER_SIZE ((UINT)1514)
170:
171: #define LANCE_128K_NUMBER_OF_SMALL_BUFFERS ((UINT)100)
172: #define LANCE_128K_NUMBER_OF_MEDIUM_BUFFERS ((UINT)50)
173: #define LANCE_128K_NUMBER_OF_LARGE_BUFFERS ((UINT)20)
174:
175: #define LANCE_64K_NUMBER_OF_SMALL_BUFFERS ((UINT)10)
176: #define LANCE_64K_NUMBER_OF_MEDIUM_BUFFERS ((UINT)10)
177: #define LANCE_64K_NUMBER_OF_LARGE_BUFFERS ((UINT)4)
178:
179: #define LANCE_32K_NUMBER_OF_SMALL_BUFFERS ((UINT)10)
180: #define LANCE_32K_NUMBER_OF_MEDIUM_BUFFERS ((UINT)10)
181: #define LANCE_32K_NUMBER_OF_LARGE_BUFFERS ((UINT)2)
182:
183:
184:
185:
186:
187:
188: #if i386
189:
190: #define LANCE_ISR_WRITE_RAP(A,C) NdisWritePortUshort((A)->NdisAdapterHandle,(ULONG)((A)->RAP),C)
191: #define LANCE_ISR_READ_RDP(A,C) NdisReadPortUshort((A)->NdisAdapterHandle,(ULONG)((A)->RDP),C)
192: #define LANCE_ISR_WRITE_RDP(A,C) NdisWritePortUshort((A)->NdisAdapterHandle,(ULONG)((A)->RDP),C)
193: #define LANCE_ISR_WRITE_NICSR(A,C) NdisWritePortUshort((A)->NdisAdapterHandle,(ULONG)((A)->Nicsr),C)
194:
195:
196: #else
197:
198:
199: #define LANCE_ISR_WRITE_RAP(A,C)\
200: NdisWritePortUshort((A)->NdisAdapterHandle,(ULONG)((A)->RAP),C);
201:
202: #define LANCE_ISR_READ_RDP(A,C)\
203: NdisReadPortUshort((A)->NdisAdapterHandle,(ULONG)((A)->RDP),C);
204:
205: #define LANCE_ISR_WRITE_RDP(A,C)\
206: NdisWritePortUshort((A)->NdisAdapterHandle,(ULONG)((A)->RDP),C);
207:
208: #define LANCE_ISR_WRITE_NICSR(A,C) NdisWritePortUshort((A)->NdisAdapterHandle,(ULONG)((A)->Nicsr),C)
209:
210: #endif
211:
212:
213: #define LANCE_GET_LOW_PART_ADDRESS(Adr) ((USHORT)(Adr & 0xffff))
214: #define LANCE_GET_HIGH_PART_ADDRESS(Adr) ((UCHAR)((Adr & 0xff0000) >> 16))
215:
216: typedef struct _LANCE_INITIALIZATION_BLOCK {
217:
218: USHORT ModeRegister;
219: UCHAR PhysicalAddress[6];
220: UCHAR LogicalAddressFilter[8];
221: USHORT LowReceiveRingAddress;
222: UCHAR HighReceiveRingAddress;
223: UCHAR ReceiveLengthLow5BitsReserved;
224: USHORT LowTransmitRingAddress;
225: UCHAR HighTransmitRingAddress;
226: UCHAR TransmitLengthLow5BitsReserved;
227:
228: } LANCE_INITIALIZATION_BLOCK,*PLANCE_INITIALIZATION_BLOCK;
229:
230: //
231: // Define masks to access bits in the mode register of the initialization
232: // block.
233: //
234: #define LANCE_MODE_PROMISCUOUS ((USHORT)(0x8000))
235:
236: //
237: // Defines for moving to/from shared memory.
238: //
239:
240:
241: #define LANCE_ZERO_MEMORY_FOR_HARDWARE(Destination,Length) \
242: NdisZeroMappedMemory(Destination,Length)
243:
244: #define LANCE_MOVE_STRUCT_TO_HARDWARE(Destination,Source) \
245: NdisMoveToMappedMemory(&(Destination), &(Source), sizeof(Source))
246:
247: #define LANCE_MOVE_MEMORY_TO_HARDWARE(Destination,Source,Length) \
248: NdisMoveToMappedMemory(Destination, Source, Length)
249:
250: #define LANCE_MOVE_HARDWARE_TO_MEMORY(Destination,Source,Length) \
251: NdisMoveFromMappedMemory(Destination, Source, Length)
252:
253: #define LANCE_WRITE_HARDWARE_LOW_PART_ADDRESS(Destination, Source) \
254: NdisWriteRegisterUshort((PUSHORT)(&Destination), (USHORT)(Source))
255:
256: #define LANCE_WRITE_HARDWARE_HIGH_PART_ADDRESS(Destination, Source) \
257: NdisWriteRegisterUchar((PUCHAR)(&Destination), (UCHAR)(Source))
258:
259: #define LANCE_WRITE_HARDWARE_MEMORY_UCHAR(Destination, Source) \
260: NdisWriteRegisterUchar((PUCHAR)(&Destination), (UCHAR)(Source))
261:
262: #define LANCE_WRITE_HARDWARE_MEMORY_USHORT(Destination, Source) \
263: NdisWriteRegisterUshort((PUSHORT)(&Destination), (USHORT)(Source))
264:
265: #define LANCE_READ_HARDWARE_MEMORY_UCHAR(Source, Destination) \
266: NdisReadRegisterUchar((PUCHAR)(&Source), Destination)
267:
268: #define LANCE_READ_HARDWARE_MEMORY_USHORT(Source, Destination) \
269: NdisReadRegisterUshort((PUSHORT)(&Source), Destination)
270:
271: #if defined(_ALPHA_)
272:
273: #define LANCE_SET_RING_BITS(Destination, Data) \
274: { \
275: UCHAR Tmp; \
276: LANCE_READ_HARDWARE_MEMORY_UCHAR(Destination, &Tmp); \
277: LANCE_WRITE_HARDWARE_MEMORY_UCHAR(Destination, Tmp | Data); \
278: }
279:
280: #else
281:
282: #define LANCE_SET_RING_BITS(Destination, Data) (Destination) |= ((Data))
283:
284: #endif // _ALPHA_
285:
286: typedef struct _LANCE_RECEIVE_ENTRY {
287:
288: //
289: // 24 bit pointer to the buffer for the receive
290: // data. This is written by the host and unchanged
291: // by the LANCE.
292: //
293: USHORT LowReceiveBufferAddress;
294: UCHAR HighReceiveBufferAddress;
295:
296: //
297: // This char field contains numerous bits describing
298: // the errors that can occur in the packet as well as
299: // whether this is the first and/or last buffer in the packet.
300: //
301: UCHAR ReceiveSummaryBits;
302:
303: //
304: // This is the twos compliment of the buffer length.
305: //
306: // NOTE: The high order 4 bits must be enabled.
307: //
308: USHORT BufferByteCount;
309:
310: //
311: // This is the length of the data in the packet.
312: //
313: // Note that the high order 4 bits are undefined.
314: //
315: USHORT MessageLength;
316:
317: } LANCE_RECEIVE_ENTRY,*PLANCE_RECEIVE_ENTRY;
318:
319: //
320: // A number of macros that make accessing the various bits of the receive
321: // ring entry a little easier as well as providing some validity checks.
322: //
323:
324: //
325: // Used to set the address of the receive buffer.
326: //
327: // Rd is a pointer to a receive descriptor.
328: //
329: // Adr is a *physical* address.
330: //
331: //
332: #define LANCE_SET_RECEIVE_BUFFER_ADDRESS(Adptr,Rd,Adr) \
333: { \
334: PVOID _Adr = (Adr); \
335: PLANCE_ADAPTER _Adptr = (Adptr);\
336: PLANCE_RECEIVE_ENTRY _Rd = (Rd); \
337: ULONG _Offset;\
338: _Offset = (ULONG)_Adr - (ULONG)(_Adptr->MmMappedBaseAddr);\
339: _Offset = _Offset + (ULONG)(_Adptr->HardwareBaseOffset);\
340: LANCE_WRITE_HARDWARE_LOW_PART_ADDRESS(\
341: _Rd->LowReceiveBufferAddress,\
342: (USHORT)((ULONG)_Offset) & 0xffff); \
343: LANCE_WRITE_HARDWARE_HIGH_PART_ADDRESS(\
344: _Rd->HighReceiveBufferAddress,\
345: (UCHAR)(((ULONG)_Offset) >> 16) & 0xff); \
346: }
347:
348:
349: //
350: // Used to set the length of the receive buffer. The stored value
351: // is actually the twos compliment of the length. Note that
352: // the twos complement of this value must have the high order 4 bits
353: // enabled.
354: //
355: // Rd is a pointer to a receive descriptor.
356: //
357: // Len is the unsigned short length of the buffer.
358: //
359: #define LANCE_SET_RECEIVE_BUFFER_LENGTH(Rd,Len) \
360: LANCE_WRITE_HARDWARE_MEMORY_USHORT(\
361: Rd->BufferByteCount,\
362: (USHORT)((~Len)+1)\
363: )
364:
365: //
366: // Masks for the summary bits in the receive descriptor.
367: //
368: #define LANCE_RECEIVE_END_OF_PACKET ((UCHAR)0x01)
369: #define LANCE_RECEIVE_START_OF_PACKET ((UCHAR)0x02)
370: #define LANCE_RECEIVE_BUFFER_ERROR ((UCHAR)0x04)
371: #define LANCE_RECEIVE_CRC_ERROR ((UCHAR)0x08)
372: #define LANCE_RECEIVE_OVERFLOW_ERROR ((UCHAR)0x10)
373: #define LANCE_RECEIVE_FRAMING_ERROR ((UCHAR)0x20)
374: #define LANCE_RECEIVE_ERROR_SUMMARY ((UCHAR)0x40)
375: #define LANCE_RECEIVE_OWNED_BY_CHIP ((UCHAR)0x80)
376:
377: //
378: // This macro gets the packet message length from what is
379: // assumed to be the last buffer in a packet. Note that
380: // on the lance the length of the data includes the four
381: // byte CRC so we must subtract four from length in the
382: // ring entry.
383: //
384: // Rd is a pointer to a receive descriptor.
385: // Value is the place to store the result.
386: //
387: #if defined(_ALPHA_)
388:
389: #define LANCE_GET_MESSAGE_SIZE(Rd, Value) \
390: { \
391: Value = (READ_REGISTER_USHORT( \
392: ((ULONG)Rd + FIELD_OFFSET(LANCE_RECEIVE_ENTRY, MessageLength)) \
393: ) & ((USHORT)0x0fff)) -4; \
394: }
395:
396:
397: #else
398:
399: #define LANCE_GET_MESSAGE_SIZE(Rd, Value) \
400: Value = (((Rd->MessageLength) & ((USHORT)0x0fff))-4)
401:
402: #endif // _ALPHA_
403:
404: typedef struct _LANCE_TRANSMIT_ENTRY {
405:
406: //
407: // 24 bit pointer to the transmit buffer. This is
408: // written by the host and unchanged by the LANCE.
409: //
410: USHORT LowTransmitBufferAddress;
411: UCHAR HighTransmitBufferAddress;
412:
413: //
414: // This field contains summary information about the packet.
415: //
416: UCHAR TransmitSummaryBits;
417:
418: //
419: // This field contains the "twos complement" of the length
420: // of the buffer.
421: //
422: // NOTE: The high order four bits must be enabled.
423: //
424: USHORT BufferByteCount;
425:
426: //
427: // This short contains the error summary information for the
428: // ring entry.
429: //
430: USHORT ErrorSummaryInfo;
431:
432: } LANCE_TRANSMIT_ENTRY,*PLANCE_TRANSMIT_ENTRY;
433:
434: //
435: // Masks for the normal summary bits in the transmit descriptor.
436: //
437: #define LANCE_TRANSMIT_END_OF_PACKET ((UCHAR)(0x01))
438: #define LANCE_TRANSMIT_START_OF_PACKET ((UCHAR)(0x02))
439: #define LANCE_TRANSMIT_DEFERRED ((UCHAR)(0x04))
440: #define LANCE_TRANSMIT_ONE_RETRY ((UCHAR)(0x08))
441: #define LANCE_TRANSMIT_MORE_THAN_ONE_RETRY ((UCHAR)(0x10))
442: #define LANCE_TRANSMIT_ANY_ERRORS ((UCHAR)(0x40))
443: #define LANCE_TRANSMIT_OWNED_BY_CHIP ((UCHAR)(0x80))
444:
445: //
446: // Set of masks to recover particular errors that a transmit can encounter.
447: //
448: #define LANCE_TRANSMIT_TDR ((USHORT)(0x03ff))
449: #define LANCE_TRANSMIT_RETRY ((USHORT)(0x0400))
450: #define LANCE_TRANSMIT_LOST_CARRIER ((USHORT)(0x0800))
451: #define LANCE_TRANSMIT_LATE_COLLISION ((USHORT)(0x0100))
452: #define LANCE_TRANSMIT_UNDERFLOW ((USHORT)(0x4000))
453: #define LANCE_TRANSMIT_BUFFER ((USHORT)(0x8000))
454:
455: //
456: // Used to set the address of the transmit buffer.
457: //
458: // Rd is a pointer to a transmit descriptor.
459: //
460: // Adr is a *physical* address.
461: //
462: //
463:
464: #define LANCE_SET_TRANSMIT_BUFFER_ADDRESS(Adptr,Td,Adr) \
465: { \
466: PVOID _Adr = (Adr); \
467: PLANCE_TRANSMIT_ENTRY _Td = (Td); \
468: ULONG _Offset;\
469: PLANCE_ADAPTER _Adptr = (Adptr);\
470: _Offset = (ULONG)_Adr - (ULONG)(_Adptr->MmMappedBaseAddr);\
471: _Offset = _Offset + (ULONG)(_Adptr->HardwareBaseOffset);\
472: LANCE_WRITE_HARDWARE_LOW_PART_ADDRESS(\
473: _Td->LowTransmitBufferAddress,\
474: (USHORT)(((ULONG)_Offset) & 0xffff)\
475: );\
476: LANCE_WRITE_HARDWARE_HIGH_PART_ADDRESS(\
477: _Td->HighTransmitBufferAddress,\
478: (UCHAR)((((ULONG)_Offset) >> 16) & 0xff)\
479: );\
480: }
481:
482:
483: //
484: // Used to set the length of the transmit buffer. The stored value
485: // is actually the twos compliment of the length. Note that
486: // the twos complement of this value must have the high order 4 bits
487: // enabled.
488: //
489: // Td is a pointer to a transmit descriptor.
490: //
491: // Len is the unsigned short length of the buffer.
492: //
493: #define LANCE_SET_TRANSMIT_BUFFER_LENGTH(Td,Len) \
494: LANCE_WRITE_HARDWARE_MEMORY_USHORT(\
495: Td->BufferByteCount,\
496: (USHORT)((~Len)+1)\
497: )
498:
499: #endif // _LANCEHARDWARE_
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.