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
19 PDRIVER_OBJECT DriverObject
,
20 PUNICODE_STRING RegistryPath
);
25 /* See debug.h for debug/trace constants */
26 ULONG DebugTraceLevel
= 0;
31 /* List of supported OIDs */
32 static ULONG MiniportOIDList
[] = {
33 OID_GEN_SUPPORTED_LIST
,
34 OID_GEN_HARDWARE_STATUS
,
35 OID_GEN_MEDIA_SUPPORTED
,
37 OID_GEN_MAXIMUM_LOOKAHEAD
,
38 OID_GEN_MAXIMUM_FRAME_SIZE
,
40 OID_GEN_TRANSMIT_BUFFER_SPACE
,
41 OID_GEN_RECEIVE_BUFFER_SPACE
,
42 OID_GEN_TRANSMIT_BLOCK_SIZE
,
43 OID_GEN_RECEIVE_BLOCK_SIZE
,
45 OID_GEN_VENDOR_DESCRIPTION
,
46 OID_GEN_VENDOR_DRIVER_VERSION
,
47 OID_GEN_CURRENT_PACKET_FILTER
,
48 OID_GEN_CURRENT_LOOKAHEAD
,
49 OID_GEN_DRIVER_VERSION
,
50 OID_GEN_MAXIMUM_TOTAL_SIZE
,
51 OID_GEN_PROTOCOL_OPTIONS
,
53 OID_GEN_MEDIA_CONNECT_STATUS
,
54 OID_GEN_MAXIMUM_SEND_PACKETS
,
55 OID_802_3_PERMANENT_ADDRESS
,
56 OID_802_3_CURRENT_ADDRESS
,
57 OID_802_3_MULTICAST_LIST
,
58 OID_802_3_MAXIMUM_LIST_SIZE
,
62 DRIVER_INFORMATION DriverInfo
= {0};
63 NDIS_PHYSICAL_ADDRESS HighestAcceptableMax
= NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
67 static BOOLEAN
MiniportCheckForHang(
68 IN NDIS_HANDLE MiniportAdapterContext
)
70 * FUNCTION: Examines if an adapter has hung
72 * MiniportAdapterContext = Pointer to adapter context area
74 * TRUE if the adapter has hung, FALSE if not
77 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
84 static VOID STDCALL
MiniportDisableInterrupt(
85 IN NDIS_HANDLE MiniportAdapterContext
)
87 * FUNCTION: Disables interrupts from an adapter
89 * MiniportAdapterContext = Pointer to adapter context area
92 NDIS_DbgPrint(MAX_TRACE
, ("Called. (MiniportDisableInterrupt).\n"));
94 NICDisableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
99 static VOID STDCALL
MiniportEnableInterrupt(
100 IN NDIS_HANDLE MiniportAdapterContext
)
102 * FUNCTION: Enables interrupts from an adapter
104 * MiniportAdapterContext = Pointer to adapter context area
107 NDIS_DbgPrint(MAX_TRACE
, ("Called. (MiniportEnableInterrupt).\n"));
109 NICEnableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
114 static VOID STDCALL
MiniportHalt(
115 IN NDIS_HANDLE MiniportAdapterContext
)
117 * FUNCTION: Deallocates resources for and halts an adapter
119 * MiniportAdapterContext = Pointer to adapter context area
122 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
124 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
129 /* Wait for any DPCs to complete. FIXME: Use something else */
130 NdisStallExecution(250000);
132 if (Adapter
->InterruptRegistered
)
133 /* Deregister interrupt */
134 NdisMDeregisterInterrupt(&Adapter
->Interrupt
);
136 if (Adapter
->IOPortRangeRegistered
)
137 /* Deregister I/O port range */
138 NdisMDeregisterIoPortRange(
139 Adapter
->MiniportAdapterHandle
,
140 Adapter
->IoBaseAddress
,
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 STDCALL
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
;
205 static NDIS_STATUS STDCALL
MiniportInitialize(
206 OUT PNDIS_STATUS OpenErrorStatus
,
207 OUT PUINT SelectedMediumIndex
,
208 IN PNDIS_MEDIUM MediumArray
,
209 IN UINT MediumArraySize
,
210 IN NDIS_HANDLE MiniportAdapterHandle
,
211 IN NDIS_HANDLE WrapperConfigurationContext
)
213 * FUNCTION: Adapter initialization function
215 * OpenErrorStatus = Address of buffer to place additional status information
216 * SelectedMediumIndex = Address of buffer to place selected medium index
217 * MediumArray = Pointer to an array of NDIS_MEDIUMs
218 * MediaArraySize = Number of elements in MediumArray
219 * MiniportAdapterHandle = Miniport adapter handle assigned by NDIS
220 * WrapperConfigurationContext = Handle used to identify configuration context
222 * Status of operation
227 PNIC_ADAPTER Adapter
;
229 NDIS_DbgPrint(MAX_TRACE
, ("Called (Adapter %X).\n", MiniportAdapterHandle
));
231 /* Search for 802.3 media which is the only one we support */
232 for (i
= 0; i
< MediumArraySize
; i
++) {
233 if (MediumArray
[i
] == NdisMedium802_3
)
237 if (i
== MediumArraySize
) {
238 NDIS_DbgPrint(MIN_TRACE
, ("No supported media.\n"));
239 return NDIS_STATUS_UNSUPPORTED_MEDIA
;
242 *SelectedMediumIndex
= i
;
244 Status
= NdisAllocateMemory((PVOID
)&Adapter
,
247 HighestAcceptableMax
);
248 if (Status
!= NDIS_STATUS_SUCCESS
) {
249 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
253 NdisZeroMemory(Adapter
, sizeof(NIC_ADAPTER
));
254 Adapter
->MiniportAdapterHandle
= MiniportAdapterHandle
;
255 Adapter
->IoBaseAddress
= DRIVER_DEFAULT_IO_BASE_ADDRESS
;
256 Adapter
->InterruptLevel
= DRIVER_DEFAULT_INTERRUPT_NUMBER
;
257 Adapter
->InterruptVector
= DRIVER_DEFAULT_INTERRUPT_NUMBER
;
258 Adapter
->InterruptShared
= DRIVER_DEFAULT_INTERRUPT_SHARED
;
259 Adapter
->InterruptMode
= DRIVER_DEFAULT_INTERRUPT_MODE
;
260 Adapter
->MaxMulticastListSize
= DRIVER_MAX_MULTICAST_LIST_SIZE
;
261 Adapter
->InterruptMask
= DRIVER_INTERRUPT_MASK
;
262 Adapter
->LookaheadSize
= DRIVER_MAXIMUM_LOOKAHEAD
;
264 /* Query the resources from PnP. */
265 MiQueryResources(&Status
, Adapter
, WrapperConfigurationContext
);
267 /* Get the port, irq, and MAC address from registry if the PnP
269 if (Status
!= NDIS_STATUS_SUCCESS
)
271 PNDIS_CONFIGURATION_PARAMETER ConfigurationParameter
;
272 NDIS_HANDLE ConfigurationHandle
;
273 UNICODE_STRING Keyword
;
274 UINT
*RegNetworkAddress
= 0;
275 UINT RegNetworkAddressLength
= 0;
277 NdisOpenConfiguration(&Status
, &ConfigurationHandle
, WrapperConfigurationContext
);
278 if (Status
== NDIS_STATUS_SUCCESS
)
280 NdisInitUnicodeString(&Keyword
, L
"Irq");
281 NdisReadConfiguration(&Status
, &ConfigurationParameter
, ConfigurationHandle
, &Keyword
, NdisParameterHexInteger
);
282 if(Status
== NDIS_STATUS_SUCCESS
)
284 NDIS_DbgPrint(MID_TRACE
,("NdisReadConfiguration for Irq returned successfully, irq 0x%x\n",
285 ConfigurationParameter
->ParameterData
.IntegerData
));
286 Adapter
->InterruptLevel
=
287 Adapter
->InterruptVector
= ConfigurationParameter
->ParameterData
.IntegerData
;
290 NdisInitUnicodeString(&Keyword
, L
"Port");
291 NdisReadConfiguration(&Status
, &ConfigurationParameter
, ConfigurationHandle
, &Keyword
, NdisParameterHexInteger
);
292 if(Status
== NDIS_STATUS_SUCCESS
)
294 NDIS_DbgPrint(MID_TRACE
,("NdisReadConfiguration for Port returned successfully, port 0x%x\n",
295 ConfigurationParameter
->ParameterData
.IntegerData
));
296 Adapter
->IoBaseAddress
= ConfigurationParameter
->ParameterData
.IntegerData
;
299 /* the returned copy of the data is owned by NDIS and will be released on NdisCloseConfiguration */
300 NdisReadNetworkAddress(&Status
, (PVOID
*)&RegNetworkAddress
, &RegNetworkAddressLength
, ConfigurationHandle
);
301 if(Status
== NDIS_STATUS_SUCCESS
&& RegNetworkAddressLength
== DRIVER_LENGTH_OF_ADDRESS
)
304 NDIS_DbgPrint(MID_TRACE
,("NdisReadNetworkAddress returned successfully, address %x:%x:%x:%x:%x:%x\n",
305 RegNetworkAddress
[0], RegNetworkAddress
[1], RegNetworkAddress
[2], RegNetworkAddress
[3],
306 RegNetworkAddress
[4], RegNetworkAddress
[5]));
307 for(i
= 0; i
< DRIVER_LENGTH_OF_ADDRESS
; i
++)
308 Adapter
->StationAddress
[i
] = RegNetworkAddress
[i
];
311 NdisCloseConfiguration(ConfigurationHandle
);
315 NDIS_DbgPrint(MIN_TRACE
,("NdisOpenConfiguration returned error 0x%x\n", Status
));
320 if (!NICCheck(Adapter
)) {
321 NDIS_DbgPrint(MID_TRACE
, ("No adapter found at (0x%X).\n", Adapter
->IoBaseAddress
));
322 NdisFreeMemory(Adapter
, sizeof(NIC_ADAPTER
), 0);
323 return NDIS_STATUS_ADAPTER_NOT_FOUND
;
325 NDIS_DbgPrint(MID_TRACE
, ("Adapter found at (0x%X).\n", Adapter
->IoBaseAddress
));
328 MiniportAdapterHandle
,
329 (NDIS_HANDLE
)Adapter
,
333 Status
= NdisMRegisterIoPortRange(
334 (PVOID
*)&Adapter
->IOBase
,
335 MiniportAdapterHandle
,
336 Adapter
->IoBaseAddress
,
339 if (Status
!= NDIS_STATUS_SUCCESS
) {
340 NDIS_DbgPrint(MIN_TRACE
, ("Cannot register port range. Status (0x%X).\n", Status
));
341 MiniportHalt((NDIS_HANDLE
)Adapter
);
345 Adapter
->IOPortRangeRegistered
= TRUE
;
349 Status
= NICInitialize(Adapter
);
350 if (Status
!= NDIS_STATUS_SUCCESS
) {
351 NDIS_DbgPrint(MIN_TRACE
,("No NE2000 or compatible network adapter found at address 0x%X.\n",
354 NDIS_DbgPrint(MID_TRACE
, ("Status (0x%X).\n", Status
));
355 MiniportHalt((NDIS_HANDLE
)Adapter
);
359 NDIS_DbgPrint(MID_TRACE
, ("BOARDDATA:\n"));
360 for (i
= 0; i
< 4; i
++) {
361 NDIS_DbgPrint(MID_TRACE
, ("%02X %02X %02X %02X\n",
362 Adapter
->SAPROM
[i
*4+0],
363 Adapter
->SAPROM
[i
*4+1],
364 Adapter
->SAPROM
[i
*4+2],
365 Adapter
->SAPROM
[i
*4+3]));
368 /* Setup adapter structure */
369 Adapter
->TXStart
= ((ULONG_PTR
)Adapter
->RamBase
>> 8);
370 Adapter
->TXCount
= DRIVER_DEFAULT_TX_BUFFER_COUNT
;
371 Adapter
->TXFree
= DRIVER_DEFAULT_TX_BUFFER_COUNT
;
372 Adapter
->TXCurrent
= -1;
373 Adapter
->PageStart
= Adapter
->TXStart
+ Adapter
->TXCount
;
374 Adapter
->PageStop
= Adapter
->TXStart
+ (Adapter
->RamSize
>> 8);
376 /* Initialize multicast address mask to accept all */
377 for (i
= 0; i
< 8; i
++)
378 Adapter
->MulticastAddressMask
[i
] = 0xFF;
383 NDIS_DbgPrint(MID_TRACE
, ("TXStart (0x%X) TXCount (0x%X) PageStart (0x%X)\n",
386 Adapter
->PageStart
));
388 NDIS_DbgPrint(MID_TRACE
, ("PageStop (0x%X) CurrentPage (0x%X) NextPacket (0x%X).\n",
390 Adapter
->CurrentPage
,
391 Adapter
->NextPacket
));
393 /* Register the interrupt */
394 Status
= NdisMRegisterInterrupt(
396 MiniportAdapterHandle
,
397 Adapter
->InterruptVector
,
398 Adapter
->InterruptLevel
,
400 Adapter
->InterruptShared
,
401 Adapter
->InterruptMode
);
402 if (Status
!= NDIS_STATUS_SUCCESS
) {
403 NDIS_DbgPrint(MIN_TRACE
, ("Cannot register interrupt. Status (0x%X).\n", Status
));
404 MiniportHalt((NDIS_HANDLE
)Adapter
);
408 Adapter
->InterruptRegistered
= TRUE
;
413 /* Add adapter to the global adapter list */
414 InsertTailList(&DriverInfo
.AdapterListHead
, &Adapter
->ListEntry
);
416 NDIS_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
418 return NDIS_STATUS_SUCCESS
;
422 static VOID STDCALL
MiniportISR(
423 OUT PBOOLEAN InterruptRecognized
,
424 OUT PBOOLEAN QueueMiniportHandleInterrupt
,
425 IN NDIS_HANDLE MiniportAdapterContext
)
427 * FUNCTION: Interrupt Service Routine for controlled adapters
429 * InterruptRecognized = Address of buffer to place wether
430 * the adapter generated the interrupt
431 * QueueMiniportHandleInterrupt = Address of buffer to place wether
432 * MiniportHandleInterrupt should be called
433 * MiniportAdapterContext = Pointer to adapter context area
435 * All pending interrupts are handled
438 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
440 NICDisableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
442 *InterruptRecognized
= TRUE
;
443 *QueueMiniportHandleInterrupt
= TRUE
;
447 static NDIS_STATUS STDCALL
MiniportQueryInformation(
448 IN NDIS_HANDLE MiniportAdapterContext
,
450 IN PVOID InformationBuffer
,
451 IN ULONG InformationBufferLength
,
452 OUT PULONG BytesWritten
,
453 OUT PULONG BytesNeeded
)
455 * FUNCTION: Handler to process queries
457 * MiniportAdapterContext = Pointer to adapter context area
458 * Oid = OID code designating query operation
459 * InformationBuffer = Address of return buffer
460 * InformationBufferLength = Length of return buffer
461 * BytesWritten = Address of buffer to place number of bytes returned
462 * BytesNeeded = Address of buffer to place number of bytes needed
463 * in InformationBuffer for specified OID
465 * Status of operation
472 USHORT GenericUSHORT
;
473 NDIS_MEDIUM Medium
= NdisMedium802_3
;
474 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
476 NDIS_DbgPrint(MAX_TRACE
, ("Called. Oid (0x%X).\n", Oid
));
478 Status
= NDIS_STATUS_SUCCESS
;
479 CopyFrom
= (PVOID
)&GenericULONG
;
480 CopySize
= sizeof(ULONG
);
483 case OID_GEN_SUPPORTED_LIST
:
484 CopyFrom
= (PVOID
)&MiniportOIDList
;
485 CopySize
= sizeof(MiniportOIDList
);
487 case OID_GEN_HARDWARE_STATUS
:
488 GenericULONG
= (ULONG
)NdisHardwareStatusReady
;
490 case OID_GEN_MEDIA_SUPPORTED
:
491 case OID_GEN_MEDIA_IN_USE
:
492 CopyFrom
= (PVOID
)&Medium
;
493 CopySize
= sizeof(NDIS_MEDIUM
);
495 case OID_GEN_MAXIMUM_LOOKAHEAD
:
496 GenericULONG
= DRIVER_MAXIMUM_LOOKAHEAD
;
498 case OID_GEN_MAXIMUM_FRAME_SIZE
:
499 GenericULONG
= DRIVER_FRAME_SIZE
- DRIVER_HEADER_SIZE
;
501 case OID_GEN_LINK_SPEED
:
502 GenericULONG
= 100000; /* 10Mbps */
504 case OID_GEN_TRANSMIT_BUFFER_SPACE
:
505 GenericULONG
= Adapter
->TXCount
* DRIVER_BLOCK_SIZE
;
507 case OID_GEN_RECEIVE_BUFFER_SPACE
:
508 GenericULONG
= Adapter
->RamSize
-
509 (ULONG_PTR
)Adapter
->RamBase
-
510 (Adapter
->TXCount
* DRIVER_BLOCK_SIZE
);
512 case OID_GEN_TRANSMIT_BLOCK_SIZE
:
513 GenericULONG
= DRIVER_BLOCK_SIZE
;
515 case OID_GEN_RECEIVE_BLOCK_SIZE
:
516 GenericULONG
= DRIVER_BLOCK_SIZE
;
518 case OID_GEN_VENDOR_ID
:
519 NdisMoveMemory(&GenericULONG
, &Adapter
->PermanentAddress
, 3);
520 GenericULONG
&= 0xFFFFFF00;
521 GenericULONG
|= 0x01;
523 case OID_GEN_VENDOR_DESCRIPTION
:
524 CopyFrom
= (PVOID
)&DRIVER_VENDOR_DESCRIPTION
;
525 CopySize
= sizeof(DRIVER_VENDOR_DESCRIPTION
);
527 case OID_GEN_VENDOR_DRIVER_VERSION
:
528 GenericUSHORT
= (USHORT
)DRIVER_VENDOR_DRIVER_VERSION
;
529 CopyFrom
= (PVOID
)&GenericUSHORT
;
530 CopySize
= sizeof(USHORT
);
532 case OID_GEN_CURRENT_PACKET_FILTER
:
533 GenericULONG
= Adapter
->PacketFilter
;
535 case OID_GEN_CURRENT_LOOKAHEAD
:
536 GenericULONG
= Adapter
->LookaheadSize
;
538 case OID_GEN_DRIVER_VERSION
:
539 GenericUSHORT
= ((USHORT
)DRIVER_NDIS_MAJOR_VERSION
<< 8) | DRIVER_NDIS_MINOR_VERSION
;
540 CopyFrom
= (PVOID
)&GenericUSHORT
;
541 CopySize
= sizeof(USHORT
);
543 case OID_GEN_MAXIMUM_TOTAL_SIZE
:
544 GenericULONG
= DRIVER_FRAME_SIZE
;
546 case OID_GEN_PROTOCOL_OPTIONS
:
547 NDIS_DbgPrint(MID_TRACE
, ("OID_GEN_PROTOCOL_OPTIONS.\n"));
548 Status
= NDIS_STATUS_NOT_SUPPORTED
;
550 case OID_GEN_MAC_OPTIONS
:
551 GenericULONG
= NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA
|
552 NDIS_MAC_OPTION_RECEIVE_SERIALIZED
|
553 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND
|
554 NDIS_MAC_OPTION_NO_LOOPBACK
;
556 case OID_GEN_MEDIA_CONNECT_STATUS
:
557 GenericULONG
= (ULONG
)NdisMediaStateConnected
;
559 case OID_GEN_MAXIMUM_SEND_PACKETS
:
562 case OID_802_3_PERMANENT_ADDRESS
:
563 CopyFrom
= (PVOID
)&Adapter
->PermanentAddress
;
564 CopySize
= DRIVER_LENGTH_OF_ADDRESS
;
566 case OID_802_3_CURRENT_ADDRESS
:
567 CopyFrom
= (PVOID
)&Adapter
->StationAddress
;
568 CopySize
= DRIVER_LENGTH_OF_ADDRESS
;
570 case OID_802_3_MULTICAST_LIST
:
571 NDIS_DbgPrint(MID_TRACE
, ("OID_802_3_MULTICAST_LIST.\n"));
572 Status
= NDIS_STATUS_NOT_SUPPORTED
;
574 case OID_802_3_MAXIMUM_LIST_SIZE
:
575 GenericULONG
= Adapter
->MaxMulticastListSize
;
577 case OID_802_3_MAC_OPTIONS
:
578 NDIS_DbgPrint(MID_TRACE
, ("OID_802_3_MAC_OPTIONS.\n"));
579 Status
= NDIS_STATUS_NOT_SUPPORTED
;
582 NDIS_DbgPrint(MIN_TRACE
, ("Unknown OID (0x%X).\n", Oid
));
583 Status
= NDIS_STATUS_INVALID_OID
;
587 if (Status
== NDIS_STATUS_SUCCESS
) {
588 if (CopySize
> InformationBufferLength
) {
589 *BytesNeeded
= (CopySize
- InformationBufferLength
);
591 Status
= NDIS_STATUS_INVALID_LENGTH
;
593 NdisMoveMemory(InformationBuffer
, CopyFrom
, CopySize
);
594 *BytesWritten
= CopySize
;
599 NDIS_DbgPrint(MAX_TRACE
, ("Leaving. Status is (0x%X).\n", Status
));
605 static NDIS_STATUS STDCALL
MiniportReconfigure(
606 OUT PNDIS_STATUS OpenErrorStatus
,
607 IN NDIS_HANDLE MiniportAdapterContext
,
608 IN NDIS_HANDLE WrapperConfigurationContext
)
610 * FUNCTION: Reconfigures an adapter
612 * OpenErrorStatus = Address of buffer to place additional status information
613 * MiniportAdapterContext = Pointer to adapter context area
614 * WrapperConfigurationContext = Handle used to identify configuration context
616 * Status of operation
618 * Never called by NDIS library
621 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
623 return NDIS_STATUS_FAILURE
;
628 static NDIS_STATUS STDCALL
MiniportReset(
629 OUT PBOOLEAN AddressingReset
,
630 IN NDIS_HANDLE MiniportAdapterContext
)
632 * FUNCTION: Resets an adapter
634 * AddressingReset = Address of a buffer to place value indicating
635 * wether NDIS library should call MiniportSetInformation
636 * to restore addressing information
637 * MiniportAdapterContext = Pointer to adapter context area
639 * Status of operation
642 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
644 return NDIS_STATUS_FAILURE
;
648 static NDIS_STATUS STDCALL
MiniportSend(
649 IN NDIS_HANDLE MiniportAdapterContext
,
650 IN PNDIS_PACKET Packet
,
653 * FUNCTION: Transmits a packet
655 * MiniportAdapterContext = Pointer to adapter context area
656 * Packet = Pointer to a packet descriptor specifying
657 * the data to be transmitted
658 * Flags = Specifies optional packet flags
660 * Status of operation
663 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
665 NDIS_DbgPrint(MID_TRACE
, ("Queueing packet.\n"));
668 NdisMSendComplete(Adapter
->MiniportAdapterHandle
,
670 NDIS_STATUS_SUCCESS
);
672 /* Queue the packet on the transmit queue */
673 RESERVED(Packet
)->Next
= NULL
;
674 if (Adapter
->TXQueueHead
== NULL
) {
675 Adapter
->TXQueueHead
= Packet
;
677 RESERVED(Adapter
->TXQueueTail
)->Next
= Packet
;
680 Adapter
->TXQueueTail
= Packet
;
682 /* Transmit the packet */
683 NICTransmit(Adapter
);
685 return NDIS_STATUS_PENDING
;
689 static NDIS_STATUS STDCALL
MiniportSetInformation(
690 IN NDIS_HANDLE MiniportAdapterContext
,
692 IN PVOID InformationBuffer
,
693 IN ULONG InformationBufferLength
,
694 OUT PULONG BytesRead
,
695 OUT PULONG BytesNeeded
)
697 * FUNCTION: Changes state information in the driver
699 * MiniportAdapterContext = Pointer to adapter context area
700 * Oid = OID code designating set operation
701 * InformationBuffer = Pointer to buffer with state information
702 * InformationBufferLength = Length of InformationBuffer
703 * BytesRead = Address of buffer to place number of bytes read
704 * BytesNeeded = Address of buffer to place number of extra bytes
705 * needed in InformationBuffer for specified OID
707 * Status of operation
711 NDIS_STATUS Status
= NDIS_STATUS_SUCCESS
;
712 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
714 NDIS_DbgPrint(MAX_TRACE
, ("Called. Oid (0x%X).\n", Oid
));
717 case OID_GEN_CURRENT_PACKET_FILTER
:
719 if (InformationBufferLength
< sizeof(ULONG
)) {
721 *BytesNeeded
= sizeof(ULONG
) - InformationBufferLength
;
722 Status
= NDIS_STATUS_INVALID_LENGTH
;
726 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
727 /* Check for properties the driver don't support */
729 (NDIS_PACKET_TYPE_ALL_FUNCTIONAL
|
730 NDIS_PACKET_TYPE_FUNCTIONAL
|
731 NDIS_PACKET_TYPE_GROUP
|
732 NDIS_PACKET_TYPE_MAC_FRAME
|
733 NDIS_PACKET_TYPE_SMT
|
734 NDIS_PACKET_TYPE_SOURCE_ROUTING
)) {
737 Status
= NDIS_STATUS_NOT_SUPPORTED
;
741 Adapter
->PacketFilter
= GenericULONG
;
743 /* FIXME: Set filter on hardware */
746 case OID_GEN_CURRENT_LOOKAHEAD
:
748 if (InformationBufferLength
< sizeof(ULONG
)) {
750 *BytesNeeded
= sizeof(ULONG
) - InformationBufferLength
;
751 Status
= NDIS_STATUS_INVALID_LENGTH
;
755 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
756 if (GenericULONG
> DRIVER_MAXIMUM_LOOKAHEAD
)
757 Status
= NDIS_STATUS_INVALID_LENGTH
;
759 Adapter
->LookaheadSize
= GenericULONG
;
761 case OID_802_3_MULTICAST_LIST
:
762 /* Verify length. Must be multiplum of hardware address length */
763 if ((InformationBufferLength
% DRIVER_LENGTH_OF_ADDRESS
) != 0) {
766 Status
= NDIS_STATUS_INVALID_LENGTH
;
770 /* Set new multicast address list */
771 NdisMoveMemory(Adapter
->Addresses
, InformationBuffer
, InformationBufferLength
);
773 /* FIXME: Update hardware */
777 NDIS_DbgPrint(MIN_TRACE
, ("Invalid object ID (0x%X).\n", Oid
));
780 Status
= NDIS_STATUS_INVALID_OID
;
784 if (Status
== NDIS_STATUS_SUCCESS
) {
785 *BytesRead
= InformationBufferLength
;
789 NDIS_DbgPrint(MAX_TRACE
, ("Leaving. Status (0x%X).\n", Status
));
795 static NDIS_STATUS STDCALL
MiniportTransferData(
796 OUT PNDIS_PACKET Packet
,
797 OUT PUINT BytesTransferred
,
798 IN NDIS_HANDLE MiniportAdapterContext
,
799 IN NDIS_HANDLE MiniportReceiveContext
,
801 IN UINT BytesToTransfer
)
803 * FUNCTION: Transfers data from a received frame into an NDIS packet
805 * Packet = Address of packet to copy received data into
806 * BytesTransferred = Address of buffer to place number of bytes transmitted
807 * MiniportAdapterContext = Pointer to adapter context area
808 * MiniportReceiveContext = Pointer to receive context area (actually NULL)
809 * ByteOffset = Offset within received packet to begin copying
810 * BytesToTransfer = Number of bytes to copy into packet
812 * Status of operation
815 PNDIS_BUFFER DstBuffer
;
816 UINT BytesCopied
, BytesToCopy
, DstSize
;
821 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
823 NDIS_DbgPrint(MAX_TRACE
, ("Called. Packet (0x%X) ByteOffset (0x%X) BytesToTransfer (%d).\n",
824 Packet
, ByteOffset
, BytesToTransfer
));
826 if (BytesToTransfer
== 0) {
827 *BytesTransferred
= 0;
828 return NDIS_STATUS_SUCCESS
;
831 RecvStart
= Adapter
->PageStart
* DRIVER_BLOCK_SIZE
;
832 RecvStop
= Adapter
->PageStop
* DRIVER_BLOCK_SIZE
;
834 NdisQueryPacket(Packet
, NULL
, NULL
, &DstBuffer
, NULL
);
835 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
837 SrcData
= Adapter
->PacketOffset
+ sizeof(DISCARD_HEADER
) + ByteOffset
;
838 if (ByteOffset
+ sizeof(DISCARD_HEADER
) + BytesToTransfer
>
839 Adapter
->PacketHeader
.PacketLength
)
840 BytesToTransfer
= Adapter
->PacketHeader
.PacketLength
-
841 sizeof(DISCARD_HEADER
) - ByteOffset
;
843 /* Start copying the data */
846 BytesToCopy
= (DstSize
< BytesToTransfer
) ? DstSize
: BytesToTransfer
;
847 if (SrcData
+ BytesToCopy
> RecvStop
)
848 BytesToCopy
= (RecvStop
- SrcData
);
850 NICReadData(Adapter
, DstData
, SrcData
, BytesToCopy
);
852 BytesCopied
+= BytesToCopy
;
853 SrcData
+= BytesToCopy
;
854 DstData
= (PUCHAR
)((ULONG_PTR
) DstData
+ BytesToCopy
);
855 BytesToTransfer
-= BytesToCopy
;
856 if (BytesToTransfer
== 0)
859 DstSize
-= BytesToCopy
;
861 /* No more bytes in destination buffer. Proceed to
862 the next buffer in the destination buffer chain */
863 NdisGetNextBuffer(DstBuffer
, &DstBuffer
);
867 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
870 if (SrcData
== RecvStop
)
874 NDIS_DbgPrint(MID_TRACE
, ("Transferred (%d) bytes.\n", BytesToTransfer
));
876 *BytesTransferred
= BytesCopied
;
878 return NDIS_STATUS_SUCCESS
;
887 PDRIVER_OBJECT DriverObject
,
888 PUNICODE_STRING RegistryPath
)
890 * FUNCTION: Main driver entry point
892 * DriverObject = Pointer to a driver object for this driver
893 * RegistryPath = Registry node for configuration parameters
895 * Status of driver initialization
899 NDIS_HANDLE NdisWrapperHandle
;
900 NDIS_MINIPORT_CHARACTERISTICS Miniport
;
902 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
904 NdisZeroMemory(&Miniport
, sizeof(Miniport
));
905 Miniport
.MajorNdisVersion
= DRIVER_NDIS_MAJOR_VERSION
;
906 Miniport
.MinorNdisVersion
= DRIVER_NDIS_MINOR_VERSION
;
907 Miniport
.CheckForHangHandler
= NULL
; //MiniportCheckForHang;
908 Miniport
.DisableInterruptHandler
= MiniportDisableInterrupt
;
909 Miniport
.EnableInterruptHandler
= MiniportEnableInterrupt
;
910 Miniport
.HaltHandler
= MiniportHalt
;
911 Miniport
.HandleInterruptHandler
= MiniportHandleInterrupt
;
912 Miniport
.InitializeHandler
= MiniportInitialize
;
913 Miniport
.ISRHandler
= MiniportISR
;
914 Miniport
.QueryInformationHandler
= MiniportQueryInformation
;
915 Miniport
.ReconfigureHandler
= MiniportReconfigure
;
916 Miniport
.ResetHandler
= MiniportReset
;
917 Miniport
.SendHandler
= MiniportSend
;
918 Miniport
.SetInformationHandler
= MiniportSetInformation
;
919 Miniport
.TransferDataHandler
= MiniportTransferData
;
921 NdisMInitializeWrapper(&NdisWrapperHandle
,
926 DriverInfo
.NdisWrapperHandle
= NdisWrapperHandle
;
927 DriverInfo
.NdisMacHandle
= NULL
;
928 InitializeListHead(&DriverInfo
.AdapterListHead
);
930 Status
= NdisMRegisterMiniport(NdisWrapperHandle
,
932 sizeof(NDIS_MINIPORT_CHARACTERISTICS
));
933 if (Status
!= NDIS_STATUS_SUCCESS
) {
934 NDIS_DbgPrint(MIN_TRACE
, ("NdisMRegisterMiniport() failed with status code (0x%X).\n", Status
));
935 NdisTerminateWrapper(NdisWrapperHandle
, NULL
);
936 return STATUS_UNSUCCESSFUL
;
939 return STATUS_SUCCESS
;
943 /* while i'm here - some basic registry sanity checks */
946 NDIS_CONFIGURATION_PARAMETER ParameterValue
;
948 ParameterValue
.ParameterType
= NdisParameterInteger
;
949 ParameterValue
.ParameterData
.IntegerData
= 0x12345678;
950 NdisInitUnicodeString(&Keyword
, L
"DwordTest");
951 NdisWriteConfiguration(&Status
, ConfigurationHandle
, &Keyword
, &ParameterValue
);
953 if(Status
!= NDIS_STATUS_SUCCESS
)
955 DbgPrint("ne2000!MiniportInitialize: failed to set DwordTest: 0x%x\n", Status
);
959 DbgPrint("ne2000!MiniportInitialize: DwordTest successfully set\n");
961 NdisInitUnicodeString(&Keyword
, L
"StringTest");
962 ParameterValue
.ParameterType
= NdisParameterString
;
963 NdisInitUnicodeString(&ParameterValue
.ParameterData
.StringData
, L
"Testing123");
965 NdisWriteConfiguration(&Status
, ConfigurationHandle
, &Keyword
, &ParameterValue
);
967 if(Status
!= NDIS_STATUS_SUCCESS
)
969 DbgPrint("ne2000!MiniportInitialize: failed to set StringTest: 0x%x\n", Status
);
973 DbgPrint("ne2000!MiniportInitialize: StringTest successfully set\n");
977 /* read back the test values */
978 NDIS_CONFIGURATION_PARAMETER
*ParameterValue
= 0;
980 NdisInitUnicodeString(&Keyword
, L
"DwordTest");
981 NdisReadConfiguration(&Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterInteger
);
983 if(Status
!= NDIS_STATUS_SUCCESS
)
985 DbgPrint("ne2000!MiniportInitialize: failed to read DwordTest: 0x%x\n", Status
);
989 if(ParameterValue
->ParameterData
.IntegerData
!= 0x12345678)
991 DbgPrint("ne2000!MiniportInitialize: DwordTest value is wrong: 0x%x\n",
992 ParameterValue
->ParameterData
.IntegerData
);
996 DbgPrint("ne2000!MiniportInitialize: DwordTest value was correctly read\n");
998 NdisInitUnicodeString(&Keyword
, L
"StringTest");
999 NdisReadConfiguration(&Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterString
);
1001 if(Status
!= NDIS_STATUS_SUCCESS
)
1003 DbgPrint("ne2000!MiniportInitialize: failed to read StringTest: 0x%x\n", Status
);
1007 if(wcsncmp(ParameterValue
->ParameterData
.StringData
.Buffer
, L
"Testing123",
1008 wcslen(L
"Testing123")))
1010 DbgPrint("ne2000!MiniportInitialize: StringTest value is wrong: %wZ\n",
1011 &ParameterValue
->ParameterData
.StringData
);
1015 DbgPrint("ne2000!MiniportInitialize: StringTest value was correctly read\n");