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
15 PDRIVER_OBJECT DriverObject
,
16 PUNICODE_STRING RegistryPath
);
21 /* See debug.h for debug/trace constants */
22 ULONG DebugTraceLevel
= 0;
27 /* List of supported OIDs */
28 static ULONG MiniportOIDList
[] = {
29 OID_GEN_SUPPORTED_LIST
,
30 OID_GEN_HARDWARE_STATUS
,
31 OID_GEN_MEDIA_SUPPORTED
,
33 OID_GEN_MAXIMUM_LOOKAHEAD
,
34 OID_GEN_MAXIMUM_FRAME_SIZE
,
36 OID_GEN_TRANSMIT_BUFFER_SPACE
,
37 OID_GEN_RECEIVE_BUFFER_SPACE
,
38 OID_GEN_TRANSMIT_BLOCK_SIZE
,
39 OID_GEN_RECEIVE_BLOCK_SIZE
,
41 OID_GEN_VENDOR_DESCRIPTION
,
42 OID_GEN_VENDOR_DRIVER_VERSION
,
43 OID_GEN_CURRENT_PACKET_FILTER
,
44 OID_GEN_CURRENT_LOOKAHEAD
,
45 OID_GEN_DRIVER_VERSION
,
46 OID_GEN_MAXIMUM_TOTAL_SIZE
,
47 OID_GEN_PROTOCOL_OPTIONS
,
49 OID_GEN_MEDIA_CONNECT_STATUS
,
50 OID_GEN_MAXIMUM_SEND_PACKETS
,
51 OID_802_3_PERMANENT_ADDRESS
,
52 OID_802_3_CURRENT_ADDRESS
,
53 OID_802_3_MULTICAST_LIST
,
54 OID_802_3_MAXIMUM_LIST_SIZE
,
58 DRIVER_INFORMATION DriverInfo
= { NULL
, NULL
, { NULL
, NULL
} };
59 NDIS_PHYSICAL_ADDRESS HighestAcceptableMax
= NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
62 static BOOLEAN NTAPI
MiniportCheckForHang(
63 IN NDIS_HANDLE MiniportAdapterContext
)
65 * FUNCTION: Examines if an adapter has hung
67 * MiniportAdapterContext = Pointer to adapter context area
69 * TRUE if the adapter has hung, FALSE if not
72 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
78 static VOID NTAPI
MiniportDisableInterrupt(
79 IN NDIS_HANDLE MiniportAdapterContext
)
81 * FUNCTION: Disables interrupts from an adapter
83 * MiniportAdapterContext = Pointer to adapter context area
86 NDIS_DbgPrint(MAX_TRACE
, ("Called. (MiniportDisableInterrupt).\n"));
88 NICDisableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
93 static VOID NTAPI
MiniportEnableInterrupt(
94 IN NDIS_HANDLE MiniportAdapterContext
)
96 * FUNCTION: Enables interrupts from an adapter
98 * MiniportAdapterContext = Pointer to adapter context area
101 NDIS_DbgPrint(MAX_TRACE
, ("Called. (MiniportEnableInterrupt).\n"));
103 NICEnableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
108 static VOID NTAPI
MiniportHalt(
109 IN NDIS_HANDLE MiniportAdapterContext
)
111 * FUNCTION: Deallocates resources for and halts an adapter
113 * MiniportAdapterContext = Pointer to adapter context area
116 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
118 ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
120 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
125 /* Wait for any DPCs to complete. FIXME: Use something else */
126 NdisStallExecution(250000);
128 if (Adapter
->InterruptRegistered
)
129 /* Deregister interrupt */
130 NdisMDeregisterInterrupt(&Adapter
->Interrupt
);
132 if (Adapter
->IOPortRangeRegistered
)
133 /* Deregister I/O port range */
134 NdisMDeregisterIoPortRange(
135 Adapter
->MiniportAdapterHandle
,
136 Adapter
->IoBaseAddress
,
140 if (Adapter
->ShutdownHandlerRegistered
)
141 NdisMDeregisterAdapterShutdownHandler(Adapter
->MiniportAdapterHandle
);
143 /* Remove adapter from global adapter list */
144 if ((&Adapter
->ListEntry
)->Blink
!= NULL
) {
145 RemoveEntryList(&Adapter
->ListEntry
);
148 /* Free adapter context area */
149 NdisFreeMemory(Adapter
, sizeof(NIC_ADAPTER
), 0);
153 static VOID NTAPI
MiQueryResources(
154 OUT PNDIS_STATUS Status
,
155 IN PNIC_ADAPTER Adapter
,
156 IN NDIS_HANDLE WrapperConfigurationContext
)
158 PNDIS_RESOURCE_LIST AssignedResources
;
160 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
;
163 NdisMQueryAdapterResources(Status
,
164 WrapperConfigurationContext
,
167 if (*Status
== NDIS_STATUS_SUCCESS
)
170 *Status
= NdisAllocateMemory((PVOID
)&AssignedResources
,
173 HighestAcceptableMax
);
174 if (*Status
!= NDIS_STATUS_SUCCESS
)
177 NdisMQueryAdapterResources(Status
,
178 WrapperConfigurationContext
,
181 if (*Status
!= NDIS_STATUS_SUCCESS
)
184 for (i
= 0; i
< AssignedResources
->Count
; i
++)
186 Descriptor
= AssignedResources
->PartialDescriptors
+ i
;
187 switch (Descriptor
->Type
)
189 case CmResourceTypeInterrupt
:
190 Adapter
->InterruptLevel
= Descriptor
->u
.Interrupt
.Level
;
191 Adapter
->InterruptVector
= Descriptor
->u
.Interrupt
.Vector
;
192 Adapter
->InterruptShared
= (Descriptor
->ShareDisposition
== CmResourceShareShared
);
193 Adapter
->InterruptMode
= Descriptor
->Flags
& CM_RESOURCE_INTERRUPT_LATCHED
?
194 NdisInterruptLatched
: NdisInterruptLevelSensitive
;
196 case CmResourceTypePort
:
197 Adapter
->IoBaseAddress
= Descriptor
->u
.Port
.Start
.LowPart
;
205 MiniportShutdown(PVOID Context
)
208 NICStop((PNIC_ADAPTER
)Context
);
212 static NDIS_STATUS NTAPI
MiniportInitialize(
213 OUT PNDIS_STATUS OpenErrorStatus
,
214 OUT PUINT SelectedMediumIndex
,
215 IN PNDIS_MEDIUM MediumArray
,
216 IN UINT MediumArraySize
,
217 IN NDIS_HANDLE MiniportAdapterHandle
,
218 IN NDIS_HANDLE WrapperConfigurationContext
)
220 * FUNCTION: Adapter initialization function
222 * OpenErrorStatus = Address of buffer to place additional status information
223 * SelectedMediumIndex = Address of buffer to place selected medium index
224 * MediumArray = Pointer to an array of NDIS_MEDIUMs
225 * MediaArraySize = Number of elements in MediumArray
226 * MiniportAdapterHandle = Miniport adapter handle assigned by NDIS
227 * WrapperConfigurationContext = Handle used to identify configuration context
229 * Status of operation
234 PNIC_ADAPTER Adapter
;
235 NDIS_HANDLE ConfigurationHandle
;
236 UINT
*RegNetworkAddress
= 0;
237 UINT RegNetworkAddressLength
= 0;
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 UNICODE_STRING Keyword
;
286 NdisOpenConfiguration(&Status
, &ConfigurationHandle
, WrapperConfigurationContext
);
287 if (Status
== NDIS_STATUS_SUCCESS
)
289 NdisInitUnicodeString(&Keyword
, L
"Irq");
290 NdisReadConfiguration(&Status
, &ConfigurationParameter
, ConfigurationHandle
, &Keyword
, NdisParameterHexInteger
);
291 if(Status
== NDIS_STATUS_SUCCESS
)
293 NDIS_DbgPrint(MID_TRACE
,("NdisReadConfiguration for Irq returned successfully, irq 0x%x\n",
294 ConfigurationParameter
->ParameterData
.IntegerData
));
295 Adapter
->InterruptLevel
=
296 Adapter
->InterruptVector
= ConfigurationParameter
->ParameterData
.IntegerData
;
299 NdisInitUnicodeString(&Keyword
, L
"Port");
300 NdisReadConfiguration(&Status
, &ConfigurationParameter
, ConfigurationHandle
, &Keyword
, NdisParameterHexInteger
);
301 if(Status
== NDIS_STATUS_SUCCESS
)
303 NDIS_DbgPrint(MID_TRACE
,("NdisReadConfiguration for Port returned successfully, port 0x%x\n",
304 ConfigurationParameter
->ParameterData
.IntegerData
));
305 Adapter
->IoBaseAddress
= ConfigurationParameter
->ParameterData
.IntegerData
;
308 NdisCloseConfiguration(ConfigurationHandle
);
312 NDIS_DbgPrint(MIN_TRACE
,("NdisOpenConfiguration returned error 0x%x\n", Status
));
317 if (!NICCheck(Adapter
)) {
318 NDIS_DbgPrint(MID_TRACE
, ("No adapter found at (0x%X).\n", Adapter
->IoBaseAddress
));
319 NdisFreeMemory(Adapter
, sizeof(NIC_ADAPTER
), 0);
320 return NDIS_STATUS_ADAPTER_NOT_FOUND
;
322 NDIS_DbgPrint(MID_TRACE
, ("Adapter found at (0x%X).\n", Adapter
->IoBaseAddress
));
325 MiniportAdapterHandle
,
326 (NDIS_HANDLE
)Adapter
,
330 Status
= NdisMRegisterIoPortRange(
331 (PVOID
*)&Adapter
->IOBase
,
332 MiniportAdapterHandle
,
333 Adapter
->IoBaseAddress
,
336 if (Status
!= NDIS_STATUS_SUCCESS
) {
337 NDIS_DbgPrint(MIN_TRACE
, ("Cannot register port range. Status (0x%X).\n", Status
));
338 MiniportHalt((NDIS_HANDLE
)Adapter
);
342 Adapter
->IOPortRangeRegistered
= TRUE
;
346 Status
= NICInitialize(Adapter
);
347 if (Status
!= NDIS_STATUS_SUCCESS
) {
348 NDIS_DbgPrint(MIN_TRACE
,("No NE2000 or compatible network adapter found at address 0x%X.\n",
351 NDIS_DbgPrint(MID_TRACE
, ("Status (0x%X).\n", Status
));
352 MiniportHalt((NDIS_HANDLE
)Adapter
);
356 NdisOpenConfiguration(&Status
, &ConfigurationHandle
, WrapperConfigurationContext
);
357 if (Status
== NDIS_STATUS_SUCCESS
)
359 NdisReadNetworkAddress(&Status
, (PVOID
*)&RegNetworkAddress
, &RegNetworkAddressLength
, ConfigurationHandle
);
360 if(Status
== NDIS_STATUS_SUCCESS
&& RegNetworkAddressLength
== DRIVER_LENGTH_OF_ADDRESS
)
363 NDIS_DbgPrint(MID_TRACE
,("NdisReadNetworkAddress returned successfully, address %x:%x:%x:%x:%x:%x\n",
364 RegNetworkAddress
[0], RegNetworkAddress
[1], RegNetworkAddress
[2], RegNetworkAddress
[3],
365 RegNetworkAddress
[4], RegNetworkAddress
[5]));
366 for(i
= 0; i
< DRIVER_LENGTH_OF_ADDRESS
; i
++)
367 Adapter
->StationAddress
[i
] = RegNetworkAddress
[i
];
370 NdisCloseConfiguration(ConfigurationHandle
);
373 if (Status
!= NDIS_STATUS_SUCCESS
|| RegNetworkAddressLength
!= DRIVER_LENGTH_OF_ADDRESS
)
376 for (i
= 0; i
< DRIVER_LENGTH_OF_ADDRESS
; i
++)
377 Adapter
->StationAddress
[i
] = Adapter
->PermanentAddress
[i
];
380 NDIS_DbgPrint(MID_TRACE
, ("BOARDDATA:\n"));
381 for (i
= 0; i
< 4; i
++) {
382 NDIS_DbgPrint(MID_TRACE
, ("%02X %02X %02X %02X\n",
383 Adapter
->SAPROM
[i
*4+0],
384 Adapter
->SAPROM
[i
*4+1],
385 Adapter
->SAPROM
[i
*4+2],
386 Adapter
->SAPROM
[i
*4+3]));
389 /* Setup adapter structure */
390 Adapter
->TXStart
= ((ULONG_PTR
)Adapter
->RamBase
>> 8);
391 Adapter
->TXCount
= DRIVER_DEFAULT_TX_BUFFER_COUNT
;
392 Adapter
->TXFree
= DRIVER_DEFAULT_TX_BUFFER_COUNT
;
393 Adapter
->TXCurrent
= -1;
394 Adapter
->PageStart
= Adapter
->TXStart
+ Adapter
->TXCount
;
395 Adapter
->PageStop
= Adapter
->TXStart
+ (Adapter
->RamSize
>> 8);
397 /* Initialize multicast address mask to accept all */
398 for (i
= 0; i
< 8; i
++)
399 Adapter
->MulticastAddressMask
[i
] = 0xFF;
404 NDIS_DbgPrint(MID_TRACE
, ("TXStart (0x%X) TXCount (0x%X) PageStart (0x%X)\n",
407 Adapter
->PageStart
));
409 NDIS_DbgPrint(MID_TRACE
, ("PageStop (0x%X) CurrentPage (0x%X) NextPacket (0x%X).\n",
411 Adapter
->CurrentPage
,
412 Adapter
->NextPacket
));
414 /* Register the interrupt */
415 Status
= NdisMRegisterInterrupt(
417 MiniportAdapterHandle
,
418 Adapter
->InterruptVector
,
419 Adapter
->InterruptLevel
,
421 Adapter
->InterruptShared
,
422 Adapter
->InterruptMode
);
423 if (Status
!= NDIS_STATUS_SUCCESS
) {
424 NDIS_DbgPrint(MIN_TRACE
, ("Cannot register interrupt. Status (0x%X).\n", Status
));
425 MiniportHalt((NDIS_HANDLE
)Adapter
);
429 Adapter
->InterruptRegistered
= TRUE
;
435 /* Register the shutdown handler */
436 NdisMRegisterAdapterShutdownHandler(MiniportAdapterHandle
, Adapter
, MiniportShutdown
);
438 Adapter
->ShutdownHandlerRegistered
= TRUE
;
440 /* Add adapter to the global adapter list */
441 InsertTailList(&DriverInfo
.AdapterListHead
, &Adapter
->ListEntry
);
443 NDIS_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
445 return NDIS_STATUS_SUCCESS
;
449 static VOID NTAPI
MiniportISR(
450 OUT PBOOLEAN InterruptRecognized
,
451 OUT PBOOLEAN QueueMiniportHandleInterrupt
,
452 IN NDIS_HANDLE MiniportAdapterContext
)
454 * FUNCTION: Interrupt Service Routine for controlled adapters
456 * InterruptRecognized = Address of buffer to place wether
457 * the adapter generated the interrupt
458 * QueueMiniportHandleInterrupt = Address of buffer to place wether
459 * MiniportHandleInterrupt should be called
460 * MiniportAdapterContext = Pointer to adapter context area
462 * All pending interrupts are handled
465 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
467 NICDisableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
469 *InterruptRecognized
= TRUE
;
470 *QueueMiniportHandleInterrupt
= TRUE
;
474 static NDIS_STATUS NTAPI
MiniportQueryInformation(
475 IN NDIS_HANDLE MiniportAdapterContext
,
477 IN PVOID InformationBuffer
,
478 IN ULONG InformationBufferLength
,
479 OUT PULONG BytesWritten
,
480 OUT PULONG BytesNeeded
)
482 * FUNCTION: Handler to process queries
484 * MiniportAdapterContext = Pointer to adapter context area
485 * Oid = OID code designating query operation
486 * InformationBuffer = Address of return buffer
487 * InformationBufferLength = Length of return buffer
488 * BytesWritten = Address of buffer to place number of bytes returned
489 * BytesNeeded = Address of buffer to place number of bytes needed
490 * in InformationBuffer for specified OID
492 * Status of operation
499 USHORT GenericUSHORT
;
500 NDIS_MEDIUM Medium
= NdisMedium802_3
;
501 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
503 NDIS_DbgPrint(MAX_TRACE
, ("Called. Oid (0x%X).\n", Oid
));
505 Status
= NDIS_STATUS_SUCCESS
;
506 CopyFrom
= (PVOID
)&GenericULONG
;
507 CopySize
= sizeof(ULONG
);
510 case OID_GEN_SUPPORTED_LIST
:
511 CopyFrom
= (PVOID
)&MiniportOIDList
;
512 CopySize
= sizeof(MiniportOIDList
);
514 case OID_GEN_HARDWARE_STATUS
:
515 GenericULONG
= (ULONG
)NdisHardwareStatusReady
;
517 case OID_GEN_MEDIA_SUPPORTED
:
518 case OID_GEN_MEDIA_IN_USE
:
519 CopyFrom
= (PVOID
)&Medium
;
520 CopySize
= sizeof(NDIS_MEDIUM
);
522 case OID_GEN_MAXIMUM_LOOKAHEAD
:
523 GenericULONG
= DRIVER_MAXIMUM_LOOKAHEAD
;
525 case OID_GEN_MAXIMUM_FRAME_SIZE
:
526 GenericULONG
= DRIVER_FRAME_SIZE
- DRIVER_HEADER_SIZE
;
528 case OID_GEN_LINK_SPEED
:
529 GenericULONG
= 100000; /* 10Mbps */
531 case OID_GEN_TRANSMIT_BUFFER_SPACE
:
532 GenericULONG
= Adapter
->TXCount
* DRIVER_BLOCK_SIZE
;
534 case OID_GEN_RECEIVE_BUFFER_SPACE
:
535 GenericULONG
= Adapter
->RamSize
-
536 (ULONG_PTR
)Adapter
->RamBase
-
537 (Adapter
->TXCount
* DRIVER_BLOCK_SIZE
);
539 case OID_GEN_TRANSMIT_BLOCK_SIZE
:
540 GenericULONG
= DRIVER_BLOCK_SIZE
;
542 case OID_GEN_RECEIVE_BLOCK_SIZE
:
543 GenericULONG
= DRIVER_BLOCK_SIZE
;
545 case OID_GEN_VENDOR_ID
:
546 NdisMoveMemory(&GenericULONG
, &Adapter
->PermanentAddress
, 3);
547 GenericULONG
&= 0xFFFFFF00;
548 GenericULONG
|= 0x01;
550 case OID_GEN_VENDOR_DESCRIPTION
:
551 CopyFrom
= (PVOID
)&DRIVER_VENDOR_DESCRIPTION
;
552 CopySize
= sizeof(DRIVER_VENDOR_DESCRIPTION
);
554 case OID_GEN_VENDOR_DRIVER_VERSION
:
555 GenericUSHORT
= (USHORT
)DRIVER_VENDOR_DRIVER_VERSION
;
556 CopyFrom
= (PVOID
)&GenericUSHORT
;
557 CopySize
= sizeof(USHORT
);
559 case OID_GEN_CURRENT_PACKET_FILTER
:
560 GenericULONG
= Adapter
->PacketFilter
;
562 case OID_GEN_CURRENT_LOOKAHEAD
:
563 GenericULONG
= Adapter
->LookaheadSize
;
565 case OID_GEN_DRIVER_VERSION
:
566 GenericUSHORT
= ((USHORT
)DRIVER_NDIS_MAJOR_VERSION
<< 8) | DRIVER_NDIS_MINOR_VERSION
;
567 CopyFrom
= (PVOID
)&GenericUSHORT
;
568 CopySize
= sizeof(USHORT
);
570 case OID_GEN_MAXIMUM_TOTAL_SIZE
:
571 GenericULONG
= DRIVER_FRAME_SIZE
;
573 case OID_GEN_PROTOCOL_OPTIONS
:
574 NDIS_DbgPrint(MID_TRACE
, ("OID_GEN_PROTOCOL_OPTIONS.\n"));
575 Status
= NDIS_STATUS_NOT_SUPPORTED
;
577 case OID_GEN_MAC_OPTIONS
:
578 GenericULONG
= NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA
|
579 NDIS_MAC_OPTION_RECEIVE_SERIALIZED
|
580 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND
|
581 NDIS_MAC_OPTION_NO_LOOPBACK
;
583 case OID_GEN_MEDIA_CONNECT_STATUS
:
584 GenericULONG
= (ULONG
)NdisMediaStateConnected
;
586 case OID_GEN_MAXIMUM_SEND_PACKETS
:
589 case OID_802_3_PERMANENT_ADDRESS
:
590 CopyFrom
= (PVOID
)&Adapter
->PermanentAddress
;
591 CopySize
= DRIVER_LENGTH_OF_ADDRESS
;
593 case OID_802_3_CURRENT_ADDRESS
:
594 CopyFrom
= (PVOID
)&Adapter
->StationAddress
;
595 CopySize
= DRIVER_LENGTH_OF_ADDRESS
;
597 case OID_802_3_MULTICAST_LIST
:
598 NDIS_DbgPrint(MID_TRACE
, ("OID_802_3_MULTICAST_LIST.\n"));
599 Status
= NDIS_STATUS_NOT_SUPPORTED
;
601 case OID_802_3_MAXIMUM_LIST_SIZE
:
602 GenericULONG
= Adapter
->MaxMulticastListSize
;
604 case OID_802_3_MAC_OPTIONS
:
605 NDIS_DbgPrint(MID_TRACE
, ("OID_802_3_MAC_OPTIONS.\n"));
606 Status
= NDIS_STATUS_NOT_SUPPORTED
;
609 NDIS_DbgPrint(MIN_TRACE
, ("Unknown OID (0x%X).\n", Oid
));
610 Status
= NDIS_STATUS_INVALID_OID
;
614 if (Status
== NDIS_STATUS_SUCCESS
) {
615 if (CopySize
> InformationBufferLength
) {
616 *BytesNeeded
= (CopySize
- InformationBufferLength
);
618 Status
= NDIS_STATUS_INVALID_LENGTH
;
620 NdisMoveMemory(InformationBuffer
, CopyFrom
, CopySize
);
621 *BytesWritten
= CopySize
;
626 NDIS_DbgPrint(MAX_TRACE
, ("Leaving. Status is (0x%X).\n", Status
));
632 static NDIS_STATUS NTAPI
MiniportReconfigure(
633 OUT PNDIS_STATUS OpenErrorStatus
,
634 IN NDIS_HANDLE MiniportAdapterContext
,
635 IN NDIS_HANDLE WrapperConfigurationContext
)
637 * FUNCTION: Reconfigures an adapter
639 * OpenErrorStatus = Address of buffer to place additional status information
640 * MiniportAdapterContext = Pointer to adapter context area
641 * WrapperConfigurationContext = Handle used to identify configuration context
643 * Status of operation
645 * Never called by NDIS library
648 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
650 return NDIS_STATUS_FAILURE
;
655 static NDIS_STATUS NTAPI
MiniportReset(
656 OUT PBOOLEAN AddressingReset
,
657 IN NDIS_HANDLE MiniportAdapterContext
)
659 * FUNCTION: Resets an adapter
661 * AddressingReset = Address of a buffer to place value indicating
662 * wether NDIS library should call MiniportSetInformation
663 * to restore addressing information
664 * MiniportAdapterContext = Pointer to adapter context area
666 * Status of operation
669 NDIS_STATUS NdisStatus
= NDIS_STATUS_SUCCESS
;
671 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
674 NdisStatus
= NICReset((PNIC_ADAPTER
)MiniportAdapterContext
);
677 *AddressingReset
= TRUE
;
683 static NDIS_STATUS NTAPI
MiniportSend(
684 IN NDIS_HANDLE MiniportAdapterContext
,
685 IN PNDIS_PACKET Packet
,
688 * FUNCTION: Transmits a packet
690 * MiniportAdapterContext = Pointer to adapter context area
691 * Packet = Pointer to a packet descriptor specifying
692 * the data to be transmitted
693 * Flags = Specifies optional packet flags
695 * Status of operation
698 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
700 ASSERT_IRQL_EQUAL(DISPATCH_LEVEL
);
703 NDIS_DbgPrint(MID_TRACE
, ("Queueing packet.\n"));
705 /* Queue the packet on the transmit queue */
706 RESERVED(Packet
)->Next
= NULL
;
707 if (Adapter
->TXQueueHead
== NULL
) {
708 Adapter
->TXQueueHead
= Packet
;
710 RESERVED(Adapter
->TXQueueTail
)->Next
= Packet
;
713 Adapter
->TXQueueTail
= Packet
;
715 /* Transmit the packet */
716 NICTransmit(Adapter
);
718 return NDIS_STATUS_PENDING
;
720 return NDIS_STATUS_SUCCESS
;
725 static NDIS_STATUS NTAPI
MiniportSetInformation(
726 IN NDIS_HANDLE MiniportAdapterContext
,
728 IN PVOID InformationBuffer
,
729 IN ULONG InformationBufferLength
,
730 OUT PULONG BytesRead
,
731 OUT PULONG BytesNeeded
)
733 * FUNCTION: Changes state information in the driver
735 * MiniportAdapterContext = Pointer to adapter context area
736 * Oid = OID code designating set operation
737 * InformationBuffer = Pointer to buffer with state information
738 * InformationBufferLength = Length of InformationBuffer
739 * BytesRead = Address of buffer to place number of bytes read
740 * BytesNeeded = Address of buffer to place number of extra bytes
741 * needed in InformationBuffer for specified OID
743 * Status of operation
747 NDIS_STATUS Status
= NDIS_STATUS_SUCCESS
;
748 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
750 NDIS_DbgPrint(MAX_TRACE
, ("Called. Oid (0x%X).\n", Oid
));
753 case OID_GEN_CURRENT_PACKET_FILTER
:
755 if (InformationBufferLength
< sizeof(ULONG
)) {
757 *BytesNeeded
= sizeof(ULONG
) - InformationBufferLength
;
758 Status
= NDIS_STATUS_INVALID_LENGTH
;
762 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
763 /* Check for properties the driver don't support */
765 (NDIS_PACKET_TYPE_ALL_FUNCTIONAL
|
766 NDIS_PACKET_TYPE_FUNCTIONAL
|
767 NDIS_PACKET_TYPE_GROUP
|
768 NDIS_PACKET_TYPE_MAC_FRAME
|
769 NDIS_PACKET_TYPE_SMT
|
770 NDIS_PACKET_TYPE_SOURCE_ROUTING
)) {
773 Status
= NDIS_STATUS_NOT_SUPPORTED
;
777 Adapter
->PacketFilter
= GenericULONG
;
779 /* FIXME: Set filter on hardware */
782 case OID_GEN_CURRENT_LOOKAHEAD
:
784 if (InformationBufferLength
< sizeof(ULONG
)) {
786 *BytesNeeded
= sizeof(ULONG
) - InformationBufferLength
;
787 Status
= NDIS_STATUS_INVALID_LENGTH
;
791 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
792 if (GenericULONG
> DRIVER_MAXIMUM_LOOKAHEAD
)
793 Status
= NDIS_STATUS_INVALID_LENGTH
;
795 Adapter
->LookaheadSize
= GenericULONG
;
797 case OID_802_3_MULTICAST_LIST
:
798 /* Verify length. Must be multiplum of hardware address length */
799 if ((InformationBufferLength
% DRIVER_LENGTH_OF_ADDRESS
) != 0) {
802 Status
= NDIS_STATUS_INVALID_LENGTH
;
806 /* Set new multicast address list */
807 NdisMoveMemory(Adapter
->Addresses
, InformationBuffer
, InformationBufferLength
);
809 /* FIXME: Update hardware */
813 NDIS_DbgPrint(MIN_TRACE
, ("Invalid object ID (0x%X).\n", Oid
));
816 Status
= NDIS_STATUS_INVALID_OID
;
820 if (Status
== NDIS_STATUS_SUCCESS
) {
821 *BytesRead
= InformationBufferLength
;
825 NDIS_DbgPrint(MAX_TRACE
, ("Leaving. Status (0x%X).\n", Status
));
831 static NDIS_STATUS NTAPI
MiniportTransferData(
832 OUT PNDIS_PACKET Packet
,
833 OUT PUINT BytesTransferred
,
834 IN NDIS_HANDLE MiniportAdapterContext
,
835 IN NDIS_HANDLE MiniportReceiveContext
,
837 IN UINT BytesToTransfer
)
839 * FUNCTION: Transfers data from a received frame into an NDIS packet
841 * Packet = Address of packet to copy received data into
842 * BytesTransferred = Address of buffer to place number of bytes transmitted
843 * MiniportAdapterContext = Pointer to adapter context area
844 * MiniportReceiveContext = Pointer to receive context area (actually NULL)
845 * ByteOffset = Offset within received packet to begin copying
846 * BytesToTransfer = Number of bytes to copy into packet
848 * Status of operation
851 PNDIS_BUFFER DstBuffer
;
852 UINT BytesCopied
, BytesToCopy
, DstSize
;
857 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
859 NDIS_DbgPrint(MAX_TRACE
, ("Called. Packet (0x%X) ByteOffset (0x%X) BytesToTransfer (%d).\n",
860 Packet
, ByteOffset
, BytesToTransfer
));
862 if (BytesToTransfer
== 0) {
863 *BytesTransferred
= 0;
864 return NDIS_STATUS_SUCCESS
;
867 RecvStart
= Adapter
->PageStart
* DRIVER_BLOCK_SIZE
;
868 RecvStop
= Adapter
->PageStop
* DRIVER_BLOCK_SIZE
;
870 NdisQueryPacket(Packet
, NULL
, NULL
, &DstBuffer
, NULL
);
871 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
873 SrcData
= Adapter
->PacketOffset
+ sizeof(DISCARD_HEADER
) + ByteOffset
;
874 if (ByteOffset
+ sizeof(DISCARD_HEADER
) + BytesToTransfer
>
875 Adapter
->PacketHeader
.PacketLength
)
876 BytesToTransfer
= Adapter
->PacketHeader
.PacketLength
-
877 sizeof(DISCARD_HEADER
) - ByteOffset
;
879 /* Start copying the data */
882 BytesToCopy
= (DstSize
< BytesToTransfer
) ? DstSize
: BytesToTransfer
;
883 if (SrcData
+ BytesToCopy
> RecvStop
)
884 BytesToCopy
= (RecvStop
- SrcData
);
886 NICReadData(Adapter
, DstData
, SrcData
, BytesToCopy
);
888 BytesCopied
+= BytesToCopy
;
889 SrcData
+= BytesToCopy
;
890 DstData
= (PUCHAR
)((ULONG_PTR
) DstData
+ BytesToCopy
);
891 BytesToTransfer
-= BytesToCopy
;
892 if (BytesToTransfer
== 0)
895 DstSize
-= BytesToCopy
;
897 /* No more bytes in destination buffer. Proceed to
898 the next buffer in the destination buffer chain */
899 NdisGetNextBuffer(DstBuffer
, &DstBuffer
);
903 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
906 if (SrcData
== RecvStop
)
910 NDIS_DbgPrint(MID_TRACE
, ("Transferred (%d) bytes.\n", BytesToTransfer
));
912 *BytesTransferred
= BytesCopied
;
914 return NDIS_STATUS_SUCCESS
;
921 PDRIVER_OBJECT DriverObject
,
922 PUNICODE_STRING RegistryPath
)
924 * FUNCTION: Main driver entry point
926 * DriverObject = Pointer to a driver object for this driver
927 * RegistryPath = Registry node for configuration parameters
929 * Status of driver initialization
933 NDIS_HANDLE NdisWrapperHandle
;
934 NDIS_MINIPORT_CHARACTERISTICS Miniport
;
936 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
938 NdisZeroMemory(&Miniport
, sizeof(Miniport
));
939 Miniport
.MajorNdisVersion
= DRIVER_NDIS_MAJOR_VERSION
;
940 Miniport
.MinorNdisVersion
= DRIVER_NDIS_MINOR_VERSION
;
941 Miniport
.CheckForHangHandler
= MiniportCheckForHang
;
942 Miniport
.DisableInterruptHandler
= MiniportDisableInterrupt
;
943 Miniport
.EnableInterruptHandler
= MiniportEnableInterrupt
;
944 Miniport
.HaltHandler
= MiniportHalt
;
945 Miniport
.HandleInterruptHandler
= MiniportHandleInterrupt
;
946 Miniport
.InitializeHandler
= MiniportInitialize
;
947 Miniport
.ISRHandler
= MiniportISR
;
948 Miniport
.QueryInformationHandler
= MiniportQueryInformation
;
949 Miniport
.ReconfigureHandler
= MiniportReconfigure
;
950 Miniport
.ResetHandler
= MiniportReset
;
951 Miniport
.SendHandler
= MiniportSend
;
952 Miniport
.SetInformationHandler
= MiniportSetInformation
;
953 Miniport
.TransferDataHandler
= MiniportTransferData
;
955 NdisMInitializeWrapper(&NdisWrapperHandle
,
960 if (!NdisWrapperHandle
) {
961 NDIS_DbgPrint(MIN_TRACE
, ("NdisMInitializeWrapper() failed\n"));
962 return STATUS_UNSUCCESSFUL
;
965 DriverInfo
.NdisWrapperHandle
= NdisWrapperHandle
;
966 DriverInfo
.NdisMacHandle
= NULL
;
967 InitializeListHead(&DriverInfo
.AdapterListHead
);
969 Status
= NdisMRegisterMiniport(NdisWrapperHandle
,
971 sizeof(NDIS_MINIPORT_CHARACTERISTICS
));
972 if (Status
!= NDIS_STATUS_SUCCESS
) {
973 NDIS_DbgPrint(MIN_TRACE
, ("NdisMRegisterMiniport() failed with status code (0x%X).\n", Status
));
974 NdisTerminateWrapper(NdisWrapperHandle
, NULL
);
975 return STATUS_UNSUCCESSFUL
;
978 return STATUS_SUCCESS
;
982 /* while i'm here - some basic registry sanity checks */
985 NDIS_CONFIGURATION_PARAMETER ParameterValue
;
987 ParameterValue
.ParameterType
= NdisParameterInteger
;
988 ParameterValue
.ParameterData
.IntegerData
= 0x12345678;
989 NdisInitUnicodeString(&Keyword
, L
"DwordTest");
990 NdisWriteConfiguration(&Status
, ConfigurationHandle
, &Keyword
, &ParameterValue
);
992 if(Status
!= NDIS_STATUS_SUCCESS
)
994 DbgPrint("ne2000!MiniportInitialize: failed to set DwordTest: 0x%x\n", Status
);
998 DbgPrint("ne2000!MiniportInitialize: DwordTest successfully set\n");
1000 NdisInitUnicodeString(&Keyword
, L
"StringTest");
1001 ParameterValue
.ParameterType
= NdisParameterString
;
1002 NdisInitUnicodeString(&ParameterValue
.ParameterData
.StringData
, L
"Testing123");
1004 NdisWriteConfiguration(&Status
, ConfigurationHandle
, &Keyword
, &ParameterValue
);
1006 if(Status
!= NDIS_STATUS_SUCCESS
)
1008 DbgPrint("ne2000!MiniportInitialize: failed to set StringTest: 0x%x\n", Status
);
1012 DbgPrint("ne2000!MiniportInitialize: StringTest successfully set\n");
1016 /* read back the test values */
1017 NDIS_CONFIGURATION_PARAMETER
*ParameterValue
= 0;
1019 NdisInitUnicodeString(&Keyword
, L
"DwordTest");
1020 NdisReadConfiguration(&Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterInteger
);
1022 if(Status
!= NDIS_STATUS_SUCCESS
)
1024 DbgPrint("ne2000!MiniportInitialize: failed to read DwordTest: 0x%x\n", Status
);
1028 if(ParameterValue
->ParameterData
.IntegerData
!= 0x12345678)
1030 DbgPrint("ne2000!MiniportInitialize: DwordTest value is wrong: 0x%x\n",
1031 ParameterValue
->ParameterData
.IntegerData
);
1035 DbgPrint("ne2000!MiniportInitialize: DwordTest value was correctly read\n");
1037 NdisInitUnicodeString(&Keyword
, L
"StringTest");
1038 NdisReadConfiguration(&Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterString
);
1040 if(Status
!= NDIS_STATUS_SUCCESS
)
1042 DbgPrint("ne2000!MiniportInitialize: failed to read StringTest: 0x%x\n", Status
);
1046 if(wcsncmp(ParameterValue
->ParameterData
.StringData
.Buffer
, L
"Testing123",
1047 wcslen(L
"Testing123")))
1049 DbgPrint("ne2000!MiniportInitialize: StringTest value is wrong: %wZ\n",
1050 &ParameterValue
->ParameterData
.StringData
);
1054 DbgPrint("ne2000!MiniportInitialize: StringTest value was correctly read\n");