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
18 PDRIVER_OBJECT DriverObject
,
19 PUNICODE_STRING RegistryPath
);
24 /* See debug.h for debug/trace constants */
25 ULONG DebugTraceLevel
= 0;
30 /* List of supported OIDs */
31 static ULONG MiniportOIDList
[] = {
32 OID_GEN_SUPPORTED_LIST
,
33 OID_GEN_HARDWARE_STATUS
,
34 OID_GEN_MEDIA_SUPPORTED
,
36 OID_GEN_MAXIMUM_LOOKAHEAD
,
37 OID_GEN_MAXIMUM_FRAME_SIZE
,
39 OID_GEN_TRANSMIT_BUFFER_SPACE
,
40 OID_GEN_RECEIVE_BUFFER_SPACE
,
41 OID_GEN_TRANSMIT_BLOCK_SIZE
,
42 OID_GEN_RECEIVE_BLOCK_SIZE
,
44 OID_GEN_VENDOR_DESCRIPTION
,
45 OID_GEN_VENDOR_DRIVER_VERSION
,
46 OID_GEN_CURRENT_PACKET_FILTER
,
47 OID_GEN_CURRENT_LOOKAHEAD
,
48 OID_GEN_DRIVER_VERSION
,
49 OID_GEN_MAXIMUM_TOTAL_SIZE
,
50 OID_GEN_PROTOCOL_OPTIONS
,
52 OID_GEN_MEDIA_CONNECT_STATUS
,
53 OID_GEN_MAXIMUM_SEND_PACKETS
,
54 OID_802_3_PERMANENT_ADDRESS
,
55 OID_802_3_CURRENT_ADDRESS
,
56 OID_802_3_MULTICAST_LIST
,
57 OID_802_3_MAXIMUM_LIST_SIZE
,
61 DRIVER_INFORMATION DriverInfo
= {0};
62 NDIS_PHYSICAL_ADDRESS HighestAcceptableMax
= NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
65 static BOOLEAN STDCALL
MiniportCheckForHang(
66 IN NDIS_HANDLE MiniportAdapterContext
)
68 * FUNCTION: Examines if an adapter has hung
70 * MiniportAdapterContext = Pointer to adapter context area
72 * TRUE if the adapter has hung, FALSE if not
75 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
81 static VOID STDCALL
MiniportDisableInterrupt(
82 IN NDIS_HANDLE MiniportAdapterContext
)
84 * FUNCTION: Disables interrupts from an adapter
86 * MiniportAdapterContext = Pointer to adapter context area
89 NDIS_DbgPrint(MAX_TRACE
, ("Called. (MiniportDisableInterrupt).\n"));
91 NICDisableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
96 static VOID STDCALL
MiniportEnableInterrupt(
97 IN NDIS_HANDLE MiniportAdapterContext
)
99 * FUNCTION: Enables interrupts from an adapter
101 * MiniportAdapterContext = Pointer to adapter context area
104 NDIS_DbgPrint(MAX_TRACE
, ("Called. (MiniportEnableInterrupt).\n"));
106 NICEnableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
111 static VOID STDCALL
MiniportHalt(
112 IN NDIS_HANDLE MiniportAdapterContext
)
114 * FUNCTION: Deallocates resources for and halts an adapter
116 * MiniportAdapterContext = Pointer to adapter context area
119 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
121 ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
123 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
128 /* Wait for any DPCs to complete. FIXME: Use something else */
129 NdisStallExecution(250000);
131 if (Adapter
->InterruptRegistered
)
132 /* Deregister interrupt */
133 NdisMDeregisterInterrupt(&Adapter
->Interrupt
);
135 if (Adapter
->IOPortRangeRegistered
)
136 /* Deregister I/O port range */
137 NdisMDeregisterIoPortRange(
138 Adapter
->MiniportAdapterHandle
,
139 Adapter
->IoBaseAddress
,
143 if (Adapter
->ShutdownHandlerRegistered
)
144 NdisMDeregisterAdapterShutdownHandler(Adapter
->MiniportAdapterHandle
);
146 /* Remove adapter from global adapter list */
147 if ((&Adapter
->ListEntry
)->Blink
!= NULL
) {
148 RemoveEntryList(&Adapter
->ListEntry
);
151 /* Free adapter context area */
152 NdisFreeMemory(Adapter
, sizeof(NIC_ADAPTER
), 0);
156 static VOID STDCALL
MiQueryResources(
157 OUT PNDIS_STATUS Status
,
158 IN PNIC_ADAPTER Adapter
,
159 IN NDIS_HANDLE WrapperConfigurationContext
)
161 PNDIS_RESOURCE_LIST AssignedResources
;
163 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
;
166 NdisMQueryAdapterResources(Status
,
167 WrapperConfigurationContext
,
170 if (*Status
== NDIS_STATUS_SUCCESS
)
173 *Status
= NdisAllocateMemory((PVOID
)&AssignedResources
,
176 HighestAcceptableMax
);
177 if (*Status
!= NDIS_STATUS_SUCCESS
)
180 NdisMQueryAdapterResources(Status
,
181 WrapperConfigurationContext
,
184 if (*Status
!= NDIS_STATUS_SUCCESS
)
187 for (i
= 0; i
< AssignedResources
->Count
; i
++)
189 Descriptor
= AssignedResources
->PartialDescriptors
+ i
;
190 switch (Descriptor
->Type
)
192 case CmResourceTypeInterrupt
:
193 Adapter
->InterruptLevel
= Descriptor
->u
.Interrupt
.Level
;
194 Adapter
->InterruptVector
= Descriptor
->u
.Interrupt
.Vector
;
195 Adapter
->InterruptShared
= (Descriptor
->ShareDisposition
== CmResourceShareShared
);
196 Adapter
->InterruptMode
= Descriptor
->Flags
& CM_RESOURCE_INTERRUPT_LATCHED
?
197 NdisInterruptLatched
: NdisInterruptLevelSensitive
;
199 case CmResourceTypePort
:
200 Adapter
->IoBaseAddress
= Descriptor
->u
.Port
.Start
.LowPart
;
208 MiniportShutdown(PVOID Context
)
211 NICStop((PNIC_ADAPTER
)Context
);
215 static NDIS_STATUS STDCALL
MiniportInitialize(
216 OUT PNDIS_STATUS OpenErrorStatus
,
217 OUT PUINT SelectedMediumIndex
,
218 IN PNDIS_MEDIUM MediumArray
,
219 IN UINT MediumArraySize
,
220 IN NDIS_HANDLE MiniportAdapterHandle
,
221 IN NDIS_HANDLE WrapperConfigurationContext
)
223 * FUNCTION: Adapter initialization function
225 * OpenErrorStatus = Address of buffer to place additional status information
226 * SelectedMediumIndex = Address of buffer to place selected medium index
227 * MediumArray = Pointer to an array of NDIS_MEDIUMs
228 * MediaArraySize = Number of elements in MediumArray
229 * MiniportAdapterHandle = Miniport adapter handle assigned by NDIS
230 * WrapperConfigurationContext = Handle used to identify configuration context
232 * Status of operation
237 PNIC_ADAPTER Adapter
;
239 ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
241 NDIS_DbgPrint(MAX_TRACE
, ("Called (Adapter %X).\n", MiniportAdapterHandle
));
243 /* Search for 802.3 media which is the only one we support */
244 for (i
= 0; i
< MediumArraySize
; i
++) {
245 if (MediumArray
[i
] == NdisMedium802_3
)
249 if (i
== MediumArraySize
) {
250 NDIS_DbgPrint(MIN_TRACE
, ("No supported media.\n"));
251 return NDIS_STATUS_UNSUPPORTED_MEDIA
;
254 *SelectedMediumIndex
= i
;
256 Status
= NdisAllocateMemory((PVOID
)&Adapter
,
259 HighestAcceptableMax
);
260 if (Status
!= NDIS_STATUS_SUCCESS
) {
261 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
265 NdisZeroMemory(Adapter
, sizeof(NIC_ADAPTER
));
266 Adapter
->MiniportAdapterHandle
= MiniportAdapterHandle
;
267 Adapter
->IoBaseAddress
= DRIVER_DEFAULT_IO_BASE_ADDRESS
;
268 Adapter
->InterruptLevel
= DRIVER_DEFAULT_INTERRUPT_NUMBER
;
269 Adapter
->InterruptVector
= DRIVER_DEFAULT_INTERRUPT_NUMBER
;
270 Adapter
->InterruptShared
= DRIVER_DEFAULT_INTERRUPT_SHARED
;
271 Adapter
->InterruptMode
= DRIVER_DEFAULT_INTERRUPT_MODE
;
272 Adapter
->MaxMulticastListSize
= DRIVER_MAX_MULTICAST_LIST_SIZE
;
273 Adapter
->InterruptMask
= DRIVER_INTERRUPT_MASK
;
274 Adapter
->LookaheadSize
= DRIVER_MAXIMUM_LOOKAHEAD
;
276 /* Query the resources from PnP. */
277 MiQueryResources(&Status
, Adapter
, WrapperConfigurationContext
);
279 /* Get the port, irq, and MAC address from registry if the PnP
281 if (Status
!= NDIS_STATUS_SUCCESS
)
283 PNDIS_CONFIGURATION_PARAMETER ConfigurationParameter
;
284 NDIS_HANDLE ConfigurationHandle
;
285 UNICODE_STRING Keyword
;
286 UINT
*RegNetworkAddress
= 0;
287 UINT RegNetworkAddressLength
= 0;
289 NdisOpenConfiguration(&Status
, &ConfigurationHandle
, WrapperConfigurationContext
);
290 if (Status
== NDIS_STATUS_SUCCESS
)
292 NdisInitUnicodeString(&Keyword
, L
"Irq");
293 NdisReadConfiguration(&Status
, &ConfigurationParameter
, ConfigurationHandle
, &Keyword
, NdisParameterHexInteger
);
294 if(Status
== NDIS_STATUS_SUCCESS
)
296 NDIS_DbgPrint(MID_TRACE
,("NdisReadConfiguration for Irq returned successfully, irq 0x%x\n",
297 ConfigurationParameter
->ParameterData
.IntegerData
));
298 Adapter
->InterruptLevel
=
299 Adapter
->InterruptVector
= ConfigurationParameter
->ParameterData
.IntegerData
;
302 NdisInitUnicodeString(&Keyword
, L
"Port");
303 NdisReadConfiguration(&Status
, &ConfigurationParameter
, ConfigurationHandle
, &Keyword
, NdisParameterHexInteger
);
304 if(Status
== NDIS_STATUS_SUCCESS
)
306 NDIS_DbgPrint(MID_TRACE
,("NdisReadConfiguration for Port returned successfully, port 0x%x\n",
307 ConfigurationParameter
->ParameterData
.IntegerData
));
308 Adapter
->IoBaseAddress
= ConfigurationParameter
->ParameterData
.IntegerData
;
311 /* the returned copy of the data is owned by NDIS and will be released on NdisCloseConfiguration */
312 NdisReadNetworkAddress(&Status
, (PVOID
*)&RegNetworkAddress
, &RegNetworkAddressLength
, ConfigurationHandle
);
313 if(Status
== NDIS_STATUS_SUCCESS
&& RegNetworkAddressLength
== DRIVER_LENGTH_OF_ADDRESS
)
316 NDIS_DbgPrint(MID_TRACE
,("NdisReadNetworkAddress returned successfully, address %x:%x:%x:%x:%x:%x\n",
317 RegNetworkAddress
[0], RegNetworkAddress
[1], RegNetworkAddress
[2], RegNetworkAddress
[3],
318 RegNetworkAddress
[4], RegNetworkAddress
[5]));
319 for(i
= 0; i
< DRIVER_LENGTH_OF_ADDRESS
; i
++)
320 Adapter
->StationAddress
[i
] = RegNetworkAddress
[i
];
323 NdisCloseConfiguration(ConfigurationHandle
);
327 NDIS_DbgPrint(MIN_TRACE
,("NdisOpenConfiguration returned error 0x%x\n", Status
));
332 if (!NICCheck(Adapter
)) {
333 NDIS_DbgPrint(MID_TRACE
, ("No adapter found at (0x%X).\n", Adapter
->IoBaseAddress
));
334 NdisFreeMemory(Adapter
, sizeof(NIC_ADAPTER
), 0);
335 return NDIS_STATUS_ADAPTER_NOT_FOUND
;
337 NDIS_DbgPrint(MID_TRACE
, ("Adapter found at (0x%X).\n", Adapter
->IoBaseAddress
));
340 MiniportAdapterHandle
,
341 (NDIS_HANDLE
)Adapter
,
345 Status
= NdisMRegisterIoPortRange(
346 (PVOID
*)&Adapter
->IOBase
,
347 MiniportAdapterHandle
,
348 Adapter
->IoBaseAddress
,
351 if (Status
!= NDIS_STATUS_SUCCESS
) {
352 NDIS_DbgPrint(MIN_TRACE
, ("Cannot register port range. Status (0x%X).\n", Status
));
353 MiniportHalt((NDIS_HANDLE
)Adapter
);
357 Adapter
->IOPortRangeRegistered
= TRUE
;
361 Status
= NICInitialize(Adapter
);
362 if (Status
!= NDIS_STATUS_SUCCESS
) {
363 NDIS_DbgPrint(MIN_TRACE
,("No NE2000 or compatible network adapter found at address 0x%X.\n",
366 NDIS_DbgPrint(MID_TRACE
, ("Status (0x%X).\n", Status
));
367 MiniportHalt((NDIS_HANDLE
)Adapter
);
371 NDIS_DbgPrint(MID_TRACE
, ("BOARDDATA:\n"));
372 for (i
= 0; i
< 4; i
++) {
373 NDIS_DbgPrint(MID_TRACE
, ("%02X %02X %02X %02X\n",
374 Adapter
->SAPROM
[i
*4+0],
375 Adapter
->SAPROM
[i
*4+1],
376 Adapter
->SAPROM
[i
*4+2],
377 Adapter
->SAPROM
[i
*4+3]));
380 /* Setup adapter structure */
381 Adapter
->TXStart
= ((ULONG_PTR
)Adapter
->RamBase
>> 8);
382 Adapter
->TXCount
= DRIVER_DEFAULT_TX_BUFFER_COUNT
;
383 Adapter
->TXFree
= DRIVER_DEFAULT_TX_BUFFER_COUNT
;
384 Adapter
->TXCurrent
= -1;
385 Adapter
->PageStart
= Adapter
->TXStart
+ Adapter
->TXCount
;
386 Adapter
->PageStop
= Adapter
->TXStart
+ (Adapter
->RamSize
>> 8);
388 /* Initialize multicast address mask to accept all */
389 for (i
= 0; i
< 8; i
++)
390 Adapter
->MulticastAddressMask
[i
] = 0xFF;
395 NDIS_DbgPrint(MID_TRACE
, ("TXStart (0x%X) TXCount (0x%X) PageStart (0x%X)\n",
398 Adapter
->PageStart
));
400 NDIS_DbgPrint(MID_TRACE
, ("PageStop (0x%X) CurrentPage (0x%X) NextPacket (0x%X).\n",
402 Adapter
->CurrentPage
,
403 Adapter
->NextPacket
));
405 /* Register the interrupt */
406 Status
= NdisMRegisterInterrupt(
408 MiniportAdapterHandle
,
409 Adapter
->InterruptVector
,
410 Adapter
->InterruptLevel
,
412 Adapter
->InterruptShared
,
413 Adapter
->InterruptMode
);
414 if (Status
!= NDIS_STATUS_SUCCESS
) {
415 NDIS_DbgPrint(MIN_TRACE
, ("Cannot register interrupt. Status (0x%X).\n", Status
));
416 MiniportHalt((NDIS_HANDLE
)Adapter
);
420 Adapter
->InterruptRegistered
= TRUE
;
426 /* Register the shutdown handler */
427 NdisMRegisterAdapterShutdownHandler(MiniportAdapterHandle
, Adapter
, MiniportShutdown
);
429 Adapter
->ShutdownHandlerRegistered
= TRUE
;
431 /* Add adapter to the global adapter list */
432 InsertTailList(&DriverInfo
.AdapterListHead
, &Adapter
->ListEntry
);
434 NDIS_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
436 return NDIS_STATUS_SUCCESS
;
440 static VOID STDCALL
MiniportISR(
441 OUT PBOOLEAN InterruptRecognized
,
442 OUT PBOOLEAN QueueMiniportHandleInterrupt
,
443 IN NDIS_HANDLE MiniportAdapterContext
)
445 * FUNCTION: Interrupt Service Routine for controlled adapters
447 * InterruptRecognized = Address of buffer to place wether
448 * the adapter generated the interrupt
449 * QueueMiniportHandleInterrupt = Address of buffer to place wether
450 * MiniportHandleInterrupt should be called
451 * MiniportAdapterContext = Pointer to adapter context area
453 * All pending interrupts are handled
456 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
458 NICDisableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
460 *InterruptRecognized
= TRUE
;
461 *QueueMiniportHandleInterrupt
= TRUE
;
465 static NDIS_STATUS STDCALL
MiniportQueryInformation(
466 IN NDIS_HANDLE MiniportAdapterContext
,
468 IN PVOID InformationBuffer
,
469 IN ULONG InformationBufferLength
,
470 OUT PULONG BytesWritten
,
471 OUT PULONG BytesNeeded
)
473 * FUNCTION: Handler to process queries
475 * MiniportAdapterContext = Pointer to adapter context area
476 * Oid = OID code designating query operation
477 * InformationBuffer = Address of return buffer
478 * InformationBufferLength = Length of return buffer
479 * BytesWritten = Address of buffer to place number of bytes returned
480 * BytesNeeded = Address of buffer to place number of bytes needed
481 * in InformationBuffer for specified OID
483 * Status of operation
490 USHORT GenericUSHORT
;
491 NDIS_MEDIUM Medium
= NdisMedium802_3
;
492 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
494 ASSERT_IRQL_EQUAL(DISPATCH_LEVEL
);
496 NDIS_DbgPrint(MAX_TRACE
, ("Called. Oid (0x%X).\n", Oid
));
498 Status
= NDIS_STATUS_SUCCESS
;
499 CopyFrom
= (PVOID
)&GenericULONG
;
500 CopySize
= sizeof(ULONG
);
503 case OID_GEN_SUPPORTED_LIST
:
504 CopyFrom
= (PVOID
)&MiniportOIDList
;
505 CopySize
= sizeof(MiniportOIDList
);
507 case OID_GEN_HARDWARE_STATUS
:
508 GenericULONG
= (ULONG
)NdisHardwareStatusReady
;
510 case OID_GEN_MEDIA_SUPPORTED
:
511 case OID_GEN_MEDIA_IN_USE
:
512 CopyFrom
= (PVOID
)&Medium
;
513 CopySize
= sizeof(NDIS_MEDIUM
);
515 case OID_GEN_MAXIMUM_LOOKAHEAD
:
516 GenericULONG
= DRIVER_MAXIMUM_LOOKAHEAD
;
518 case OID_GEN_MAXIMUM_FRAME_SIZE
:
519 GenericULONG
= DRIVER_FRAME_SIZE
- DRIVER_HEADER_SIZE
;
521 case OID_GEN_LINK_SPEED
:
522 GenericULONG
= 100000; /* 10Mbps */
524 case OID_GEN_TRANSMIT_BUFFER_SPACE
:
525 GenericULONG
= Adapter
->TXCount
* DRIVER_BLOCK_SIZE
;
527 case OID_GEN_RECEIVE_BUFFER_SPACE
:
528 GenericULONG
= Adapter
->RamSize
-
529 (ULONG_PTR
)Adapter
->RamBase
-
530 (Adapter
->TXCount
* DRIVER_BLOCK_SIZE
);
532 case OID_GEN_TRANSMIT_BLOCK_SIZE
:
533 GenericULONG
= DRIVER_BLOCK_SIZE
;
535 case OID_GEN_RECEIVE_BLOCK_SIZE
:
536 GenericULONG
= DRIVER_BLOCK_SIZE
;
538 case OID_GEN_VENDOR_ID
:
539 NdisMoveMemory(&GenericULONG
, &Adapter
->PermanentAddress
, 3);
540 GenericULONG
&= 0xFFFFFF00;
541 GenericULONG
|= 0x01;
543 case OID_GEN_VENDOR_DESCRIPTION
:
544 CopyFrom
= (PVOID
)&DRIVER_VENDOR_DESCRIPTION
;
545 CopySize
= sizeof(DRIVER_VENDOR_DESCRIPTION
);
547 case OID_GEN_VENDOR_DRIVER_VERSION
:
548 GenericUSHORT
= (USHORT
)DRIVER_VENDOR_DRIVER_VERSION
;
549 CopyFrom
= (PVOID
)&GenericUSHORT
;
550 CopySize
= sizeof(USHORT
);
552 case OID_GEN_CURRENT_PACKET_FILTER
:
553 GenericULONG
= Adapter
->PacketFilter
;
555 case OID_GEN_CURRENT_LOOKAHEAD
:
556 GenericULONG
= Adapter
->LookaheadSize
;
558 case OID_GEN_DRIVER_VERSION
:
559 GenericUSHORT
= ((USHORT
)DRIVER_NDIS_MAJOR_VERSION
<< 8) | DRIVER_NDIS_MINOR_VERSION
;
560 CopyFrom
= (PVOID
)&GenericUSHORT
;
561 CopySize
= sizeof(USHORT
);
563 case OID_GEN_MAXIMUM_TOTAL_SIZE
:
564 GenericULONG
= DRIVER_FRAME_SIZE
;
566 case OID_GEN_PROTOCOL_OPTIONS
:
567 NDIS_DbgPrint(MID_TRACE
, ("OID_GEN_PROTOCOL_OPTIONS.\n"));
568 Status
= NDIS_STATUS_NOT_SUPPORTED
;
570 case OID_GEN_MAC_OPTIONS
:
571 GenericULONG
= NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA
|
572 NDIS_MAC_OPTION_RECEIVE_SERIALIZED
|
573 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND
|
574 NDIS_MAC_OPTION_NO_LOOPBACK
;
576 case OID_GEN_MEDIA_CONNECT_STATUS
:
577 GenericULONG
= (ULONG
)NdisMediaStateConnected
;
579 case OID_GEN_MAXIMUM_SEND_PACKETS
:
582 case OID_802_3_PERMANENT_ADDRESS
:
583 CopyFrom
= (PVOID
)&Adapter
->PermanentAddress
;
584 CopySize
= DRIVER_LENGTH_OF_ADDRESS
;
586 case OID_802_3_CURRENT_ADDRESS
:
587 CopyFrom
= (PVOID
)&Adapter
->StationAddress
;
588 CopySize
= DRIVER_LENGTH_OF_ADDRESS
;
590 case OID_802_3_MULTICAST_LIST
:
591 NDIS_DbgPrint(MID_TRACE
, ("OID_802_3_MULTICAST_LIST.\n"));
592 Status
= NDIS_STATUS_NOT_SUPPORTED
;
594 case OID_802_3_MAXIMUM_LIST_SIZE
:
595 GenericULONG
= Adapter
->MaxMulticastListSize
;
597 case OID_802_3_MAC_OPTIONS
:
598 NDIS_DbgPrint(MID_TRACE
, ("OID_802_3_MAC_OPTIONS.\n"));
599 Status
= NDIS_STATUS_NOT_SUPPORTED
;
602 NDIS_DbgPrint(MIN_TRACE
, ("Unknown OID (0x%X).\n", Oid
));
603 Status
= NDIS_STATUS_INVALID_OID
;
607 if (Status
== NDIS_STATUS_SUCCESS
) {
608 if (CopySize
> InformationBufferLength
) {
609 *BytesNeeded
= (CopySize
- InformationBufferLength
);
611 Status
= NDIS_STATUS_INVALID_LENGTH
;
613 NdisMoveMemory(InformationBuffer
, CopyFrom
, CopySize
);
614 *BytesWritten
= CopySize
;
619 NDIS_DbgPrint(MAX_TRACE
, ("Leaving. Status is (0x%X).\n", Status
));
625 static NDIS_STATUS STDCALL
MiniportReconfigure(
626 OUT PNDIS_STATUS OpenErrorStatus
,
627 IN NDIS_HANDLE MiniportAdapterContext
,
628 IN NDIS_HANDLE WrapperConfigurationContext
)
630 * FUNCTION: Reconfigures an adapter
632 * OpenErrorStatus = Address of buffer to place additional status information
633 * MiniportAdapterContext = Pointer to adapter context area
634 * WrapperConfigurationContext = Handle used to identify configuration context
636 * Status of operation
638 * Never called by NDIS library
641 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
643 return NDIS_STATUS_FAILURE
;
648 static NDIS_STATUS STDCALL
MiniportReset(
649 OUT PBOOLEAN AddressingReset
,
650 IN NDIS_HANDLE MiniportAdapterContext
)
652 * FUNCTION: Resets an adapter
654 * AddressingReset = Address of a buffer to place value indicating
655 * wether NDIS library should call MiniportSetInformation
656 * to restore addressing information
657 * MiniportAdapterContext = Pointer to adapter context area
659 * Status of operation
662 ASSERT_IRQL_EQUAL(DISPATCH_LEVEL
);
664 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
666 return NDIS_STATUS_FAILURE
;
670 static NDIS_STATUS STDCALL
MiniportSend(
671 IN NDIS_HANDLE MiniportAdapterContext
,
672 IN PNDIS_PACKET Packet
,
675 * FUNCTION: Transmits a packet
677 * MiniportAdapterContext = Pointer to adapter context area
678 * Packet = Pointer to a packet descriptor specifying
679 * the data to be transmitted
680 * Flags = Specifies optional packet flags
682 * Status of operation
685 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
687 ASSERT_IRQL_EQUAL(DISPATCH_LEVEL
);
690 NDIS_DbgPrint(MID_TRACE
, ("Queueing packet.\n"));
692 /* Queue the packet on the transmit queue */
693 RESERVED(Packet
)->Next
= NULL
;
694 if (Adapter
->TXQueueHead
== NULL
) {
695 Adapter
->TXQueueHead
= Packet
;
697 RESERVED(Adapter
->TXQueueTail
)->Next
= Packet
;
700 Adapter
->TXQueueTail
= Packet
;
702 /* Transmit the packet */
703 NICTransmit(Adapter
);
705 return NDIS_STATUS_PENDING
;
707 return NDIS_STATUS_SUCCESS
;
712 static NDIS_STATUS STDCALL
MiniportSetInformation(
713 IN NDIS_HANDLE MiniportAdapterContext
,
715 IN PVOID InformationBuffer
,
716 IN ULONG InformationBufferLength
,
717 OUT PULONG BytesRead
,
718 OUT PULONG BytesNeeded
)
720 * FUNCTION: Changes state information in the driver
722 * MiniportAdapterContext = Pointer to adapter context area
723 * Oid = OID code designating set operation
724 * InformationBuffer = Pointer to buffer with state information
725 * InformationBufferLength = Length of InformationBuffer
726 * BytesRead = Address of buffer to place number of bytes read
727 * BytesNeeded = Address of buffer to place number of extra bytes
728 * needed in InformationBuffer for specified OID
730 * Status of operation
734 NDIS_STATUS Status
= NDIS_STATUS_SUCCESS
;
735 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
737 ASSERT_IRQL_EQUAL(DISPATCH_LEVEL
);
739 NDIS_DbgPrint(MAX_TRACE
, ("Called. Oid (0x%X).\n", Oid
));
742 case OID_GEN_CURRENT_PACKET_FILTER
:
744 if (InformationBufferLength
< sizeof(ULONG
)) {
746 *BytesNeeded
= sizeof(ULONG
) - InformationBufferLength
;
747 Status
= NDIS_STATUS_INVALID_LENGTH
;
751 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
752 /* Check for properties the driver don't support */
754 (NDIS_PACKET_TYPE_ALL_FUNCTIONAL
|
755 NDIS_PACKET_TYPE_FUNCTIONAL
|
756 NDIS_PACKET_TYPE_GROUP
|
757 NDIS_PACKET_TYPE_MAC_FRAME
|
758 NDIS_PACKET_TYPE_SMT
|
759 NDIS_PACKET_TYPE_SOURCE_ROUTING
)) {
762 Status
= NDIS_STATUS_NOT_SUPPORTED
;
766 Adapter
->PacketFilter
= GenericULONG
;
768 /* FIXME: Set filter on hardware */
771 case OID_GEN_CURRENT_LOOKAHEAD
:
773 if (InformationBufferLength
< sizeof(ULONG
)) {
775 *BytesNeeded
= sizeof(ULONG
) - InformationBufferLength
;
776 Status
= NDIS_STATUS_INVALID_LENGTH
;
780 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
781 if (GenericULONG
> DRIVER_MAXIMUM_LOOKAHEAD
)
782 Status
= NDIS_STATUS_INVALID_LENGTH
;
784 Adapter
->LookaheadSize
= GenericULONG
;
786 case OID_802_3_MULTICAST_LIST
:
787 /* Verify length. Must be multiplum of hardware address length */
788 if ((InformationBufferLength
% DRIVER_LENGTH_OF_ADDRESS
) != 0) {
791 Status
= NDIS_STATUS_INVALID_LENGTH
;
795 /* Set new multicast address list */
796 NdisMoveMemory(Adapter
->Addresses
, InformationBuffer
, InformationBufferLength
);
798 /* FIXME: Update hardware */
802 NDIS_DbgPrint(MIN_TRACE
, ("Invalid object ID (0x%X).\n", Oid
));
805 Status
= NDIS_STATUS_INVALID_OID
;
809 if (Status
== NDIS_STATUS_SUCCESS
) {
810 *BytesRead
= InformationBufferLength
;
814 NDIS_DbgPrint(MAX_TRACE
, ("Leaving. Status (0x%X).\n", Status
));
820 static NDIS_STATUS STDCALL
MiniportTransferData(
821 OUT PNDIS_PACKET Packet
,
822 OUT PUINT BytesTransferred
,
823 IN NDIS_HANDLE MiniportAdapterContext
,
824 IN NDIS_HANDLE MiniportReceiveContext
,
826 IN UINT BytesToTransfer
)
828 * FUNCTION: Transfers data from a received frame into an NDIS packet
830 * Packet = Address of packet to copy received data into
831 * BytesTransferred = Address of buffer to place number of bytes transmitted
832 * MiniportAdapterContext = Pointer to adapter context area
833 * MiniportReceiveContext = Pointer to receive context area (actually NULL)
834 * ByteOffset = Offset within received packet to begin copying
835 * BytesToTransfer = Number of bytes to copy into packet
837 * Status of operation
840 PNDIS_BUFFER DstBuffer
;
841 UINT BytesCopied
, BytesToCopy
, DstSize
;
846 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
848 ASSERT_IRQL_EQUAL(DISPATCH_LEVEL
);
850 NDIS_DbgPrint(MAX_TRACE
, ("Called. Packet (0x%X) ByteOffset (0x%X) BytesToTransfer (%d).\n",
851 Packet
, ByteOffset
, BytesToTransfer
));
853 if (BytesToTransfer
== 0) {
854 *BytesTransferred
= 0;
855 return NDIS_STATUS_SUCCESS
;
858 RecvStart
= Adapter
->PageStart
* DRIVER_BLOCK_SIZE
;
859 RecvStop
= Adapter
->PageStop
* DRIVER_BLOCK_SIZE
;
861 NdisQueryPacket(Packet
, NULL
, NULL
, &DstBuffer
, NULL
);
862 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
864 SrcData
= Adapter
->PacketOffset
+ sizeof(DISCARD_HEADER
) + ByteOffset
;
865 if (ByteOffset
+ sizeof(DISCARD_HEADER
) + BytesToTransfer
>
866 Adapter
->PacketHeader
.PacketLength
)
867 BytesToTransfer
= Adapter
->PacketHeader
.PacketLength
-
868 sizeof(DISCARD_HEADER
) - ByteOffset
;
870 /* Start copying the data */
873 BytesToCopy
= (DstSize
< BytesToTransfer
) ? DstSize
: BytesToTransfer
;
874 if (SrcData
+ BytesToCopy
> RecvStop
)
875 BytesToCopy
= (RecvStop
- SrcData
);
877 NICReadData(Adapter
, DstData
, SrcData
, BytesToCopy
);
879 BytesCopied
+= BytesToCopy
;
880 SrcData
+= BytesToCopy
;
881 DstData
= (PUCHAR
)((ULONG_PTR
) DstData
+ BytesToCopy
);
882 BytesToTransfer
-= BytesToCopy
;
883 if (BytesToTransfer
== 0)
886 DstSize
-= BytesToCopy
;
888 /* No more bytes in destination buffer. Proceed to
889 the next buffer in the destination buffer chain */
890 NdisGetNextBuffer(DstBuffer
, &DstBuffer
);
894 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
897 if (SrcData
== RecvStop
)
901 NDIS_DbgPrint(MID_TRACE
, ("Transferred (%d) bytes.\n", BytesToTransfer
));
903 *BytesTransferred
= BytesCopied
;
905 return NDIS_STATUS_SUCCESS
;
914 PDRIVER_OBJECT DriverObject
,
915 PUNICODE_STRING RegistryPath
)
917 * FUNCTION: Main driver entry point
919 * DriverObject = Pointer to a driver object for this driver
920 * RegistryPath = Registry node for configuration parameters
922 * Status of driver initialization
926 NDIS_HANDLE NdisWrapperHandle
;
927 NDIS_MINIPORT_CHARACTERISTICS Miniport
;
929 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
931 NdisZeroMemory(&Miniport
, sizeof(Miniport
));
932 Miniport
.MajorNdisVersion
= DRIVER_NDIS_MAJOR_VERSION
;
933 Miniport
.MinorNdisVersion
= DRIVER_NDIS_MINOR_VERSION
;
934 Miniport
.CheckForHangHandler
= MiniportCheckForHang
;
935 Miniport
.DisableInterruptHandler
= MiniportDisableInterrupt
;
936 Miniport
.EnableInterruptHandler
= MiniportEnableInterrupt
;
937 Miniport
.HaltHandler
= MiniportHalt
;
938 Miniport
.HandleInterruptHandler
= MiniportHandleInterrupt
;
939 Miniport
.InitializeHandler
= MiniportInitialize
;
940 Miniport
.ISRHandler
= MiniportISR
;
941 Miniport
.QueryInformationHandler
= MiniportQueryInformation
;
942 Miniport
.ReconfigureHandler
= MiniportReconfigure
;
943 Miniport
.ResetHandler
= MiniportReset
;
944 Miniport
.SendHandler
= MiniportSend
;
945 Miniport
.SetInformationHandler
= MiniportSetInformation
;
946 Miniport
.TransferDataHandler
= MiniportTransferData
;
948 NdisMInitializeWrapper(&NdisWrapperHandle
,
953 if (!NdisWrapperHandle
) {
954 NDIS_DbgPrint(MIN_TRACE
, ("NdisMInitializeWrapper() failed\n"));
955 return STATUS_UNSUCCESSFUL
;
958 DriverInfo
.NdisWrapperHandle
= NdisWrapperHandle
;
959 DriverInfo
.NdisMacHandle
= NULL
;
960 InitializeListHead(&DriverInfo
.AdapterListHead
);
962 Status
= NdisMRegisterMiniport(NdisWrapperHandle
,
964 sizeof(NDIS_MINIPORT_CHARACTERISTICS
));
965 if (Status
!= NDIS_STATUS_SUCCESS
) {
966 NDIS_DbgPrint(MIN_TRACE
, ("NdisMRegisterMiniport() failed with status code (0x%X).\n", Status
));
967 NdisTerminateWrapper(NdisWrapperHandle
, NULL
);
968 return STATUS_UNSUCCESSFUL
;
971 return STATUS_SUCCESS
;
975 /* while i'm here - some basic registry sanity checks */
978 NDIS_CONFIGURATION_PARAMETER ParameterValue
;
980 ParameterValue
.ParameterType
= NdisParameterInteger
;
981 ParameterValue
.ParameterData
.IntegerData
= 0x12345678;
982 NdisInitUnicodeString(&Keyword
, L
"DwordTest");
983 NdisWriteConfiguration(&Status
, ConfigurationHandle
, &Keyword
, &ParameterValue
);
985 if(Status
!= NDIS_STATUS_SUCCESS
)
987 DbgPrint("ne2000!MiniportInitialize: failed to set DwordTest: 0x%x\n", Status
);
991 DbgPrint("ne2000!MiniportInitialize: DwordTest successfully set\n");
993 NdisInitUnicodeString(&Keyword
, L
"StringTest");
994 ParameterValue
.ParameterType
= NdisParameterString
;
995 NdisInitUnicodeString(&ParameterValue
.ParameterData
.StringData
, L
"Testing123");
997 NdisWriteConfiguration(&Status
, ConfigurationHandle
, &Keyword
, &ParameterValue
);
999 if(Status
!= NDIS_STATUS_SUCCESS
)
1001 DbgPrint("ne2000!MiniportInitialize: failed to set StringTest: 0x%x\n", Status
);
1005 DbgPrint("ne2000!MiniportInitialize: StringTest successfully set\n");
1009 /* read back the test values */
1010 NDIS_CONFIGURATION_PARAMETER
*ParameterValue
= 0;
1012 NdisInitUnicodeString(&Keyword
, L
"DwordTest");
1013 NdisReadConfiguration(&Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterInteger
);
1015 if(Status
!= NDIS_STATUS_SUCCESS
)
1017 DbgPrint("ne2000!MiniportInitialize: failed to read DwordTest: 0x%x\n", Status
);
1021 if(ParameterValue
->ParameterData
.IntegerData
!= 0x12345678)
1023 DbgPrint("ne2000!MiniportInitialize: DwordTest value is wrong: 0x%x\n",
1024 ParameterValue
->ParameterData
.IntegerData
);
1028 DbgPrint("ne2000!MiniportInitialize: DwordTest value was correctly read\n");
1030 NdisInitUnicodeString(&Keyword
, L
"StringTest");
1031 NdisReadConfiguration(&Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterString
);
1033 if(Status
!= NDIS_STATUS_SUCCESS
)
1035 DbgPrint("ne2000!MiniportInitialize: failed to read StringTest: 0x%x\n", Status
);
1039 if(wcsncmp(ParameterValue
->ParameterData
.StringData
.Buffer
, L
"Testing123",
1040 wcslen(L
"Testing123")))
1042 DbgPrint("ne2000!MiniportInitialize: StringTest value is wrong: %wZ\n",
1043 &ParameterValue
->ParameterData
.StringData
);
1047 DbgPrint("ne2000!MiniportInitialize: StringTest value was correctly read\n");