|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1990-1992 Microsoft Corporation
4:
5: Module Name:
6:
7: sonicsft.h
8:
9: Abstract:
10:
11: The main header for a SONIC NDIS driver.
12:
13: The overall structure is taken from the Lance driver
14: by Tony Ercolano.
15:
16: Author:
17:
18: Anthony V. Ercolano (tonye) creation-date 19-Jun-1990
19: Adam Barr (adamba) 20-Nov-1990
20:
21: Environment:
22:
23: This driver is expected to work in DOS, OS2 and NT at the equivalent
24: of kernel mode.
25:
26: Architecturally, there is an assumption in this driver that we are
27: on a little endian machine.
28:
29: Revision History:
30:
31:
32: --*/
33:
34: #ifndef _SONICSFT_
35: #define _SONICSFT_
36:
37:
38: //
39: // We use STATIC to define procedures that will be static in the
40: // final build but which we now make extern to allow them to be
41: // debugged (breakpoints can be set on them).
42: //
43:
44: #if DEVL
45: #define STATIC
46: #else
47: #define STATIC static
48: #endif
49:
50:
51: //
52: // This variable is used to control debug output.
53: //
54:
55: #if DBG
56: extern INT SonicDbg;
57: #endif
58:
59:
60:
61: //
62: // Used when registering ourselves with NDIS.
63: //
64:
65: #define SONIC_NDIS_MAJOR_VERSION 3
66: #define SONIC_NDIS_MINOR_VERSION 0
67:
68:
69: //
70: // The maximum number of bytes that we will pass to an NDIS
71: // indication (since we receive packets contiguously, there is
72: // no reason to limit this). This number includes header and
73: // data.
74: //
75:
76: #define SONIC_INDICATE_MAXIMUM 1514
77:
78: //
79: // The maximum number of bytes we will pass to a loopback
80: // indication (unless it all is in one buffer). This number
81: // includes only data, not the header.
82: //
83:
84: #define SONIC_LOOPBACK_MAXIMUM 208
85:
86: //
87: // Used for parsing OIDs
88: //
89:
90: #define OID_TYPE_MASK 0xffff0000
91: #define OID_TYPE_GENERAL_OPERATIONAL 0x00010000
92: #define OID_TYPE_GENERAL_STATISTICS 0x00020000
93: #define OID_TYPE_802_3_OPERATIONAL 0x01010000
94: #define OID_TYPE_802_3_STATISTICS 0x01020000
95:
96: #define OID_REQUIRED_MASK 0x0000ff00
97: #define OID_REQUIRED_MANDATORY 0x00000100
98: #define OID_REQUIRED_OPTIONAL 0x00000200
99:
100: #define OID_INDEX_MASK 0x000000ff
101:
102: //
103: // Indexes in the GeneralMandatory array.
104: //
105:
106: #define GM_TRANSMIT_GOOD 0x00
107: #define GM_RECEIVE_GOOD 0x01
108: #define GM_TRANSMIT_BAD 0x02
109: #define GM_RECEIVE_BAD 0x03
110: #define GM_RECEIVE_NO_BUFFER 0x04
111: #define GM_ARRAY_SIZE 0x05
112:
113: //
114: // Indexes in the GeneralOptional array. There are
115: // two sections, the ones up to COUNT_ARRAY_SIZE
116: // have entries for number (4 bytes) and number of
117: // bytes (8 bytes), the rest are a normal array.
118: //
119:
120: #define GO_DIRECTED_TRANSMITS 0x00
121: #define GO_MULTICAST_TRANSMITS 0x01
122: #define GO_BROADCAST_TRANSMITS 0x02
123: #define GO_DIRECTED_RECEIVES 0x03
124: #define GO_MULTICAST_RECEIVES 0x04
125: #define GO_BROADCAST_RECEIVES 0x05
126: #define GO_COUNT_ARRAY_SIZE 0x06
127:
128: #define GO_ARRAY_START 0x0C
129: #define GO_RECEIVE_CRC 0x0C
130: #define GO_TRANSMIT_QUEUE_LENGTH 0x0D
131: #define GO_ARRAY_SIZE 0x0E
132:
133: //
134: // Indexes in the MediaMandatory array.
135: //
136:
137: #define MM_RECEIVE_ERROR_ALIGNMENT 0x00
138: #define MM_TRANSMIT_ONE_COLLISION 0x01
139: #define MM_TRANSMIT_MORE_COLLISIONS 0x02
140: #define MM_ARRAY_SIZE 0x03
141:
142: //
143: // Indexes in the MediaOptional array.
144: //
145:
146: #define MO_TRANSMIT_DEFERRED 0x00
147: #define MO_TRANSMIT_MAX_COLLISIONS 0x01
148: #define MO_RECEIVE_OVERRUN 0x02
149: #define MO_TRANSMIT_UNDERRUN 0x03
150: #define MO_TRANSMIT_HEARTBEAT_FAILURE 0x04
151: #define MO_TRANSMIT_TIMES_CRS_LOST 0x05
152: #define MO_TRANSMIT_LATE_COLLISIONS 0x06
153: #define MO_ARRAY_SIZE 0x07
154:
155:
156:
157: //
158: // Macros used for memory allocation and deallocation.
159: //
160: // Note that for regular memory we put no limit on the physical
161: // address, but for contiguous and noncached we limit it to
162: // 32 bits since that is all the card can handle (presumably
163: // such memory will be DMAed to/from by the card).
164: //
165:
166: #define SONIC_ALLOC_MEMORY(_Status, _Address, _Length) \
167: { \
168: NDIS_PHYSICAL_ADDRESS Temp = NDIS_PHYSICAL_ADDRESS_CONST(-1, -1); \
169: *(_Status) = NdisAllocateMemory( \
170: (PVOID)(_Address), \
171: (_Length), \
172: 0, \
173: Temp \
174: ); \
175: }
176:
177: #define SONIC_FREE_MEMORY(_Address, _Length) \
178: NdisFreeMemory( \
179: (PVOID)(_Address), \
180: (_Length), \
181: 0 \
182: )
183:
184:
185: #define SONIC_ALLOC_CONTIGUOUS_MEMORY(_Status, _Address, _Length) \
186: { \
187: NDIS_PHYSICAL_ADDRESS Temp = NDIS_PHYSICAL_ADDRESS_CONST(-1, 0); \
188: *(_Status) = NdisAllocateMemory( \
189: (PVOID)(_Address), \
190: (_Length), \
191: NDIS_MEMORY_CONTIGUOUS, \
192: Temp \
193: ); \
194: }
195:
196: #define SONIC_FREE_CONTIGUOUS_MEMORY(_Address, _Length) \
197: NdisFreeMemory( \
198: (PVOID)(_Address), \
199: (_Length), \
200: NDIS_MEMORY_CONTIGUOUS \
201: )
202:
203:
204: #define SONIC_ALLOC_NONCACHED_MEMORY(_Status, _Address, _Length) \
205: { \
206: NDIS_PHYSICAL_ADDRESS Temp = NDIS_PHYSICAL_ADDRESS_CONST(-1, 0); \
207: *(_Status) = NdisAllocateMemory( \
208: (PVOID)(_Address), \
209: (_Length), \
210: NDIS_MEMORY_CONTIGUOUS | NDIS_MEMORY_NONCACHED, \
211: Temp \
212: ); \
213: }
214:
215: #define SONIC_FREE_NONCACHED_MEMORY(_Address, _Length) \
216: NdisFreeMemory( \
217: (PVOID)(_Address), \
218: (_Length), \
219: NDIS_MEMORY_CONTIGUOUS | NDIS_MEMORY_NONCACHED \
220: )
221:
222:
223:
224: //
225: // Macros to move and zero memory.
226: //
227:
228: #define SONIC_MOVE_MEMORY(Destination,Source,Length) NdisMoveMemory(Destination,Source,Length)
229: #define SONIC_ZERO_MEMORY(Destination,Length) NdisZeroMemory(Destination,Length)
230:
231:
232: //
233: // Used to record the 8-byte counters.
234: //
235:
236: typedef struct _SONIC_LARGE_INTEGER {
237: ULONG LowPart;
238: ULONG HighPart;
239: } SONIC_LARGE_INTEGER, *PSONIC_LARGE_INTEGER;
240:
241: //
242: // This initializes an 8-byte counter.
243: //
244:
245: #define SonicZeroLargeInteger(LargeInteger) \
246: { \
247: LargeInteger.LowPart = 0L;\
248: LargeInteger.HighPart = 0L; \
249: }
250:
251: //
252: // This adds a longword to an 8-byte counter.
253: //
254:
255: #define SonicAddUlongToLargeInteger(LargeInteger, Ulong) \
256: { \
257: PSONIC_LARGE_INTEGER TmpLarge = (LargeInteger); \
258: TmpLarge->LowPart += (ULONG)Ulong; \
259: if (TmpLarge->LowPart < (ULONG)Ulong) { \
260: ++TmpLarge->HighPart; \
261: } \
262: }
263:
264:
265:
266: //
267: // This flushes a buffer for write.
268: //
269:
270: #define SONIC_FLUSH_WRITE_BUFFER(Buffer) \
271: NdisFlushBuffer( \
272: Buffer, \
273: TRUE \
274: )
275:
276:
277: //
278: // This record type is used to store sonic global data.
279: // It is used as the MacMacContext in the call to
280: // NdisRegisterMac.
281: //
282:
283: typedef struct _SONIC_MAC {
284:
285: //
286: // The handle returned by NdisInitializeWrapper.
287: //
288:
289: NDIS_HANDLE WrapperHandle;
290:
291: //
292: // The handle returned by NdisRegisterMac.
293: //
294:
295: NDIS_HANDLE MacHandle;
296:
297: } SONIC_MAC, *PSONIC_MAC;
298:
299:
300: //
301: // This identifies the type of the packet for quick reference
302: // in the SONIC_PACKET_RESERVED.PacketType field.
303: //
304:
305: #define SONIC_DIRECTED 1
306: #define SONIC_MULTICAST 2
307: #define SONIC_BROADCAST 3
308: #define SONIC_LOOPBACK 4
309:
310:
311: //
312: // This record type is inserted into the MacReserved portion
313: // of the packet header when the packet is going through the
314: // staged allocation of buffer space prior to the actual send.
315: //
316: typedef struct _SONIC_PACKET_RESERVED {
317:
318: //
319: // Points to the next packet in the chain of queued packets
320: // being allocated, loopbacked, or waiting for the finish
321: // of transmission.
322: //
323: // The packet will either be on the stage list for allocation,
324: // the loopback list for loopback processing, on an adapter
325: // wide doubly linked list (see below) for post transmission
326: // processing.
327: //
328: // We always keep the packet on a list so that in case the
329: // the adapter is closing down or resetting, all the packets
330: // can easily be located and "canceled".
331: //
332: PNDIS_PACKET Next;
333:
334: //
335: // This field holds the binding handle of the open binding
336: // that submitted this packet for send.
337: //
338: NDIS_HANDLE MacBindingHandle;
339:
340: //
341: // The length of the packet.
342: //
343: USHORT PacketLength;
344:
345: //
346: // This identifies the type of the packet.
347: //
348: UCHAR PacketType;
349:
350: //
351: // Was the transmit successful?
352: //
353: BOOLEAN SuccessfulTransmit;
354:
355: //
356: // If TRUE then the packet caused an adapter buffer to
357: // be allocated.
358: //
359: BOOLEAN UsedSonicBuffer;
360:
361: //
362: // If the previous field was TRUE then this gives the
363: // index into the array of adapter buffer descriptors that
364: // contains the old packet information.
365: //
366: UCHAR SonicBuffersIndex;
367:
368: //
369: // Gives the index into the ring to packet structure as well
370: // as the ring descriptors.
371: //
372: USHORT DescriptorIndex;
373:
374: } SONIC_PACKET_RESERVED,*PSONIC_PACKET_RESERVED;
375:
376:
377: //
378: // This macro will return a pointer to the sonic reserved portion
379: // of a packet given a pointer to a packet.
380: //
381: #define PSONIC_RESERVED_FROM_PACKET(Packet) \
382: ((PSONIC_PACKET_RESERVED)((PVOID)((Packet)->MacReserved)))
383:
384:
385:
386: //
387: // This structure is used in the MacReserved field of
388: // an NDIS_REQUEST_BLOCK, passed in during multicast
389: // address/packet filter operations.
390: //
391:
392: typedef struct _SONIC_REQUEST_RESERVED {
393: PNDIS_REQUEST Next;
394: struct _SONIC_OPEN * OpenBlock;
395: } _SONIC_REQUEST_RESERVED, * PSONIC_REQUEST_RESERVED;
396:
397:
398: //
399: // This macro will return a pointer to the sonic reserved portion
400: // of a request given a pointer to the request.
401: //
402: #define PSONIC_RESERVED_FROM_REQUEST(Request) \
403: ((PSONIC_REQUEST_RESERVED)((PVOID)((Request)->MacReserved)))
404:
405:
406:
407: //
408: // The return code from a multicast operation.
409: //
410: typedef enum { CAM_LOADED, CAM_NOT_LOADED } MULTICAST_STATUS;
411:
412:
413: //
414: // This structure is used to map entries in the ring descriptors
415: // back to the packets from which the data in the ring descriptor
416: // originated.
417: //
418:
419: typedef struct _SONIC_DESCRIPTOR_TO_PACKET {
420:
421: //
422: // Points to the packet from which data is being transmitted
423: // through this ring entry.
424: //
425: PNDIS_PACKET OwningPacket;
426:
427: //
428: // Location of our link field.
429: //
430: SONIC_PHYSICAL_ADDRESS * LinkPointer;
431:
432: //
433: // Location of the previous link field.
434: //
435: SONIC_PHYSICAL_ADDRESS * PrevLinkPointer;
436:
437: //
438: // When a packet is submitted to the hardware we record
439: // here whether it used adapter buffers and if so, the buffer
440: // index.
441: //
442: UINT SonicBuffersIndex;
443: BOOLEAN UsedSonicBuffer;
444:
445: } SONIC_DESCRIPTOR_TO_PACKET,*PSONIC_DESCRIPTOR_TO_PACKET;
446:
447:
448: //
449: // If an ndis packet does not meet the hardware contraints then
450: // an adapter buffer will be allocated. Enough data will be copied
451: // out of the ndis packet so that by using a combination of the
452: // adapter buffer and remaining ndis buffers the hardware
453: // constraints are satisfied.
454: //
455: // In the SONIC_ADAPTER structure three threaded lists are kept in
456: // one array. One points to a list of SONIC_BUFFER_DESCRIPTORS
457: // that point to small adapter buffers. Another is for medium sized
458: // buffers and the last for full sized (large) buffers.
459: //
460: // The allocation is controlled via a free list head and
461: // the free lists are "threaded" by a field in the adapter buffer
462: // descriptor.
463: //
464:
465: typedef struct _SONIC_BUFFER_DESCRIPTOR {
466:
467: //
468: // A Physical pointer to a small, medium, or large buffer.
469: //
470: NDIS_PHYSICAL_ADDRESS PhysicalSonicBuffer;
471:
472: //
473: // A virtual pointer to a small, medium, or large buffer.
474: //
475: PVOID VirtualSonicBuffer;
476:
477: //
478: // This is used to flush the buffer when it is used.
479: //
480: PNDIS_BUFFER FlushBuffer;
481:
482: //
483: // Threads the elements of an array of these descriptors into
484: // a free list. -1 implies no more entries in the list.
485: //
486: INT Next;
487:
488: //
489: // Holds the length of data placed into the buffer. This
490: // can (and likely will) be less that the actual buffers
491: // length.
492: //
493: UINT DataLength;
494:
495: } SONIC_BUFFER_DESCRIPTOR,*PSONIC_BUFFER_DESCRIPTOR;
496:
497:
498: //
499: // This is the basic structure that defines the state of an
500: // adapter. There is one of these allocate per adapter that
501: // the sonic driver supports.
502: //
503:
504: typedef struct _SONIC_ADAPTER {
505:
506: //
507: // Will be true the first time that the hardware is initialized
508: // by the driver initialization.
509: //
510: BOOLEAN FirstInitialization;
511:
512: //
513: // TRUE if RemoveAdapter has been called or if Shutdown is in progress.
514: //
515: BOOLEAN Removed;
516:
517: //
518: // The type of the adapter; current supported values are:
519: //
520: // 1: EISA 9010E/B card from National Semiconductor
521: // 2: Sonic chip on the MIPS R4000 motherbaord.
522: //
523: UCHAR AdapterType;
524:
525: //
526: // TRUE if the permanent address is valid. On some cards the
527: // permanent address is read by SonicHardwareGetDetails;
528: // if not, it is read later by SonicHardwareGetAddress.
529: //
530: BOOLEAN PermanentAddressValid;
531:
532: //
533: // The burned-in network address from the hardware.
534: //
535: CHAR PermanentNetworkAddress[ETH_LENGTH_OF_ADDRESS];
536:
537: //
538: // The current network address from the hardware.
539: //
540: CHAR CurrentNetworkAddress[ETH_LENGTH_OF_ADDRESS];
541:
542: //
543: // This is the buffer pool used to allocate flush buffers
544: // out of.
545: //
546: NDIS_HANDLE FlushBufferPoolHandle;
547:
548: //
549: // These are boolean, used as a gate to ensure that only one thread
550: // of execution is actually processing the specified source of
551: // deferred processing.
552: //
553:
554: BOOLEAN ProcessingReceiveInterrupt;
555: BOOLEAN ProcessingGeneralInterrupt;
556: BOOLEAN ProcessingDeferredOperations;
557:
558: //
559: // Used to queue deferred operations.
560: //
561: NDIS_TIMER DeferredTimer;
562:
563: //
564: // Holds the interrupt object for this adapter.
565: //
566: NDIS_INTERRUPT Interrupt;
567:
568: //
569: // TRUE if the adapter is latched, FALSE for level-sensitive.
570: //
571: BOOLEAN InterruptLatched;
572:
573: // The following fields are accessed by the ISR and must be aligned to the
574: // minimum granularity of the architecture on which it runs
575:
576: #if defined(_ALPHA_)
577:
578: union {
579: UQUAD _ForceQuadwordAlignment;
580: struct {
581:
582: #endif // defined(_ALPHA_)
583:
584: //
585: // Holds a value of the ISR from one or more interrupts.
586: // This value is only set by the interrupt service routine
587: // and cleared by the interrupt synchronization routine.
588: //
589: USHORT IsrValue;
590:
591: //
592: // The current value to put in the Interrupt Mask Register.
593: //
594: USHORT InterruptMaskRegister;
595:
596: #if defined(_ALPHA_)
597:
598: };
599: };
600:
601: #endif // defined(_ALPHA_)
602:
603: //
604: // The current value to put in the Receive Control Register.
605: //
606: USHORT ReceiveControlRegister;
607:
608: //
609: // The value that the Data Configuration Register should be
610: // initialized to.
611: //
612: USHORT DataConfigurationRegister;
613:
614: //
615: // Have we receive an unacknowledged Receive Buffers
616: // Exhausted interrupt.
617: //
618: BOOLEAN ReceiveBuffersExhausted;
619:
620: //
621: // Have we receive an unacknowledged Receive Descriptors
622: // Exhausted interrupt.
623: //
624: BOOLEAN ReceiveDescriptorsExhausted;
625:
626: //
627: // Location of the beginning of the SONIC ports.
628: //
629: ULONG SonicPortAddress;
630:
631: //
632: // The number of bits that port numbers need to be shifted left
633: // before adding them to PortAddress (1 for 16-bit ports, 2
634: // for 32-bit ports).
635: //
636: UINT PortShift;
637:
638: //
639: // The virtual address of the blank buffer used for padding.
640: //
641: PUCHAR BlankBuffer;
642:
643: //
644: // The Physical address of the blank buffer used for padding.
645: //
646: NDIS_PHYSICAL_ADDRESS BlankBufferAddress;
647:
648: //
649: // Keeps a reference count on the current number of uses of
650: // this adapter block. Uses is defined to be the number of
651: // routines currently within the "external" interface.
652: //
653: UINT References;
654:
655: //
656: // List head for all open bindings for this adapter.
657: //
658: LIST_ENTRY OpenBindings;
659:
660: //
661: // Number of open bindings.
662: //
663: UINT OpenCount;
664:
665: //
666: // List head for all opens that had outstanding references
667: // when an attempt was made to close them.
668: //
669: LIST_ENTRY CloseList;
670:
671: //
672: // Spinlock to protect fields in this structure..
673: //
674: NDIS_SPIN_LOCK Lock;
675:
676: //
677: // Handle given by NDIS when the adapter was registered.
678: //
679: NDIS_HANDLE NdisAdapterHandle;
680:
681: //
682: // Pointer to the filter database for the MAC.
683: //
684: PETH_FILTER FilterDB;
685:
686: //
687: // The head of the request queue for this adapter.
688: //
689: PNDIS_REQUEST FirstRequest;
690:
691: //
692: // The tail of the request queue for this adapter.
693: //
694: PNDIS_REQUEST LastRequest;
695:
696: //
697: // The current packet filter.
698: //
699: UINT CurrentPacketFilter;
700:
701: //
702: // The value of the bits in CamEnable, except for
703: // the first one (which is for our network address);
704: // as opposed to the value stored in the real CamEnable,
705: // which may have some bits off if multicast addresses
706: // are not included in the current packet filter.
707: //
708: UINT MulticastCamEnableBits;
709:
710: //
711: // The number of transmit descriptors.
712: //
713: UINT NumberOfTransmitDescriptors;
714:
715: //
716: // The number of receive buffers
717: //
718: UINT NumberOfReceiveBuffers;
719:
720: //
721: // The number of receive descriptors
722: //
723: UINT NumberOfReceiveDescriptors;
724:
725: //
726: // Pointer to the transmit descriptors (this is
727: // allocated to be of size NumberOfTransmitDescriptors).
728: //
729: PSONIC_TRANSMIT_DESCRIPTOR TransmitDescriptorArea;
730:
731: //
732: // The physical address of the transmit descriptor area.
733: //
734: NDIS_PHYSICAL_ADDRESS TransmitDescriptorAreaPhysical;
735:
736: //
737: // Pointer to the last transmit descriptor.
738: //
739: PSONIC_TRANSMIT_DESCRIPTOR LastTransmitDescriptor;
740:
741: //
742: // Counter that records the number of transmit rings currently
743: // available for allocation.
744: //
745: UINT NumberOfAvailableDescriptors;
746:
747: //
748: // This is used to determine whether to use the programmable
749: // interrupt on a packet or not.
750: //
751: UINT PacketsSinceLastInterrupt;
752:
753: //
754: // Pointer to transmit descriptor ring entry that is the
755: // first ring entry available for allocation of transmit
756: // buffers.
757: //
758: // Can only be accessed when the adapter lock
759: // is held.
760: //
761: PSONIC_TRANSMIT_DESCRIPTOR AllocateableDescriptor;
762:
763: //
764: // Pointer to a transmit descriptor ring entry that is the
765: // first ring entry that the MAC currently has made available
766: // for transmission.
767: //
768: // Can only be accessed when the adapter lock
769: // is held.
770: //
771: PSONIC_TRANSMIT_DESCRIPTOR TransmittingDescriptor;
772:
773: //
774: // Pointer to the first packet that has been allocated to
775: // a transmit packet but has not yet been relinquished to
776: // the hardware. We need this pointer to keep the transmit
777: // post processing from running into a packet that has not
778: // been transmitted.
779: //
780: PSONIC_TRANSMIT_DESCRIPTOR FirstUncommittedDescriptor;
781:
782: //
783: // Pointer to an array of structs that map transmit ring entries
784: // back to a packet (this is allocated to be of size
785: // NumberOfTransmitDescriptors).
786: //
787: PSONIC_DESCRIPTOR_TO_PACKET DescriptorToPacket;
788:
789: //
790: // Pointer to the receive resource area (this is
791: // allocated to be of size NumberofReceiveBuffers).
792: //
793: PSONIC_RECEIVE_RESOURCE ReceiveResourceArea;
794:
795: //
796: // The physical address of ReceiveResourceArea.
797: //
798: NDIS_PHYSICAL_ADDRESS ReceiveResourceAreaPhysical;
799:
800: //
801: // Pointer to the array holding the receive buffers (this
802: // is allocated to be of size NumberofReceiveBuffers).
803: //
804: PVOID * ReceiveBufferArea;
805:
806: //
807: // The RBA which we are currently taking packets out of
808: // (will be one of the entries in the ReceiveBufferArea
809: // array).
810: //
811: UINT CurrentReceiveBufferIndex;
812:
813: //
814: // Pointer to the receive descriptor area
815: // (this is allocated to be of size NumberOfReceiveDescriptors).
816: //
817: PSONIC_RECEIVE_DESCRIPTOR ReceiveDescriptorArea;
818:
819: //
820: // The physical address of ReceiveDescriptorArea
821: //
822: NDIS_PHYSICAL_ADDRESS ReceiveDescriptorAreaPhysical;
823:
824: //
825: // The last receive descriptor in the area.
826: //
827: PSONIC_RECEIVE_DESCRIPTOR LastReceiveDescriptor;
828:
829: //
830: // The index receive descriptor we should look at next (will be
831: // one of the entries in ReceiveDescriptorArea).
832: //
833: UINT CurrentReceiveDescriptorIndex;
834:
835: //
836: // Pointer to the CAM descriptor area. This will be
837: // located directly after the receive resource area,
838: // the separate pointer is for convenience.
839: //
840: PSONIC_CAM_DESCRIPTOR_AREA CamDescriptorArea;
841:
842: //
843: // The physical address corresponding to CamDescriptorArea.
844: // This is stored as a 4-byte address since it is just
845: // a fixed offset from ReceiveResourceAreaPhysical and
846: // is not allocated with NdisAllocateSharedMemory.
847: //
848: SONIC_PHYSICAL_ADDRESS CamDescriptorAreaPhysical;
849:
850: //
851: // This is used to flush the CAM descriptor area.
852: //
853: PNDIS_BUFFER CamDescriptorAreaFlushBuffer;
854:
855: //
856: // The last entry in the CAM that is used.
857: //
858: UINT CamDescriptorAreaSize;
859:
860: //
861: // An bitmask showing which entries in the CAM are
862: // used or reserved for use.
863: //
864: UINT CamDescriptorsUsed;
865:
866: //
867: // Pointer to the first packet on the loopback list.
868: //
869: // Can only be accessed when the adapter lock
870: // is held.
871: //
872: PNDIS_PACKET FirstLoopBack;
873:
874: //
875: // Pointer to the last packet on the loopback list.
876: //
877: // Can only be accessed when the adapter lock
878: // is held.
879: //
880: PNDIS_PACKET LastLoopBack;
881:
882: //
883: // non-zero if an indication is for a loopback packet.
884: //
885: PNDIS_PACKET CurrentLoopbackPacket;
886:
887: //
888: // Pointer to the first transmitting packet that is actually
889: // sending, or done with the living on the loopback queue.
890: //
891: // Can only be accessed when the adapter lock
892: // is held.
893: //
894: PNDIS_PACKET FirstFinishTransmit;
895:
896: //
897: // Pointer to the last transmitting packet that is actually
898: // sending, or done with the living on the loopback queue.
899: //
900: // Can only be accessed when the adapter lock
901: // is held.
902: //
903: PNDIS_PACKET LastFinishTransmit;
904:
905: //
906: // Listheads for the adapters buffers. If the list
907: // head is equal to -1 then there are no free elements
908: // on the list.
909: //
910: // The list heads must only be accessed when the
911: // adapter lock is held.
912: //
913: // Note that the listhead at index 0 will always be -1.
914: //
915: INT SonicBufferListHeads[4];
916:
917: //
918: // Pointers to an array of adapter buffer descriptors.
919: // The array will actually be threaded together by
920: // three free lists. The lists will be for small,
921: // medium and full sized packets.
922: //
923: PSONIC_BUFFER_DESCRIPTOR SonicBuffers;
924:
925: //
926: // This holds the actual memory used by the small
927: // sonic buffers (so that it can be a single piece
928: // of memory and therefore only use a single physical
929: // address.
930: //
931: PVOID SmallSonicBuffers;
932:
933: //
934: // This holds the memory for the medium sonic buffers.
935: //
936: PVOID MediumSonicBuffers;
937:
938: //
939: // Holds the open that queued a reset.
940: //
941: struct _SONIC_OPEN * ResettingOpen;
942:
943: //
944: // Flag that when enabled lets routines know that a reset
945: // is in progress, for the purposes of blocking other
946: // requests (except other resets).
947: //
948: BOOLEAN ResetInProgress;
949:
950: //
951: // Flag the lets us know that we are indicating RESET_START
952: // to all the protocols. During this time we can reject
953: // NdisReset requests with the status RESET_IN_PROGRESS.
954: //
955: BOOLEAN IndicatingResetStart;
956:
957: //
958: // Flag that says that we are indicating RESET_END to all
959: // the protocols. If this is set when a reset comes in, then
960: // we cannot indicating RESET_START right away; the thread
961: // indicating RESET_END will indicate the RESET_START if
962: // it fines that BlockResets has come on while it was
963: // indicating RESET_END.
964: //
965: BOOLEAN IndicatingResetEnd;
966:
967: //
968: // TRUE if a request is being processed.
969: //
970: BOOLEAN RequestInProgress;
971:
972: //
973: // This field lets the send allocation code know that it's
974: // futile to even try to move a packet along to that stage.
975: //
976: // The stage will be closed to close a binding
977: // or to reset the adapter.
978: //
979: // This variable can only be accessed when the adapter
980: // lock is held.
981: //
982: BOOLEAN SendStageOpen;
983:
984: //
985: // The AlreadyProcessingSendStage variable are set up to keep
986: // more than one thread from accessing a particular send
987: // a one time.
988: //
989: // This variable can only be accessed when the adapter
990: // lock is held.
991: //
992: BOOLEAN AlreadyProcessingSendStage;
993:
994: //
995: // Pointers to the first and last packets that are waiting to
996: // be sent. All packets in transmit are linked
997: // via there next field.
998: //
999: // Can only be accessed when the adapter lock
1000: // is held.
1001: //
1002: PNDIS_PACKET FirstSendStagePacket;
1003: PNDIS_PACKET LastSendStagePacket;
1004:
1005: //
1006: // These hold adapter statistics.
1007: //
1008: ULONG GeneralMandatory[GM_ARRAY_SIZE];
1009: SONIC_LARGE_INTEGER GeneralOptionalByteCount[GO_COUNT_ARRAY_SIZE];
1010: ULONG GeneralOptionalFrameCount[GO_COUNT_ARRAY_SIZE];
1011: ULONG GeneralOptional[GO_ARRAY_SIZE - GO_ARRAY_START];
1012: ULONG MediaMandatory[MM_ARRAY_SIZE];
1013: ULONG MediaOptional[MO_ARRAY_SIZE];
1014:
1015: //
1016: // For handling missing interrupts (caused by user mis-configs)
1017: //
1018:
1019: PVOID WakeUpDpc;
1020: NDIS_TIMER WakeUpTimer;
1021: BOOLEAN WakeUpTimeout;
1022:
1023: //
1024: // Count how often we log an error from finding a packet in
1025: // the wrong RBA.
1026: //
1027:
1028: USHORT WrongRbaErrorLogCount;
1029:
1030: //
1031: // For indicating loopback packets.
1032: //
1033:
1034: UCHAR Loopback[SONIC_LOOPBACK_MAXIMUM];
1035:
1036: } SONIC_ADAPTER,*PSONIC_ADAPTER;
1037:
1038:
1039: //
1040: // Given a MacBindingHandle this macro returns a pointer to the
1041: // SONIC_ADAPTER.
1042: //
1043:
1044: #define PSONIC_ADAPTER_FROM_BINDING_HANDLE(Handle) \
1045: (((PSONIC_OPEN)((PVOID)(Handle)))->OwningSonic)
1046:
1047:
1048: //
1049: // Given a MacContextHandle return the PSONIC_ADAPTER
1050: // it represents.
1051: //
1052:
1053: #define PSONIC_ADAPTER_FROM_CONTEXT_HANDLE(Handle) \
1054: ((PSONIC_ADAPTER)((PVOID)(Handle)))
1055:
1056:
1057:
1058: //
1059: // One of these structures is created on each MacOpenAdapter.
1060: //
1061:
1062: typedef struct _SONIC_OPEN {
1063:
1064: //
1065: // Linking structure for all of the open bindings of a particular
1066: // adapter.
1067: //
1068: LIST_ENTRY OpenList;
1069:
1070: //
1071: // The Adapter that requested this open binding.
1072: //
1073: PSONIC_ADAPTER OwningSonic;
1074:
1075: //
1076: // Handle of this adapter in the filter database.
1077: //
1078: NDIS_HANDLE NdisFilterHandle;
1079:
1080: //
1081: // Given by NDIS when the adapter was opened.
1082: //
1083: NDIS_HANDLE NdisBindingContext;
1084:
1085: //
1086: // Counter of all the different reasons that a open binding
1087: // couldn't be closed. This would be incremented each time
1088: // for:
1089: //
1090: // While a particular interface routine is accessing this open
1091: //
1092: // During an indication.
1093: //
1094: // When the open causes a reset.
1095: //
1096: // A packet currently being sent.
1097: //
1098: // (Basically the above two mean any time the open has left
1099: // some processing around to be accomplished later.)
1100: //
1101: // This field should only be accessed when the adapter lock is held.
1102: //
1103: UINT References;
1104:
1105: //
1106: // A request that we use to queue the open or close request on
1107: // the adapter's queue.
1108: //
1109: NDIS_REQUEST OpenCloseRequest;
1110:
1111: //
1112: // A flag indicating that this binding is in the process of closing.
1113: //
1114: BOOLEAN BindingShuttingDown;
1115:
1116: } SONIC_OPEN,*PSONIC_OPEN;
1117:
1118:
1119: //
1120: // This macro returns a pointer to a PSONIC_OPEN given a MacBindingHandle.
1121: //
1122:
1123: #define PSONIC_OPEN_FROM_BINDING_HANDLE(Handle) \
1124: ((PSONIC_OPEN)((PVOID)Handle))
1125:
1126:
1127: //
1128: // This macro returns a NDIS_HANDLE from a PSONIC_OPEN
1129: //
1130:
1131: #define BINDING_HANDLE_FROM_PSONIC_OPEN(Open) \
1132: ((NDIS_HANDLE)((PVOID)Open))
1133:
1134:
1135: //
1136: // procedures which do error logging
1137: //
1138:
1139: typedef enum _SONIC_PROC_ID{
1140: registerAdapter,
1141: openAdapter,
1142: hardwareDetails,
1143: handleDeferred,
1144: processReceiveInterrupts
1145: } SONIC_PROC_ID;
1146:
1147:
1148: //
1149: // Error log values
1150: //
1151:
1152: #define SONIC_ERRMSG_INIT_INTERRUPT (ULONG)0x01
1153: #define SONIC_ERRMSG_CREATE_FILTER (ULONG)0x02
1154: #define SONIC_ERRMSG_ALLOC_MEMORY (ULONG)0x03
1155: #define SONIC_ERRMSG_REGISTER_ADAPTER (ULONG)0x04
1156: #define SONIC_ERRMSG_ALLOC_DEVICE_NAME (ULONG)0x05
1157: #define SONIC_ERRMSG_ALLOC_ADAPTER (ULONG)0x06
1158: #define SONIC_ERRMSG_INITIAL_INIT (ULONG)0x07
1159: #define SONIC_ERRMSG_OPEN_DB (ULONG)0x08
1160: #define SONIC_ERRMSG_ALLOC_OPEN (ULONG)0x09
1161: #define SONIC_ERRMSG_HARDWARE_ADDRESS (ULONG)0x0A
1162: #define SONIC_ERRMSG_WRONG_RBA (ULONG)0x0B
1163:
1164:
1165:
1166: //
1167: // This macro will act a "epilogue" to every routine in the
1168: // *interface*. It will check whether there any requests needed
1169: // to defer there processing. It will also decrement the reference
1170: // count on the adapter. If the reference count is zero and there
1171: // is deferred work to do it will insert the interrupt processing
1172: // routine in the DPC queue.
1173: //
1174: // Note that we don't need to include checking for blocked receives
1175: // since blocked receives imply that there will eventually be an
1176: // interrupt.
1177: //
1178: // NOTE: This macro assumes that it is called with the lock acquired.
1179: //
1180:
1181: #define SONIC_DO_DEFERRED(Adapter) \
1182: { \
1183: PSONIC_ADAPTER _A = (Adapter); \
1184: if ((!_A->ProcessingDeferredOperations) && \
1185: (((_A->References == 2) && \
1186: _A->ResetInProgress) || \
1187: _A->FirstLoopBack || \
1188: (!IsListEmpty(&_A->CloseList)))) { \
1189: _A->ProcessingDeferredOperations = TRUE; \
1190: NdisReleaseSpinLock(&_A->Lock); \
1191: NdisSetTimer(&_A->DeferredTimer,0); \
1192: } else { \
1193: _A->References--; \
1194: NdisReleaseSpinLock(&_A->Lock); \
1195: } \
1196: }
1197:
1198:
1199:
1200: //
1201: // Definitions of sonic functions which are used by multiple
1202: // source files.
1203: //
1204:
1205:
1206: //
1207: // alloc.c
1208: //
1209:
1210: extern
1211: BOOLEAN
1212: AllocateAdapterMemory(
1213: IN PSONIC_ADAPTER Adapter
1214: );
1215:
1216: extern
1217: VOID
1218: DeleteAdapterMemory(
1219: IN PSONIC_ADAPTER Adapter
1220: );
1221:
1222:
1223: //
1224: // interrup.c
1225: //
1226:
1227: extern
1228: VOID
1229: SonicDeferredProcessing(
1230: IN PVOID SystemSpecific1,
1231: IN PVOID Context,
1232: IN PVOID SystemSpecific2,
1233: IN PVOID SystemSpecific3
1234: );
1235:
1236: extern
1237: BOOLEAN
1238: SonicInterruptService(
1239: IN PVOID Context
1240: );
1241:
1242: extern
1243: VOID
1244: SonicTimerProcess(
1245: IN PVOID SystemSpecific1,
1246: IN PVOID Context,
1247: IN PVOID SystemSpecific2,
1248: IN PVOID SystemSpecific3
1249: );
1250:
1251: VOID
1252: SonicWakeUpDpc(
1253: IN PVOID SystemSpecific1,
1254: IN PVOID Context,
1255: IN PVOID SystemSpecific2,
1256: IN PVOID SystemSpecific3
1257: );
1258:
1259: //
1260: // loopback.c
1261: //
1262:
1263: extern
1264: VOID
1265: SonicProcessLoopback(
1266: IN PSONIC_ADAPTER Adapter
1267: );
1268:
1269: extern
1270: VOID
1271: SonicPutPacketOnLoopBack(
1272: IN PSONIC_ADAPTER Adapter,
1273: IN PNDIS_PACKET Packet,
1274: IN BOOLEAN SuccessfulTransmit
1275: );
1276:
1277: //
1278: // packet.c
1279: //
1280:
1281: extern
1282: VOID
1283: SonicCopyFromPacketToBuffer(
1284: IN PNDIS_PACKET Packet,
1285: IN UINT Offset,
1286: IN UINT BytesToCopy,
1287: OUT PCHAR Buffer,
1288: OUT PUINT BytesCopied
1289: );
1290:
1291: extern
1292: VOID
1293: SonicCopyFromBufferToPacket(
1294: IN PCHAR Buffer,
1295: IN UINT BytesToCopy,
1296: IN PNDIS_PACKET Packet,
1297: IN UINT Offset,
1298: OUT PUINT BytesCopied
1299: );
1300:
1301: extern
1302: VOID
1303: SonicCopyFromPacketToPacket(
1304: IN PNDIS_PACKET Destination,
1305: IN UINT DestinationOffset,
1306: IN UINT BytesToCopy,
1307: IN PNDIS_PACKET Source,
1308: IN UINT SourceOffset,
1309: OUT PUINT BytesCopied
1310: );
1311:
1312:
1313: //
1314: // request.c
1315: //
1316:
1317: extern
1318: NDIS_STATUS
1319: SonicRequest(
1320: IN NDIS_HANDLE MacBindingHandle,
1321: IN PNDIS_REQUEST NdisRequest
1322: );
1323:
1324: extern
1325: NDIS_STATUS
1326: SonicQueryGlobalStatistics(
1327: IN NDIS_HANDLE MacAdapterContext,
1328: IN PNDIS_REQUEST NdisRequest
1329: );
1330:
1331: extern
1332: VOID
1333: SonicQueueRequest(
1334: IN PSONIC_ADAPTER Adapter,
1335: IN PNDIS_REQUEST NdisRequest
1336: );
1337:
1338: extern
1339: VOID
1340: SonicProcessRequestQueue(
1341: IN PSONIC_ADAPTER Adapter
1342: );
1343:
1344: extern
1345: NDIS_STATUS
1346: SonicChangeClass(
1347: IN UINT OldFilterClasses,
1348: IN UINT NewFilterClasses,
1349: IN NDIS_HANDLE NdisBindingContext,
1350: IN PNDIS_REQUEST NdisRequest,
1351: IN BOOLEAN Set
1352: );
1353:
1354: extern
1355: NDIS_STATUS
1356: SonicChangeAddresses(
1357: IN UINT OldAddressCount,
1358: IN CHAR OldAddresses[][ETH_LENGTH_OF_ADDRESS],
1359: IN UINT NewAddressCount,
1360: IN CHAR NewAddresses[][ETH_LENGTH_OF_ADDRESS],
1361: IN NDIS_HANDLE MacBindingHandle,
1362: IN PNDIS_REQUEST NdisRequest,
1363: IN BOOLEAN Set
1364: );
1365:
1366: extern
1367: VOID
1368: SonicCloseAction(
1369: IN NDIS_HANDLE MacBindingHandle
1370: );
1371:
1372:
1373: //
1374: // send.c
1375: //
1376:
1377: extern
1378: NDIS_STATUS
1379: SonicSend(
1380: IN NDIS_HANDLE MacBindingHandle,
1381: IN PNDIS_PACKET Packet
1382: );
1383:
1384:
1385: extern
1386: VOID
1387: SonicStagedAllocation(
1388: IN PSONIC_ADAPTER Adapter
1389: );
1390:
1391:
1392: //
1393: // sonic.c
1394: //
1395:
1396: extern
1397: VOID
1398: SonicStartChip(
1399: IN PSONIC_ADAPTER Adapter
1400: );
1401:
1402: extern
1403: VOID
1404: StartAdapterReset(
1405: IN PSONIC_ADAPTER Adapter
1406: );
1407:
1408: extern
1409: VOID
1410: SetupForReset(
1411: IN PSONIC_ADAPTER Adapter,
1412: IN PSONIC_OPEN Open
1413: );
1414:
1415: extern
1416: VOID
1417: SonicStartCamReload(
1418: IN PSONIC_ADAPTER Adapter
1419: );
1420:
1421:
1422: //
1423: // transfer.c
1424: //
1425:
1426: extern
1427: NDIS_STATUS
1428: SonicTransferData(
1429: IN NDIS_HANDLE MacBindingHandle,
1430: IN NDIS_HANDLE MacReceiveContext,
1431: IN UINT ByteOffset,
1432: IN UINT BytesToTransfer,
1433: OUT PNDIS_PACKET Packet,
1434: OUT PUINT BytesTransferred
1435: );
1436:
1437: #endif // _SONICSFT_
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.