2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Novell Eagle 2000 driver
5 * PURPOSE: Driver entry point
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 27/08-2000 Created
16 PDRIVER_OBJECT DriverObject
,
17 PUNICODE_STRING RegistryPath
);
22 /* See debug.h for debug/trace constants */
23 ULONG DebugTraceLevel
= 0;
28 /* List of supported OIDs */
29 static ULONG MiniportOIDList
[] = {
30 OID_GEN_SUPPORTED_LIST
,
31 OID_GEN_HARDWARE_STATUS
,
32 OID_GEN_MEDIA_SUPPORTED
,
34 OID_GEN_MAXIMUM_LOOKAHEAD
,
35 OID_GEN_MAXIMUM_FRAME_SIZE
,
37 OID_GEN_TRANSMIT_BUFFER_SPACE
,
38 OID_GEN_RECEIVE_BUFFER_SPACE
,
39 OID_GEN_TRANSMIT_BLOCK_SIZE
,
40 OID_GEN_RECEIVE_BLOCK_SIZE
,
42 OID_GEN_VENDOR_DESCRIPTION
,
43 OID_GEN_VENDOR_DRIVER_VERSION
,
44 OID_GEN_CURRENT_PACKET_FILTER
,
45 OID_GEN_CURRENT_LOOKAHEAD
,
46 OID_GEN_DRIVER_VERSION
,
47 OID_GEN_MAXIMUM_TOTAL_SIZE
,
48 OID_GEN_PROTOCOL_OPTIONS
,
50 OID_GEN_MEDIA_CONNECT_STATUS
,
51 OID_GEN_MAXIMUM_SEND_PACKETS
,
52 OID_802_3_PERMANENT_ADDRESS
,
53 OID_802_3_CURRENT_ADDRESS
,
54 OID_802_3_MULTICAST_LIST
,
55 OID_802_3_MAXIMUM_LIST_SIZE
,
59 DRIVER_INFORMATION DriverInfo
= { NULL
, NULL
, { NULL
, NULL
} };
60 NDIS_PHYSICAL_ADDRESS HighestAcceptableMax
= NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
63 static BOOLEAN NTAPI
MiniportCheckForHang(
64 IN NDIS_HANDLE MiniportAdapterContext
)
66 * FUNCTION: Examines if an adapter has hung
68 * MiniportAdapterContext = Pointer to adapter context area
70 * TRUE if the adapter has hung, FALSE if not
73 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
79 static VOID NTAPI
MiniportDisableInterrupt(
80 IN NDIS_HANDLE MiniportAdapterContext
)
82 * FUNCTION: Disables interrupts from an adapter
84 * MiniportAdapterContext = Pointer to adapter context area
87 NDIS_DbgPrint(MAX_TRACE
, ("Called. (MiniportDisableInterrupt).\n"));
89 NICDisableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
94 static VOID NTAPI
MiniportEnableInterrupt(
95 IN NDIS_HANDLE MiniportAdapterContext
)
97 * FUNCTION: Enables interrupts from an adapter
99 * MiniportAdapterContext = Pointer to adapter context area
102 NDIS_DbgPrint(MAX_TRACE
, ("Called. (MiniportEnableInterrupt).\n"));
104 NICEnableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
109 static VOID NTAPI
MiniportHalt(
110 IN NDIS_HANDLE MiniportAdapterContext
)
112 * FUNCTION: Deallocates resources for and halts an adapter
114 * MiniportAdapterContext = Pointer to adapter context area
117 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
119 ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
121 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
126 /* Wait for any DPCs to complete. FIXME: Use something else */
127 NdisStallExecution(250000);
129 if (Adapter
->InterruptRegistered
)
130 /* Deregister interrupt */
131 NdisMDeregisterInterrupt(&Adapter
->Interrupt
);
133 if (Adapter
->IOPortRangeRegistered
)
134 /* Deregister I/O port range */
135 NdisMDeregisterIoPortRange(
136 Adapter
->MiniportAdapterHandle
,
137 Adapter
->IoBaseAddress
,
141 if (Adapter
->ShutdownHandlerRegistered
)
142 NdisMDeregisterAdapterShutdownHandler(Adapter
->MiniportAdapterHandle
);
144 /* Remove adapter from global adapter list */
145 if ((&Adapter
->ListEntry
)->Blink
!= NULL
) {
146 RemoveEntryList(&Adapter
->ListEntry
);
149 /* Free adapter context area */
150 NdisFreeMemory(Adapter
, sizeof(NIC_ADAPTER
), 0);
154 static VOID NTAPI
MiQueryResources(
155 OUT PNDIS_STATUS Status
,
156 IN PNIC_ADAPTER Adapter
,
157 IN NDIS_HANDLE WrapperConfigurationContext
)
159 PNDIS_RESOURCE_LIST AssignedResources
;
161 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
;
164 NdisMQueryAdapterResources(Status
,
165 WrapperConfigurationContext
,
168 if (*Status
== NDIS_STATUS_SUCCESS
)
171 *Status
= NdisAllocateMemory((PVOID
)&AssignedResources
,
174 HighestAcceptableMax
);
175 if (*Status
!= NDIS_STATUS_SUCCESS
)
178 NdisMQueryAdapterResources(Status
,
179 WrapperConfigurationContext
,
182 if (*Status
!= NDIS_STATUS_SUCCESS
)
185 for (i
= 0; i
< AssignedResources
->Count
; i
++)
187 Descriptor
= AssignedResources
->PartialDescriptors
+ i
;
188 switch (Descriptor
->Type
)
190 case CmResourceTypeInterrupt
:
191 Adapter
->InterruptLevel
= Descriptor
->u
.Interrupt
.Level
;
192 Adapter
->InterruptVector
= Descriptor
->u
.Interrupt
.Vector
;
193 Adapter
->InterruptShared
= (Descriptor
->ShareDisposition
== CmResourceShareShared
);
194 Adapter
->InterruptMode
= Descriptor
->Flags
& CM_RESOURCE_INTERRUPT_LATCHED
?
195 NdisInterruptLatched
: NdisInterruptLevelSensitive
;
197 case CmResourceTypePort
:
198 Adapter
->IoBaseAddress
= Descriptor
->u
.Port
.Start
.LowPart
;
206 MiniportShutdown(PVOID Context
)
209 NICStop((PNIC_ADAPTER
)Context
);
213 static NDIS_STATUS NTAPI
MiniportInitialize(
214 OUT PNDIS_STATUS OpenErrorStatus
,
215 OUT PUINT SelectedMediumIndex
,
216 IN PNDIS_MEDIUM MediumArray
,
217 IN UINT MediumArraySize
,
218 IN NDIS_HANDLE MiniportAdapterHandle
,
219 IN NDIS_HANDLE WrapperConfigurationContext
)
221 * FUNCTION: Adapter initialization function
223 * OpenErrorStatus = Address of buffer to place additional status information
224 * SelectedMediumIndex = Address of buffer to place selected medium index
225 * MediumArray = Pointer to an array of NDIS_MEDIUMs
226 * MediaArraySize = Number of elements in MediumArray
227 * MiniportAdapterHandle = Miniport adapter handle assigned by NDIS
228 * WrapperConfigurationContext = Handle used to identify configuration context
230 * Status of operation
235 PNIC_ADAPTER Adapter
;
236 NDIS_HANDLE ConfigurationHandle
;
237 UINT
*RegNetworkAddress
= 0;
238 UINT RegNetworkAddressLength
= 0;
240 ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
242 NDIS_DbgPrint(MAX_TRACE
, ("Called (Adapter %X).\n", MiniportAdapterHandle
));
244 /* Search for 802.3 media which is the only one we support */
245 for (i
= 0; i
< MediumArraySize
; i
++) {
246 if (MediumArray
[i
] == NdisMedium802_3
)
250 if (i
== MediumArraySize
) {
251 NDIS_DbgPrint(MIN_TRACE
, ("No supported media.\n"));
252 return NDIS_STATUS_UNSUPPORTED_MEDIA
;
255 *SelectedMediumIndex
= i
;
257 Status
= NdisAllocateMemory((PVOID
)&Adapter
,
260 HighestAcceptableMax
);
261 if (Status
!= NDIS_STATUS_SUCCESS
) {
262 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
266 NdisZeroMemory(Adapter
, sizeof(NIC_ADAPTER
));
267 Adapter
->MiniportAdapterHandle
= MiniportAdapterHandle
;
268 Adapter
->IoBaseAddress
= DRIVER_DEFAULT_IO_BASE_ADDRESS
;
269 Adapter
->InterruptLevel
= DRIVER_DEFAULT_INTERRUPT_NUMBER
;
270 Adapter
->InterruptVector
= DRIVER_DEFAULT_INTERRUPT_NUMBER
;
271 Adapter
->InterruptShared
= DRIVER_DEFAULT_INTERRUPT_SHARED
;
272 Adapter
->InterruptMode
= DRIVER_DEFAULT_INTERRUPT_MODE
;
273 Adapter
->MaxMulticastListSize
= DRIVER_MAX_MULTICAST_LIST_SIZE
;
274 Adapter
->InterruptMask
= DRIVER_INTERRUPT_MASK
;
275 Adapter
->LookaheadSize
= DRIVER_MAXIMUM_LOOKAHEAD
;
277 /* Query the resources from PnP. */
278 MiQueryResources(&Status
, Adapter
, WrapperConfigurationContext
);
280 /* Get the port, irq, and MAC address from registry if the PnP
282 if (Status
!= NDIS_STATUS_SUCCESS
)
284 PNDIS_CONFIGURATION_PARAMETER ConfigurationParameter
;
285 UNICODE_STRING Keyword
;
287 NdisOpenConfiguration(&Status
, &ConfigurationHandle
, WrapperConfigurationContext
);
288 if (Status
== NDIS_STATUS_SUCCESS
)
290 NdisInitUnicodeString(&Keyword
, L
"Irq");
291 NdisReadConfiguration(&Status
, &ConfigurationParameter
, ConfigurationHandle
, &Keyword
, NdisParameterHexInteger
);
292 if(Status
== NDIS_STATUS_SUCCESS
)
294 NDIS_DbgPrint(MID_TRACE
,("NdisReadConfiguration for Irq returned successfully, irq 0x%x\n",
295 ConfigurationParameter
->ParameterData
.IntegerData
));
296 Adapter
->InterruptLevel
=
297 Adapter
->InterruptVector
= ConfigurationParameter
->ParameterData
.IntegerData
;
300 NdisInitUnicodeString(&Keyword
, L
"Port");
301 NdisReadConfiguration(&Status
, &ConfigurationParameter
, ConfigurationHandle
, &Keyword
, NdisParameterHexInteger
);
302 if(Status
== NDIS_STATUS_SUCCESS
)
304 NDIS_DbgPrint(MID_TRACE
,("NdisReadConfiguration for Port returned successfully, port 0x%x\n",
305 ConfigurationParameter
->ParameterData
.IntegerData
));
306 Adapter
->IoBaseAddress
= ConfigurationParameter
->ParameterData
.IntegerData
;
309 NdisCloseConfiguration(ConfigurationHandle
);
313 NDIS_DbgPrint(MIN_TRACE
,("NdisOpenConfiguration returned error 0x%x\n", Status
));
318 if (!NICCheck(Adapter
)) {
319 NDIS_DbgPrint(MID_TRACE
, ("No adapter found at (0x%X).\n", Adapter
->IoBaseAddress
));
320 NdisFreeMemory(Adapter
, sizeof(NIC_ADAPTER
), 0);
321 return NDIS_STATUS_ADAPTER_NOT_FOUND
;
323 NDIS_DbgPrint(MID_TRACE
, ("Adapter found at (0x%X).\n", Adapter
->IoBaseAddress
));
326 MiniportAdapterHandle
,
327 (NDIS_HANDLE
)Adapter
,
331 Status
= NdisMRegisterIoPortRange(
332 (PVOID
*)&Adapter
->IOBase
,
333 MiniportAdapterHandle
,
334 Adapter
->IoBaseAddress
,
337 if (Status
!= NDIS_STATUS_SUCCESS
) {
338 NDIS_DbgPrint(MIN_TRACE
, ("Cannot register port range. Status (0x%X).\n", Status
));
339 MiniportHalt((NDIS_HANDLE
)Adapter
);
343 Adapter
->IOPortRangeRegistered
= TRUE
;
347 Status
= NICInitialize(Adapter
);
348 if (Status
!= NDIS_STATUS_SUCCESS
) {
349 NDIS_DbgPrint(MIN_TRACE
,("No NE2000 or compatible network adapter found at address 0x%X.\n",
352 NDIS_DbgPrint(MID_TRACE
, ("Status (0x%X).\n", Status
));
353 MiniportHalt((NDIS_HANDLE
)Adapter
);
357 NdisOpenConfiguration(&Status
, &ConfigurationHandle
, WrapperConfigurationContext
);
358 if (Status
== NDIS_STATUS_SUCCESS
)
360 NdisReadNetworkAddress(&Status
, (PVOID
*)&RegNetworkAddress
, &RegNetworkAddressLength
, ConfigurationHandle
);
361 if(Status
== NDIS_STATUS_SUCCESS
&& RegNetworkAddressLength
== DRIVER_LENGTH_OF_ADDRESS
)
364 NDIS_DbgPrint(MID_TRACE
,("NdisReadNetworkAddress returned successfully, address %x:%x:%x:%x:%x:%x\n",
365 RegNetworkAddress
[0], RegNetworkAddress
[1], RegNetworkAddress
[2], RegNetworkAddress
[3],
366 RegNetworkAddress
[4], RegNetworkAddress
[5]));
367 for(i
= 0; i
< DRIVER_LENGTH_OF_ADDRESS
; i
++)
368 Adapter
->StationAddress
[i
] = RegNetworkAddress
[i
];
371 NdisCloseConfiguration(ConfigurationHandle
);
374 if (Status
!= NDIS_STATUS_SUCCESS
|| RegNetworkAddressLength
!= DRIVER_LENGTH_OF_ADDRESS
)
377 for (i
= 0; i
< DRIVER_LENGTH_OF_ADDRESS
; i
++)
378 Adapter
->StationAddress
[i
] = Adapter
->PermanentAddress
[i
];
381 NDIS_DbgPrint(MID_TRACE
, ("BOARDDATA:\n"));
382 for (i
= 0; i
< 4; i
++) {
383 NDIS_DbgPrint(MID_TRACE
, ("%02X %02X %02X %02X\n",
384 Adapter
->SAPROM
[i
*4+0],
385 Adapter
->SAPROM
[i
*4+1],
386 Adapter
->SAPROM
[i
*4+2],
387 Adapter
->SAPROM
[i
*4+3]));
390 /* Setup adapter structure */
391 Adapter
->TXStart
= ((ULONG_PTR
)Adapter
->RamBase
>> 8);
392 Adapter
->TXCount
= DRIVER_DEFAULT_TX_BUFFER_COUNT
;
393 Adapter
->TXFree
= DRIVER_DEFAULT_TX_BUFFER_COUNT
;
394 Adapter
->TXCurrent
= -1;
395 Adapter
->PageStart
= Adapter
->TXStart
+ Adapter
->TXCount
;
396 Adapter
->PageStop
= Adapter
->TXStart
+ (Adapter
->RamSize
>> 8);
398 /* Initialize multicast address mask to accept all */
399 for (i
= 0; i
< 8; i
++)
400 Adapter
->MulticastAddressMask
[i
] = 0xFF;
405 NDIS_DbgPrint(MID_TRACE
, ("TXStart (0x%X) TXCount (0x%X) PageStart (0x%X)\n",
408 Adapter
->PageStart
));
410 NDIS_DbgPrint(MID_TRACE
, ("PageStop (0x%X) CurrentPage (0x%X) NextPacket (0x%X).\n",
412 Adapter
->CurrentPage
,
413 Adapter
->NextPacket
));
415 /* Register the interrupt */
416 Status
= NdisMRegisterInterrupt(
418 MiniportAdapterHandle
,
419 Adapter
->InterruptVector
,
420 Adapter
->InterruptLevel
,
422 Adapter
->InterruptShared
,
423 Adapter
->InterruptMode
);
424 if (Status
!= NDIS_STATUS_SUCCESS
) {
425 NDIS_DbgPrint(MIN_TRACE
, ("Cannot register interrupt. Status (0x%X).\n", Status
));
426 MiniportHalt((NDIS_HANDLE
)Adapter
);
430 Adapter
->InterruptRegistered
= TRUE
;
436 /* Register the shutdown handler */
437 NdisMRegisterAdapterShutdownHandler(MiniportAdapterHandle
, Adapter
, MiniportShutdown
);
439 Adapter
->ShutdownHandlerRegistered
= TRUE
;
441 /* Add adapter to the global adapter list */
442 InsertTailList(&DriverInfo
.AdapterListHead
, &Adapter
->ListEntry
);
444 NDIS_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
446 return NDIS_STATUS_SUCCESS
;
450 static VOID NTAPI
MiniportISR(
451 OUT PBOOLEAN InterruptRecognized
,
452 OUT PBOOLEAN QueueMiniportHandleInterrupt
,
453 IN NDIS_HANDLE MiniportAdapterContext
)
455 * FUNCTION: Interrupt Service Routine for controlled adapters
457 * InterruptRecognized = Address of buffer to place wether
458 * the adapter generated the interrupt
459 * QueueMiniportHandleInterrupt = Address of buffer to place wether
460 * MiniportHandleInterrupt should be called
461 * MiniportAdapterContext = Pointer to adapter context area
463 * All pending interrupts are handled
466 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
468 NICDisableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
470 *InterruptRecognized
= TRUE
;
471 *QueueMiniportHandleInterrupt
= TRUE
;
475 static NDIS_STATUS NTAPI
MiniportQueryInformation(
476 IN NDIS_HANDLE MiniportAdapterContext
,
478 IN PVOID InformationBuffer
,
479 IN ULONG InformationBufferLength
,
480 OUT PULONG BytesWritten
,
481 OUT PULONG BytesNeeded
)
483 * FUNCTION: Handler to process queries
485 * MiniportAdapterContext = Pointer to adapter context area
486 * Oid = OID code designating query operation
487 * InformationBuffer = Address of return buffer
488 * InformationBufferLength = Length of return buffer
489 * BytesWritten = Address of buffer to place number of bytes returned
490 * BytesNeeded = Address of buffer to place number of bytes needed
491 * in InformationBuffer for specified OID
493 * Status of operation
500 USHORT GenericUSHORT
;
501 NDIS_MEDIUM Medium
= NdisMedium802_3
;
502 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
504 NDIS_DbgPrint(MAX_TRACE
, ("Called. Oid (0x%X).\n", Oid
));
506 Status
= NDIS_STATUS_SUCCESS
;
507 CopyFrom
= (PVOID
)&GenericULONG
;
508 CopySize
= sizeof(ULONG
);
511 case OID_GEN_SUPPORTED_LIST
:
512 CopyFrom
= (PVOID
)&MiniportOIDList
;
513 CopySize
= sizeof(MiniportOIDList
);
515 case OID_GEN_HARDWARE_STATUS
:
516 GenericULONG
= (ULONG
)NdisHardwareStatusReady
;
518 case OID_GEN_MEDIA_SUPPORTED
:
519 case OID_GEN_MEDIA_IN_USE
:
520 CopyFrom
= (PVOID
)&Medium
;
521 CopySize
= sizeof(NDIS_MEDIUM
);
523 case OID_GEN_MAXIMUM_LOOKAHEAD
:
524 GenericULONG
= DRIVER_MAXIMUM_LOOKAHEAD
;
526 case OID_GEN_MAXIMUM_FRAME_SIZE
:
527 GenericULONG
= DRIVER_FRAME_SIZE
- DRIVER_HEADER_SIZE
;
529 case OID_GEN_LINK_SPEED
:
530 GenericULONG
= 100000; /* 10Mbps */
532 case OID_GEN_TRANSMIT_BUFFER_SPACE
:
533 GenericULONG
= Adapter
->TXCount
* DRIVER_BLOCK_SIZE
;
535 case OID_GEN_RECEIVE_BUFFER_SPACE
:
536 GenericULONG
= Adapter
->RamSize
-
537 (ULONG_PTR
)Adapter
->RamBase
-
538 (Adapter
->TXCount
* DRIVER_BLOCK_SIZE
);
540 case OID_GEN_TRANSMIT_BLOCK_SIZE
:
541 GenericULONG
= DRIVER_BLOCK_SIZE
;
543 case OID_GEN_RECEIVE_BLOCK_SIZE
:
544 GenericULONG
= DRIVER_BLOCK_SIZE
;
546 case OID_GEN_VENDOR_ID
:
547 NdisMoveMemory(&GenericULONG
, &Adapter
->PermanentAddress
, 3);
548 GenericULONG
&= 0xFFFFFF00;
549 GenericULONG
|= 0x01;
551 case OID_GEN_VENDOR_DESCRIPTION
:
552 CopyFrom
= (PVOID
)&DRIVER_VENDOR_DESCRIPTION
;
553 CopySize
= sizeof(DRIVER_VENDOR_DESCRIPTION
);
555 case OID_GEN_VENDOR_DRIVER_VERSION
:
556 GenericUSHORT
= (USHORT
)DRIVER_VENDOR_DRIVER_VERSION
;
557 CopyFrom
= (PVOID
)&GenericUSHORT
;
558 CopySize
= sizeof(USHORT
);
560 case OID_GEN_CURRENT_PACKET_FILTER
:
561 GenericULONG
= Adapter
->PacketFilter
;
563 case OID_GEN_CURRENT_LOOKAHEAD
:
564 GenericULONG
= Adapter
->LookaheadSize
;
566 case OID_GEN_DRIVER_VERSION
:
567 GenericUSHORT
= ((USHORT
)DRIVER_NDIS_MAJOR_VERSION
<< 8) | DRIVER_NDIS_MINOR_VERSION
;
568 CopyFrom
= (PVOID
)&GenericUSHORT
;
569 CopySize
= sizeof(USHORT
);
571 case OID_GEN_MAXIMUM_TOTAL_SIZE
:
572 GenericULONG
= DRIVER_FRAME_SIZE
;
574 case OID_GEN_PROTOCOL_OPTIONS
:
575 NDIS_DbgPrint(MID_TRACE
, ("OID_GEN_PROTOCOL_OPTIONS.\n"));
576 Status
= NDIS_STATUS_NOT_SUPPORTED
;
578 case OID_GEN_MAC_OPTIONS
:
579 GenericULONG
= NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA
|
580 NDIS_MAC_OPTION_RECEIVE_SERIALIZED
|
581 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND
|
582 NDIS_MAC_OPTION_NO_LOOPBACK
;
584 case OID_GEN_MEDIA_CONNECT_STATUS
:
585 GenericULONG
= (ULONG
)NdisMediaStateConnected
;
587 case OID_GEN_MAXIMUM_SEND_PACKETS
:
590 case OID_802_3_PERMANENT_ADDRESS
:
591 CopyFrom
= (PVOID
)&Adapter
->PermanentAddress
;
592 CopySize
= DRIVER_LENGTH_OF_ADDRESS
;
594 case OID_802_3_CURRENT_ADDRESS
:
595 CopyFrom
= (PVOID
)&Adapter
->StationAddress
;
596 CopySize
= DRIVER_LENGTH_OF_ADDRESS
;
598 case OID_802_3_MULTICAST_LIST
:
599 NDIS_DbgPrint(MID_TRACE
, ("OID_802_3_MULTICAST_LIST.\n"));
600 Status
= NDIS_STATUS_NOT_SUPPORTED
;
602 case OID_802_3_MAXIMUM_LIST_SIZE
:
603 GenericULONG
= Adapter
->MaxMulticastListSize
;
605 case OID_802_3_MAC_OPTIONS
:
606 NDIS_DbgPrint(MID_TRACE
, ("OID_802_3_MAC_OPTIONS.\n"));
607 Status
= NDIS_STATUS_NOT_SUPPORTED
;
610 NDIS_DbgPrint(MIN_TRACE
, ("Unknown OID (0x%X).\n", Oid
));
611 Status
= NDIS_STATUS_INVALID_OID
;
615 if (Status
== NDIS_STATUS_SUCCESS
) {
616 if (CopySize
> InformationBufferLength
) {
617 *BytesNeeded
= (CopySize
- InformationBufferLength
);
619 Status
= NDIS_STATUS_INVALID_LENGTH
;
621 NdisMoveMemory(InformationBuffer
, CopyFrom
, CopySize
);
622 *BytesWritten
= CopySize
;
627 NDIS_DbgPrint(MAX_TRACE
, ("Leaving. Status is (0x%X).\n", Status
));
633 static NDIS_STATUS NTAPI
MiniportReconfigure(
634 OUT PNDIS_STATUS OpenErrorStatus
,
635 IN NDIS_HANDLE MiniportAdapterContext
,
636 IN NDIS_HANDLE WrapperConfigurationContext
)
638 * FUNCTION: Reconfigures an adapter
640 * OpenErrorStatus = Address of buffer to place additional status information
641 * MiniportAdapterContext = Pointer to adapter context area
642 * WrapperConfigurationContext = Handle used to identify configuration context
644 * Status of operation
646 * Never called by NDIS library
649 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
651 return NDIS_STATUS_FAILURE
;
656 static NDIS_STATUS NTAPI
MiniportReset(
657 OUT PBOOLEAN AddressingReset
,
658 IN NDIS_HANDLE MiniportAdapterContext
)
660 * FUNCTION: Resets an adapter
662 * AddressingReset = Address of a buffer to place value indicating
663 * wether NDIS library should call MiniportSetInformation
664 * to restore addressing information
665 * MiniportAdapterContext = Pointer to adapter context area
667 * Status of operation
670 NDIS_STATUS NdisStatus
= NDIS_STATUS_SUCCESS
;
672 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
675 NdisStatus
= NICReset((PNIC_ADAPTER
)MiniportAdapterContext
);
678 *AddressingReset
= TRUE
;
684 static NDIS_STATUS NTAPI
MiniportSend(
685 IN NDIS_HANDLE MiniportAdapterContext
,
686 IN PNDIS_PACKET Packet
,
689 * FUNCTION: Transmits a packet
691 * MiniportAdapterContext = Pointer to adapter context area
692 * Packet = Pointer to a packet descriptor specifying
693 * the data to be transmitted
694 * Flags = Specifies optional packet flags
696 * Status of operation
699 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
701 ASSERT_IRQL_EQUAL(DISPATCH_LEVEL
);
704 NDIS_DbgPrint(MID_TRACE
, ("Queueing packet.\n"));
706 /* Queue the packet on the transmit queue */
707 RESERVED(Packet
)->Next
= NULL
;
708 if (Adapter
->TXQueueHead
== NULL
) {
709 Adapter
->TXQueueHead
= Packet
;
711 RESERVED(Adapter
->TXQueueTail
)->Next
= Packet
;
714 Adapter
->TXQueueTail
= Packet
;
716 /* Transmit the packet */
717 NICTransmit(Adapter
);
719 return NDIS_STATUS_PENDING
;
721 return NDIS_STATUS_SUCCESS
;
726 static NDIS_STATUS NTAPI
MiniportSetInformation(
727 IN NDIS_HANDLE MiniportAdapterContext
,
729 IN PVOID InformationBuffer
,
730 IN ULONG InformationBufferLength
,
731 OUT PULONG BytesRead
,
732 OUT PULONG BytesNeeded
)
734 * FUNCTION: Changes state information in the driver
736 * MiniportAdapterContext = Pointer to adapter context area
737 * Oid = OID code designating set operation
738 * InformationBuffer = Pointer to buffer with state information
739 * InformationBufferLength = Length of InformationBuffer
740 * BytesRead = Address of buffer to place number of bytes read
741 * BytesNeeded = Address of buffer to place number of extra bytes
742 * needed in InformationBuffer for specified OID
744 * Status of operation
748 NDIS_STATUS Status
= NDIS_STATUS_SUCCESS
;
749 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
751 NDIS_DbgPrint(MAX_TRACE
, ("Called. Oid (0x%X).\n", Oid
));
754 case OID_GEN_CURRENT_PACKET_FILTER
:
756 if (InformationBufferLength
< sizeof(ULONG
)) {
758 *BytesNeeded
= sizeof(ULONG
) - InformationBufferLength
;
759 Status
= NDIS_STATUS_INVALID_LENGTH
;
763 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
764 /* Check for properties the driver don't support */
766 (NDIS_PACKET_TYPE_ALL_FUNCTIONAL
|
767 NDIS_PACKET_TYPE_FUNCTIONAL
|
768 NDIS_PACKET_TYPE_GROUP
|
769 NDIS_PACKET_TYPE_MAC_FRAME
|
770 NDIS_PACKET_TYPE_SMT
|
771 NDIS_PACKET_TYPE_SOURCE_ROUTING
)) {
774 Status
= NDIS_STATUS_NOT_SUPPORTED
;
778 Adapter
->PacketFilter
= GenericULONG
;
780 /* FIXME: Set filter on hardware */
783 case OID_GEN_CURRENT_LOOKAHEAD
:
785 if (InformationBufferLength
< sizeof(ULONG
)) {
787 *BytesNeeded
= sizeof(ULONG
) - InformationBufferLength
;
788 Status
= NDIS_STATUS_INVALID_LENGTH
;
792 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
793 if (GenericULONG
> DRIVER_MAXIMUM_LOOKAHEAD
)
794 Status
= NDIS_STATUS_INVALID_LENGTH
;
796 Adapter
->LookaheadSize
= GenericULONG
;
798 case OID_802_3_MULTICAST_LIST
:
799 /* Verify length. Must be multiplum of hardware address length */
800 if ((InformationBufferLength
% DRIVER_LENGTH_OF_ADDRESS
) != 0) {
803 Status
= NDIS_STATUS_INVALID_LENGTH
;
807 /* Set new multicast address list */
808 NdisMoveMemory(Adapter
->Addresses
, InformationBuffer
, InformationBufferLength
);
810 /* FIXME: Update hardware */
814 NDIS_DbgPrint(MIN_TRACE
, ("Invalid object ID (0x%X).\n", Oid
));
817 Status
= NDIS_STATUS_INVALID_OID
;
821 if (Status
== NDIS_STATUS_SUCCESS
) {
822 *BytesRead
= InformationBufferLength
;
826 NDIS_DbgPrint(MAX_TRACE
, ("Leaving. Status (0x%X).\n", Status
));
832 static NDIS_STATUS NTAPI
MiniportTransferData(
833 OUT PNDIS_PACKET Packet
,
834 OUT PUINT BytesTransferred
,
835 IN NDIS_HANDLE MiniportAdapterContext
,
836 IN NDIS_HANDLE MiniportReceiveContext
,
838 IN UINT BytesToTransfer
)
840 * FUNCTION: Transfers data from a received frame into an NDIS packet
842 * Packet = Address of packet to copy received data into
843 * BytesTransferred = Address of buffer to place number of bytes transmitted
844 * MiniportAdapterContext = Pointer to adapter context area
845 * MiniportReceiveContext = Pointer to receive context area (actually NULL)
846 * ByteOffset = Offset within received packet to begin copying
847 * BytesToTransfer = Number of bytes to copy into packet
849 * Status of operation
852 PNDIS_BUFFER DstBuffer
;
853 UINT BytesCopied
, BytesToCopy
, DstSize
;
858 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
860 NDIS_DbgPrint(MAX_TRACE
, ("Called. Packet (0x%X) ByteOffset (0x%X) BytesToTransfer (%d).\n",
861 Packet
, ByteOffset
, BytesToTransfer
));
863 if (BytesToTransfer
== 0) {
864 *BytesTransferred
= 0;
865 return NDIS_STATUS_SUCCESS
;
868 RecvStart
= Adapter
->PageStart
* DRIVER_BLOCK_SIZE
;
869 RecvStop
= Adapter
->PageStop
* DRIVER_BLOCK_SIZE
;
871 NdisQueryPacket(Packet
, NULL
, NULL
, &DstBuffer
, NULL
);
872 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
874 SrcData
= Adapter
->PacketOffset
+ sizeof(DISCARD_HEADER
) + ByteOffset
;
875 if (ByteOffset
+ sizeof(DISCARD_HEADER
) + BytesToTransfer
>
876 Adapter
->PacketHeader
.PacketLength
)
877 BytesToTransfer
= Adapter
->PacketHeader
.PacketLength
-
878 sizeof(DISCARD_HEADER
) - ByteOffset
;
880 /* Start copying the data */
883 BytesToCopy
= (DstSize
< BytesToTransfer
) ? DstSize
: BytesToTransfer
;
884 if (SrcData
+ BytesToCopy
> RecvStop
)
885 BytesToCopy
= (RecvStop
- SrcData
);
887 NICReadData(Adapter
, DstData
, SrcData
, BytesToCopy
);
889 BytesCopied
+= BytesToCopy
;
890 SrcData
+= BytesToCopy
;
891 DstData
= (PUCHAR
)((ULONG_PTR
) DstData
+ BytesToCopy
);
892 BytesToTransfer
-= BytesToCopy
;
893 if (BytesToTransfer
== 0)
896 DstSize
-= BytesToCopy
;
898 /* No more bytes in destination buffer. Proceed to
899 the next buffer in the destination buffer chain */
900 NdisGetNextBuffer(DstBuffer
, &DstBuffer
);
904 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
907 if (SrcData
== RecvStop
)
911 NDIS_DbgPrint(MID_TRACE
, ("Transferred (%d) bytes.\n", BytesToTransfer
));
913 *BytesTransferred
= BytesCopied
;
915 return NDIS_STATUS_SUCCESS
;
922 PDRIVER_OBJECT DriverObject
,
923 PUNICODE_STRING RegistryPath
)
925 * FUNCTION: Main driver entry point
927 * DriverObject = Pointer to a driver object for this driver
928 * RegistryPath = Registry node for configuration parameters
930 * Status of driver initialization
934 NDIS_HANDLE NdisWrapperHandle
;
935 NDIS_MINIPORT_CHARACTERISTICS Miniport
;
937 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
939 NdisZeroMemory(&Miniport
, sizeof(Miniport
));
940 Miniport
.MajorNdisVersion
= DRIVER_NDIS_MAJOR_VERSION
;
941 Miniport
.MinorNdisVersion
= DRIVER_NDIS_MINOR_VERSION
;
942 Miniport
.CheckForHangHandler
= MiniportCheckForHang
;
943 Miniport
.DisableInterruptHandler
= MiniportDisableInterrupt
;
944 Miniport
.EnableInterruptHandler
= MiniportEnableInterrupt
;
945 Miniport
.HaltHandler
= MiniportHalt
;
946 Miniport
.HandleInterruptHandler
= MiniportHandleInterrupt
;
947 Miniport
.InitializeHandler
= MiniportInitialize
;
948 Miniport
.ISRHandler
= MiniportISR
;
949 Miniport
.QueryInformationHandler
= MiniportQueryInformation
;
950 Miniport
.ReconfigureHandler
= MiniportReconfigure
;
951 Miniport
.ResetHandler
= MiniportReset
;
952 Miniport
.SendHandler
= MiniportSend
;
953 Miniport
.SetInformationHandler
= MiniportSetInformation
;
954 Miniport
.TransferDataHandler
= MiniportTransferData
;
956 NdisMInitializeWrapper(&NdisWrapperHandle
,
961 if (!NdisWrapperHandle
) {
962 NDIS_DbgPrint(MIN_TRACE
, ("NdisMInitializeWrapper() failed\n"));
963 return STATUS_UNSUCCESSFUL
;
966 DriverInfo
.NdisWrapperHandle
= NdisWrapperHandle
;
967 DriverInfo
.NdisMacHandle
= NULL
;
968 InitializeListHead(&DriverInfo
.AdapterListHead
);
970 Status
= NdisMRegisterMiniport(NdisWrapperHandle
,
972 sizeof(NDIS_MINIPORT_CHARACTERISTICS
));
973 if (Status
!= NDIS_STATUS_SUCCESS
) {
974 NDIS_DbgPrint(MIN_TRACE
, ("NdisMRegisterMiniport() failed with status code (0x%X).\n", Status
));
975 NdisTerminateWrapper(NdisWrapperHandle
, NULL
);
976 return STATUS_UNSUCCESSFUL
;
979 return STATUS_SUCCESS
;
983 /* while i'm here - some basic registry sanity checks */
986 NDIS_CONFIGURATION_PARAMETER ParameterValue
;
988 ParameterValue
.ParameterType
= NdisParameterInteger
;
989 ParameterValue
.ParameterData
.IntegerData
= 0x12345678;
990 NdisInitUnicodeString(&Keyword
, L
"DwordTest");
991 NdisWriteConfiguration(&Status
, ConfigurationHandle
, &Keyword
, &ParameterValue
);
993 if(Status
!= NDIS_STATUS_SUCCESS
)
995 DbgPrint("ne2000!MiniportInitialize: failed to set DwordTest: 0x%x\n", Status
);
999 DbgPrint("ne2000!MiniportInitialize: DwordTest successfully set\n");
1001 NdisInitUnicodeString(&Keyword
, L
"StringTest");
1002 ParameterValue
.ParameterType
= NdisParameterString
;
1003 NdisInitUnicodeString(&ParameterValue
.ParameterData
.StringData
, L
"Testing123");
1005 NdisWriteConfiguration(&Status
, ConfigurationHandle
, &Keyword
, &ParameterValue
);
1007 if(Status
!= NDIS_STATUS_SUCCESS
)
1009 DbgPrint("ne2000!MiniportInitialize: failed to set StringTest: 0x%x\n", Status
);
1013 DbgPrint("ne2000!MiniportInitialize: StringTest successfully set\n");
1017 /* read back the test values */
1018 NDIS_CONFIGURATION_PARAMETER
*ParameterValue
= 0;
1020 NdisInitUnicodeString(&Keyword
, L
"DwordTest");
1021 NdisReadConfiguration(&Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterInteger
);
1023 if(Status
!= NDIS_STATUS_SUCCESS
)
1025 DbgPrint("ne2000!MiniportInitialize: failed to read DwordTest: 0x%x\n", Status
);
1029 if(ParameterValue
->ParameterData
.IntegerData
!= 0x12345678)
1031 DbgPrint("ne2000!MiniportInitialize: DwordTest value is wrong: 0x%x\n",
1032 ParameterValue
->ParameterData
.IntegerData
);
1036 DbgPrint("ne2000!MiniportInitialize: DwordTest value was correctly read\n");
1038 NdisInitUnicodeString(&Keyword
, L
"StringTest");
1039 NdisReadConfiguration(&Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterString
);
1041 if(Status
!= NDIS_STATUS_SUCCESS
)
1043 DbgPrint("ne2000!MiniportInitialize: failed to read StringTest: 0x%x\n", Status
);
1047 if(wcsncmp(ParameterValue
->ParameterData
.StringData
.Buffer
, L
"Testing123",
1048 wcslen(L
"Testing123")))
1050 DbgPrint("ne2000!MiniportInitialize: StringTest value is wrong: %wZ\n",
1051 &ParameterValue
->ParameterData
.StringData
);
1055 DbgPrint("ne2000!MiniportInitialize: StringTest value was correctly read\n");