2 * Copyright (c) 1993,1994
3 * Texas A&M University. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Texas A&M University
16 * and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * David K. Hess, Douglas Lee Schales, David R. Safford
36 * Heavily modified for Metaware HighC + GNU C 2.8+
50 #include "msdos/ndis2.h"
52 #if defined(USE_NDIS2)
55 * Packet buffer handling
57 extern int FreePktBuf (PktBuf
*buf
);
58 extern int EnquePktBuf (PktBuf
*buf
);
59 extern PktBuf
* AllocPktBuf (void);
64 #define MAX_NUM_DEBUG_STRINGS 90
65 #define DEBUG_STRING_LENGTH 80
66 #define STACK_POOL_SIZE 6
67 #define STACK_SIZE 256
70 #define MEDIA_ETHERNET 2
73 static int startDebug
= 0;
74 static int stopDebug
= 0;
76 static DWORD droppedPackets
= 0L;
77 static WORD frameSize
= 0;
78 static WORD headerSize
= 0;
79 static int mediaType
= 0;
80 static char *lastErr
= NULL
;
82 static BYTE debugStrings
[MAX_NUM_DEBUG_STRINGS
][DEBUG_STRING_LENGTH
];
83 static BYTE
*freeStacks
[STACK_POOL_SIZE
];
84 static int freeStackPtr
= STACK_POOL_SIZE
- 1;
86 static ProtMan protManEntry
= NULL
;
87 static WORD protManDS
= 0;
88 static volatile int xmitPending
;
90 static struct _PktBuf
*txBufPending
;
91 static struct _CardHandle
*handle
;
92 static struct _CommonChars common
;
93 static struct _ProtocolChars protChars
;
94 static struct _ProtDispatch lowerTable
;
96 static struct _FailingModules failingModules
;
97 static struct _BindingsList bindings
;
105 "The function completed successfully.\n" },
107 { ERR_WAIT_FOR_RELEASE
,
108 "The ReceiveChain completed successfully but the protocol has\n"
109 "retained control of the buffer.\n" },
111 { ERR_REQUEST_QUEUED
,
112 "The current request has been queued.\n" },
114 { ERR_FRAME_NOT_RECOGNIZED
,
115 "Frame not recognized.\n" },
117 { ERR_FRAME_REJECTED
,
118 "Frame was discarded.\n" },
121 "Protocol wishes to forward frame to another protocol.\n" },
123 { ERR_OUT_OF_RESOURCE
,
124 "Out of resource.\n" },
126 { ERR_INVALID_PARAMETER
,
127 "Invalid parameter.\n" },
129 { ERR_INVALID_FUNCTION
,
130 "Invalid function.\n" },
133 "Not supported.\n" },
135 { ERR_HARDWARE_ERROR
,
136 "Hardware error.\n" },
138 { ERR_TRANSMIT_ERROR
,
139 "The packet was not transmitted due to an error.\n" },
141 { ERR_NO_SUCH_DESTINATION
,
142 "Token ring packet was not recognized when transmitted.\n" },
144 { ERR_BUFFER_TOO_SMALL
,
145 "Provided buffer was too small.\n" },
147 { ERR_ALREADY_STARTED
,
148 "Network drivers already started.\n" },
150 { ERR_INCOMPLETE_BINDING
,
151 "Protocol driver could not complete its bindings.\n" },
153 { ERR_DRIVER_NOT_INITIALIZED
,
154 "MAC did not initialize properly.\n" },
156 { ERR_HARDWARE_NOT_FOUND
,
157 "Hardware not found.\n" },
159 { ERR_HARDWARE_FAILURE
,
160 "Hardware failure.\n" },
162 { ERR_CONFIGURATION_FAILURE
,
163 "Configuration failure.\n" },
165 { ERR_INTERRUPT_CONFLICT
,
166 "Interrupt conflict.\n" },
168 { ERR_INCOMPATIBLE_MAC
,
169 "The MAC is not compatible with the protocol.\n" },
171 { ERR_INITIALIZATION_FAILED
,
172 "Initialization failed.\n" },
175 "Binding did not occur.\n" },
177 { ERR_NETWORK_MAY_NOT_BE_CONNECTED
,
178 "The network may not be connected to the adapter.\n" },
180 { ERR_INCOMPATIBLE_OS_VERSION
,
181 "The version of the operating system is incompatible with the protocol.\n" },
183 { ERR_ALREADY_REGISTERED
,
184 "The protocol is already registered.\n" },
186 { ERR_PATH_NOT_FOUND
,
187 "PROTMAN.EXE could not be found.\n" },
189 { ERR_INSUFFICIENT_MEMORY
,
190 "Insufficient memory.\n" },
192 { ERR_INFO_NOT_FOUND
,
193 "Protocol Mananger info structure is lost or corrupted.\n" },
195 { ERR_GENERAL_FAILURE
,
196 "General failure.\n" }
202 #define PERROR(str) printf("%s (%d): %s\n", __FILE__,__LINE__,str)
203 #define DEBUG_RING() (debugStrings[stopDebug+1 == MAX_NUM_DEBUG_STRINGS ? \
204 stopDebug = 0 : ++stopDebug])
207 * needs rewrite for DOSX
209 #define MAC_DISPATCH(hnd) ((struct _MacUpperDispatch*)(hnd)->common->upperDispatchTable)
210 #define MAC_STATUS(hnd) ((struct _MacStatusTable*) (hnd)->common->serviceStatus)
211 #define MAC_CHAR(hnd) ((struct _MacChars*) (hnd)->common->serviceChars)
214 #define DEBUG0(str) printf (str)
215 #define DEBUG1(fmt,a) printf (fmt,a)
216 #define DEBUG2(fmt,a,b) printf (fmt,a,b)
217 #define TRACE0(str) sprintf (DEBUG_RING(),str)
218 #define TRACE1(fmt,a) sprintf (DEBUG_RING(),fmt,a)
220 #define DEBUG0(str) ((void)0)
221 #define DEBUG1(fmt,a) ((void)0)
222 #define DEBUG2(fmt,a,b) ((void)0)
223 #define TRACE0(str) ((void)0)
224 #define TRACE1(fmt,a) ((void)0)
228 * This routine is called from both threads
230 void NdisFreeStack (BYTE
*aStack
)
234 if (freeStackPtr
== STACK_POOL_SIZE
- 1)
235 PERROR ("tried to free too many stacks");
237 freeStacks
[++freeStackPtr
] = aStack
;
239 if (freeStackPtr
== 0)
240 TRACE0 ("freeStackPtr went positive\n");
246 * This routine is called from callbacks to allocate local data
248 BYTE
*NdisAllocStack (void)
254 if (freeStackPtr
< 0)
256 /* Ran out of stack buffers. Return NULL which will start
259 TRACE0 ("freeStackPtr went negative\n");
263 stack
= freeStacks
[freeStackPtr
--];
269 CALLBACK (NdisSystemRequest (DWORD param1
, DWORD param2
, WORD param3
,
270 WORD opcode
, WORD targetDS
))
272 static int bindEntry
= 0;
273 struct _CommonChars
*macCommon
;
274 volatile WORD result
;
278 case REQ_INITIATE_BIND
:
279 macCommon
= (struct _CommonChars
*) param2
;
280 if (macCommon
== NULL
)
282 printf ("There is an NDIS misconfiguration.\n");
283 result
= ERR_GENERAL_FAILURE
;
286 DEBUG2 ("module name %s\n"
288 macCommon
->moduleName
,
289 ((MacChars
*) macCommon
->serviceChars
)->macName
);
291 /* Binding to the MAC */
292 result
= macCommon
->systemRequest ((DWORD
)&common
, (DWORD
)&macCommon
,
294 macCommon
->moduleDS
);
296 if (!strcmp(bindings
.moduleName
[bindEntry
], handle
->moduleName
))
297 handle
->common
= macCommon
;
298 else PERROR ("unknown module");
302 case REQ_INITIATE_UNBIND
:
303 macCommon
= (struct _CommonChars
*) param2
;
304 result
= macCommon
->systemRequest ((DWORD
)&common
, 0,
306 macCommon
->moduleDS
);
310 result
= ERR_GENERAL_FAILURE
;
319 CALLBACK (NdisRequestConfirm (WORD protId
, WORD macId
, WORD reqHandle
,
320 WORD status
, WORD request
, WORD protDS
))
322 ARGSUSED (protId
); ARGSUSED (macId
);
323 ARGSUSED (reqHandle
); ARGSUSED (status
);
324 ARGSUSED (request
); ARGSUSED (protDS
);
325 return (ERR_SUCCESS
);
328 CALLBACK (NdisTransmitConfirm (WORD protId
, WORD macId
, WORD reqHandle
,
329 WORD status
, WORD protDS
))
332 FreePktBuf (txBufPending
); /* Add passed ECB back to the free list */
334 ARGSUSED (reqHandle
);
337 return (ERR_SUCCESS
);
342 * The primary function for receiving packets
344 CALLBACK (NdisReceiveLookahead (WORD macId
, WORD frameSize
,
345 WORD bytesAvail
, BYTE
*buffer
,
346 BYTE
*indicate
, WORD protDS
))
351 struct _TDBufDescr tDBufDescr
;
354 TRACE1 ("lookahead length = %d, ", bytesAvail
);
355 TRACE1 ("ecb = %08lX, ", *ecb
);
356 TRACE1 ("count = %08lX\n", count
);
357 TRACE1 ("offset = %08lX, ", offset
);
358 TRACE1 ("timesAllowed = %d, ", timesAllowed
);
359 TRACE1 ("packet size = %d\n", look
->dataLookAheadLen
);
362 /* Allocate a buffer for the packet
364 if ((pktBuf
= AllocPktBuf()) == NULL
)
367 return (ERR_FRAME_REJECTED
);
371 * Now kludge things. Note we will have to undo this later. This will
372 * make the packet contiguous after the MLID has done the requested copy.
375 tDBufDescr
.tDDataCount
= 1;
376 tDBufDescr
.tDBufDescrRec
[0].tDPtrType
= NDIS_PTR_PHYSICAL
;
377 tDBufDescr
.tDBufDescrRec
[0].tDDataPtr
= pktBuf
->buffer
;
378 tDBufDescr
.tDBufDescrRec
[0].tDDataLen
= pktBuf
->length
;
379 tDBufDescr
.tDBufDescrRec
[0].dummy
= 0;
381 result
= MAC_DISPATCH(handle
)->transferData (&bytesCopied
, 0, &tDBufDescr
,
382 handle
->common
->moduleDS
);
383 pktBuf
->packetLength
= bytesCopied
;
385 if (result
== ERR_SUCCESS
)
387 else FreePktBuf (pktBuf
);
389 ARGSUSED (frameSize
);
390 ARGSUSED (bytesAvail
);
394 return (ERR_SUCCESS
);
397 CALLBACK (NdisIndicationComplete (WORD macId
, WORD protDS
))
402 /* We don't give a hoot about these. Just return
404 return (ERR_SUCCESS
);
408 * This is the OTHER way we may receive packets
410 CALLBACK (NdisReceiveChain (WORD macId
, WORD frameSize
, WORD reqHandle
,
411 struct _RxBufDescr
*rxBufDescr
,
412 BYTE
*indicate
, WORD protDS
))
414 struct _PktBuf
*pktBuf
;
418 * For now we copy the entire packet over to a PktBuf structure. This may be
419 * a performance hit but this routine probably isn't called very much, and
420 * it is a lot of work to do it otherwise. Also if it is a filter protocol
421 * packet we could end up sucking up MAC buffes.
424 if ((pktBuf
= AllocPktBuf()) == NULL
)
427 return (ERR_FRAME_REJECTED
);
429 pktBuf
->packetLength
= 0;
431 /* Copy the packet to the buffer
433 for (i
= 0; i
< rxBufDescr
->rxDataCount
; ++i
)
435 struct _RxBufDescrRec
*rxDescr
= &rxBufDescr
->rxBufDescrRec
[i
];
437 memcpy (pktBuf
->buffer
+ pktBuf
->packetLength
,
438 rxDescr
->rxDataPtr
, rxDescr
->rxDataLen
);
439 pktBuf
->packetLength
+= rxDescr
->rxDataLen
;
442 EnquePktBuf (pktBuf
);
444 ARGSUSED (frameSize
);
445 ARGSUSED (reqHandle
);
449 /* This frees up the buffer for the MAC to use
451 return (ERR_SUCCESS
);
454 CALLBACK (NdisStatusProc (WORD macId
, WORD param1
, BYTE
*indicate
,
455 WORD opcode
, WORD protDS
))
459 case STATUS_RING_STATUS
:
461 case STATUS_ADAPTER_CHECK
:
463 case STATUS_START_RESET
:
465 case STATUS_INTERRUPT
:
467 case STATUS_END_RESET
:
478 /* We don't need to do anything about this stuff yet
480 return (ERR_SUCCESS
);
484 * Tell the NDIS driver to start the delivery of the packet
486 int NdisSendPacket (struct _PktBuf
*pktBuf
, int macId
)
488 struct _TxBufDescr txBufDescr
;
492 txBufPending
= pktBuf
; /* we only have 1 pending Tx at a time */
494 txBufDescr
.txImmedLen
= 0;
495 txBufDescr
.txImmedPtr
= NULL
;
496 txBufDescr
.txDataCount
= 1;
497 txBufDescr
.txBufDescrRec
[0].txPtrType
= NDIS_PTR_PHYSICAL
;
498 txBufDescr
.txBufDescrRec
[0].dummy
= 0;
499 txBufDescr
.txBufDescrRec
[0].txDataLen
= pktBuf
->packetLength
;
500 txBufDescr
.txBufDescrRec
[0].txDataPtr
= pktBuf
->buffer
;
502 result
= MAC_DISPATCH(handle
)->transmitChain (common
.moduleId
,
505 handle
->common
->moduleDS
);
508 case ERR_OUT_OF_RESOURCE
:
509 /* Note that this should not happen but if it does there is not
510 * much we can do about it
512 printf ("ERROR: transmit queue overflowed\n");
516 /* Everything was hunky dory and synchronous. Free up the
523 case ERR_REQUEST_QUEUED
:
524 /* Everything was hunky dory and asynchronous. Do nothing
529 printf ("Tx fail, code = %04X\n", result
);
536 static int ndis_nerr
= sizeof(ndis_errlist
) / sizeof(ndis_errlist
[0]);
538 static char *Ndis_strerror (WORD errorCode
)
543 for (i
= 0; i
< ndis_nerr
; i
++)
544 if (errorCode
== ndis_errlist
[i
].err_num
)
545 return (ndis_errlist
[i
].err_text
);
547 sprintf (buf
,"unknown error %d",errorCode
);
552 char *NdisLastError (void)
554 char *errStr
= lastErr
;
561 struct _ReqBlock reqBlock
;
563 int ndisFd
= open (NDIS_PATH
, O_RDONLY
);
567 printf ("Could not open NDIS Protocol Manager device.\n");
571 memset (&reqBlock
, 0, sizeof(ReqBlock
));
573 reqBlock
.opcode
= PM_GET_PROTOCOL_MANAGER_LINKAGE
;
575 result
= NdisGetLinkage (ndisFd
, (char*)&reqBlock
, sizeof(ReqBlock
));
578 printf ("Could not get Protocol Manager linkage.\n");
584 protManEntry
= (ProtMan
) reqBlock
.pointer1
;
585 protManDS
= reqBlock
.word1
;
587 DEBUG2 ("Entry Point = %04X:%04X\n", FP_SEG(protManEntry
),FP_OFF(protManEntry
));
588 DEBUG1 ("ProtMan DS = %04X\n", protManDS
);
593 int NdisRegisterAndBind (int promis
)
595 struct _ReqBlock reqBlock
;
598 memset (&common
,0,sizeof(common
));
600 common
.tableSize
= sizeof (common
);
602 common
.majorNdisVersion
= 2;
603 common
.minorNdisVersion
= 0;
604 common
.majorModuleVersion
= 2;
605 common
.minorModuleVersion
= 0;
607 /* Indicates binding from below and dynamically loaded
609 common
.moduleFlags
= 0x00000006L
;
611 strcpy (common
.moduleName
, "PCAP");
613 common
.protocolLevelUpper
= 0xFF;
614 common
.protocolLevelLower
= 1;
615 common
.interfaceLower
= 1;
617 common
.moduleDS
= _dos_ds
; /* the callback data segment */
619 common
.moduleDS
= _DS
;
622 common
.systemRequest
= (SystemRequest
) systemRequestGlue
;
623 common
.serviceChars
= (BYTE
*) &protChars
;
624 common
.serviceStatus
= NULL
;
625 common
.upperDispatchTable
= NULL
;
626 common
.lowerDispatchTable
= (BYTE
*) &lowerTable
;
628 protChars
.length
= sizeof (protChars
);
629 protChars
.name
[0] = 0;
632 lowerTable
.backPointer
= &common
;
633 lowerTable
.requestConfirm
= requestConfirmGlue
;
634 lowerTable
.transmitConfirm
= transmitConfirmGlue
;
635 lowerTable
.receiveLookahead
= receiveLookaheadGlue
;
636 lowerTable
.indicationComplete
= indicationCompleteGlue
;
637 lowerTable
.receiveChain
= receiveChainGlue
;
638 lowerTable
.status
= statusGlue
;
639 lowerTable
.flags
= 3;
641 lowerTable
.flags
|= 4; /* promiscous mode (receive everything) */
643 bindings
.numBindings
= 1;
644 strcpy (bindings
.moduleName
[0], handle
->moduleName
);
646 /* Register ourselves with NDIS
648 reqBlock
.opcode
= PM_REGISTER_MODULE
;
649 reqBlock
.pointer1
= (BYTE FAR
*) &common
;
650 reqBlock
.pointer2
= (BYTE FAR
*) &bindings
;
652 result
= (*protManEntry
) (&reqBlock
, protManDS
);
655 printf ("Protman registering failed: %s\n", Ndis_strerror(result
));
659 /* Start the binding process
661 reqBlock
.opcode
= PM_BIND_AND_START
;
662 reqBlock
.pointer1
= (BYTE FAR
*) &failingModules
;
664 result
= (*protManEntry
) (&reqBlock
, protManDS
);
667 printf ("Start binding failed: %s\n", Ndis_strerror(result
));
673 static int CheckMacFeatures (CardHandle
*card
)
676 BYTE _far
*mediaString
;
679 DEBUG2 ("checking card features\n"
680 "common table address = %08lX, macId = %d\n",
681 card
->common
, card
->common
->moduleId
);
683 serviceFlags
= MAC_CHAR (handle
)->serviceFlags
;
685 if ((serviceFlags
& SF_PROMISCUOUS
) == 0)
687 printf ("The MAC %s does not support promiscuous mode.\n",
692 mediaString
= MAC_CHAR (handle
)->macName
;
694 DEBUG1 ("media type = %s\n",mediaString
);
696 /* Get the media type. And set the header size
698 if (!strncmp(mediaString
,"802.3",5) ||
699 !strncmp(mediaString
,"DIX",3) ||
700 !strncmp(mediaString
,"DIX+802.3",9))
701 headerSize
= sizeof (EthernetIIHeader
);
703 else if (!strncmp(mediaString
,"FDDI",4))
704 headerSize
= sizeof (FddiHeader
) +
705 sizeof (Ieee802Dot2SnapHeader
);
708 printf ("Unsupported MAC type: `%s'\n", mediaString
);
712 frameSize
= MAC_CHAR (handle
)->maxFrameSize
;
713 mac_addr
= MAC_CHAR (handle
)->currentAddress
;
715 printf ("Hardware address: %02X:%02X:%02X:%02X:%02X:%02X\n",
716 mac_addr
[0], mac_addr
[1], mac_addr
[2],
717 mac_addr
[3], mac_addr
[4], mac_addr
[5]);
721 static int NdisStartMac (CardHandle
*card
)
725 /* Set the lookahead length
727 result
= MAC_DISPATCH(handle
)->request (common
.moduleId
, 0,
730 card
->common
->moduleDS
);
732 /* We assume that if we got INVALID PARAMETER then either this
733 * is not supported or will work anyway. NE2000 does this.
735 if (result
!= ERR_SUCCESS
&& result
!= ERR_INVALID_PARAMETER
)
737 DEBUG1 ("Set lookahead failed: %s\n", Ndis_strerror(result
));
741 /* Set the packet filter. Note that for some medias and drivers we
742 * must specify all three flags or the card(s) will not operate correctly.
744 result
= MAC_DISPATCH(handle
)->request (common
.moduleId
, 0,
745 /* all packets */ FILTER_PROMISCUOUS
|
746 /* packets to us */ FILTER_DIRECTED
|
747 /* broadcasts */ FILTER_BROADCAST
,
748 0, REQ_SET_PACKET_FILTER
,
749 card
->common
->moduleDS
);
750 if (result
!= ERR_SUCCESS
)
752 DEBUG1 ("Set packet filter failed: %s\n", Ndis_strerror(result
));
756 /* If OPEN/CLOSE supported then open the adapter
758 if (MAC_CHAR(handle
)->serviceFlags
& SF_OPEN_CLOSE
)
760 result
= MAC_DISPATCH(handle
)->request (common
.moduleId
, 0, 0, NULL
,
762 card
->common
->moduleDS
);
763 if (result
!= ERR_SUCCESS
)
765 DEBUG1 ("Opening the MAC failed: %s\n", Ndis_strerror(result
));
772 void NdisShutdown (void)
774 struct _ReqBlock reqBlock
;
780 /* If the adapters support open and are open then close them
782 if ((MAC_CHAR(handle
)->serviceFlags
& SF_OPEN_CLOSE
) &&
783 (MAC_STATUS(handle
)->macStatus
& MAC_OPEN
))
785 result
= MAC_DISPATCH(handle
)->request (common
.moduleId
, 0, 0, 0,
787 handle
->common
->moduleDS
);
788 if (result
!= ERR_SUCCESS
)
790 printf ("Closing the MAC failed: %s\n", Ndis_strerror(result
));
795 /* Tell the Protocol Manager to unbind and stop
797 reqBlock
.opcode
= PM_UNBIND_AND_STOP
;
798 reqBlock
.pointer1
= (BYTE FAR
*) &failingModules
;
799 reqBlock
.pointer2
= NULL
;
801 result
= (*protManEntry
) (&reqBlock
, protManDS
);
803 printf ("Unbind failed: %s\n", Ndis_strerror(result
));
805 for (i
= 0; i
< STACK_POOL_SIZE
; ++i
)
806 free (freeStacks
[i
] - STACK_SIZE
);
811 int NdisInit (int promis
)
815 /* Allocate the real mode stacks used for NDIS callbacks
817 for (i
= 0; i
< STACK_POOL_SIZE
; ++i
)
819 freeStacks
[i
] = malloc (STACK_SIZE
);
822 freeStacks
[i
] += STACK_SIZE
;
828 if (!NdisRegisterAndBind(promis
))
831 DEBUG1 ("My module id: %d\n", common
.moduleId
);
832 DEBUG1 ("Handle id; %d\n", handle
->common
->moduleId
);
833 DEBUG1 ("MAC card: %-16s - ", handle
->moduleName
);
835 atexit (NdisShutdown
);
837 if (!CheckMacFeatures(&handle
))
843 DEBUG0 ("Media type: FDDI");
846 DEBUG0 ("Media type: ETHERNET");
849 DEBUG0 ("Unsupported media.\n");
853 DEBUG1 (" - Frame size: %d\n", frameSize
);
855 if (!NdisStartMac(&handle
))
859 #endif /* USE_NDIS2 */