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 /* See debug.h for debug/trace constants */
16 ULONG DebugTraceLevel
= MIN_TRACE
;
21 /* List of supported OIDs */
22 static ULONG MiniportOIDList
[] = {
23 OID_GEN_SUPPORTED_LIST
,
24 OID_GEN_HARDWARE_STATUS
,
25 OID_GEN_MEDIA_SUPPORTED
,
27 OID_GEN_MAXIMUM_LOOKAHEAD
,
28 OID_GEN_MAXIMUM_FRAME_SIZE
,
30 OID_GEN_TRANSMIT_BUFFER_SPACE
,
31 OID_GEN_RECEIVE_BUFFER_SPACE
,
32 OID_GEN_TRANSMIT_BLOCK_SIZE
,
33 OID_GEN_RECEIVE_BLOCK_SIZE
,
35 OID_GEN_VENDOR_DESCRIPTION
,
36 OID_GEN_VENDOR_DRIVER_VERSION
,
37 OID_GEN_CURRENT_PACKET_FILTER
,
38 OID_GEN_CURRENT_LOOKAHEAD
,
39 OID_GEN_DRIVER_VERSION
,
40 OID_GEN_MAXIMUM_TOTAL_SIZE
,
41 OID_GEN_PROTOCOL_OPTIONS
,
43 OID_GEN_MEDIA_CONNECT_STATUS
,
44 OID_GEN_MAXIMUM_SEND_PACKETS
,
45 OID_802_3_PERMANENT_ADDRESS
,
46 OID_802_3_CURRENT_ADDRESS
,
47 OID_802_3_MULTICAST_LIST
,
48 OID_802_3_MAXIMUM_LIST_SIZE
,
52 DRIVER_INFORMATION DriverInfo
= {0};
53 NDIS_PHYSICAL_ADDRESS HighestAcceptableMax
= NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
56 BOOLEAN
MiniportCheckForHang(
57 IN NDIS_HANDLE MiniportAdapterContext
)
59 * FUNCTION: Examines if an adapter has hung
61 * MiniportAdapterContext = Pointer to adapter context area
63 * TRUE if the adapter has hung, FALSE if not
66 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
72 VOID
MiniportDisableInterrupt(
73 IN NDIS_HANDLE MiniportAdapterContext
)
75 * FUNCTION: Disables interrupts from an adapter
77 * MiniportAdapterContext = Pointer to adapter context area
80 NDIS_DbgPrint(MAX_TRACE
, ("Called. (MiniportDisableInterrupt).\n"));
82 NICDisableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
87 VOID
MiniportEnableInterrupt(
88 IN NDIS_HANDLE MiniportAdapterContext
)
90 * FUNCTION: Enables interrupts from an adapter
92 * MiniportAdapterContext = Pointer to adapter context area
95 NDIS_DbgPrint(MAX_TRACE
, ("Called. (MiniportEnableInterrupt).\n"));
97 NICEnableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
103 IN NDIS_HANDLE MiniportAdapterContext
)
105 * FUNCTION: Deallocates resources for and halts an adapter
107 * MiniportAdapterContext = Pointer to adapter context area
110 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
112 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
117 /* Wait for any DPCs to complete. FIXME: Use something else */
118 NdisStallExecution(250000);
120 if (Adapter
->InterruptRegistered
)
121 /* Deregister interrupt */
122 NdisMDeregisterInterrupt(&Adapter
->Interrupt
);
124 if (Adapter
->IOPortRangeRegistered
)
125 /* Deregister I/O port range */
126 NdisMDeregisterIoPortRange(
127 Adapter
->MiniportAdapterHandle
,
128 Adapter
->IoBaseAddress
,
132 /* Remove adapter from global adapter list */
133 if ((&Adapter
->ListEntry
)->Blink
!= NULL
) {
134 RemoveEntryList(&Adapter
->ListEntry
);
137 /* Free adapter context area */
138 NdisFreeMemory(Adapter
, sizeof(NIC_ADAPTER
), 0);
142 NDIS_STATUS
MiniportInitialize(
143 OUT PNDIS_STATUS OpenErrorStatus
,
144 OUT PUINT SelectedMediumIndex
,
145 IN PNDIS_MEDIUM MediumArray
,
146 IN UINT MediumArraySize
,
147 IN NDIS_HANDLE MiniportAdapterHandle
,
148 IN NDIS_HANDLE WrapperConfigurationContext
)
150 * FUNCTION: Adapter initialization function
152 * OpenErrorStatus = Address of buffer to place additional status information
153 * SelectedMediumIndex = Address of buffer to place selected medium index
154 * MediumArray = Pointer to an array of NDIS_MEDIUMs
155 * MediaArraySize = Number of elements in MediumArray
156 * MiniportAdapterHandle = Miniport adapter handle assigned by NDIS
157 * WrapperConfigurationContext = Handle used to identify configuration context
159 * Status of operation
164 PNIC_ADAPTER Adapter
;
166 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
168 /* Search for 802.3 media which is the only one we support */
169 for (i
= 0; i
< MediumArraySize
; i
++) {
170 if (MediumArray
[i
] == NdisMedium802_3
)
174 if (i
== MediumArraySize
) {
175 NDIS_DbgPrint(MIN_TRACE
, ("No supported media.\n"));
176 return NDIS_STATUS_UNSUPPORTED_MEDIA
;
179 *SelectedMediumIndex
= i
;
181 Status
= NdisAllocateMemory((PVOID
)&Adapter
,
184 HighestAcceptableMax
);
185 if (Status
!= NDIS_STATUS_SUCCESS
) {
186 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
190 NdisZeroMemory(Adapter
, sizeof(NIC_ADAPTER
));
191 Adapter
->MiniportAdapterHandle
= MiniportAdapterHandle
;
192 Adapter
->IoBaseAddress
= DRIVER_DEFAULT_IO_BASE_ADDRESS
;
193 Adapter
->InterruptNumber
= DRIVER_DEFAULT_INTERRUPT_NUMBER
;
194 Adapter
->MaxMulticastListSize
= DRIVER_MAX_MULTICAST_LIST_SIZE
;
195 Adapter
->InterruptMask
= DRIVER_INTERRUPT_MASK
;
196 Adapter
->LookaheadSize
= DRIVER_MAXIMUM_LOOKAHEAD
;
198 /* get the port, irq, and MAC address from registry */
201 PNDIS_CONFIGURATION_PARAMETER ConfigurationParameter
;
202 NDIS_HANDLE ConfigurationHandle
;
203 UNICODE_STRING Keyword
;
204 UINT
*RegNetworkAddress
= 0;
205 UINT RegNetworkAddressLength
= 0;
207 NdisOpenConfiguration(&Status
, &ConfigurationHandle
, WrapperConfigurationContext
);
208 if(Status
!= NDIS_STATUS_SUCCESS
)
210 NDIS_DbgPrint(MIN_TRACE
,("NdisOpenConfiguration returned error 0x%x\n", Status
));
214 NdisInitUnicodeString(&Keyword
, L
"Irq");
215 NdisReadConfiguration(&Status
, &ConfigurationParameter
, ConfigurationHandle
, &Keyword
, NdisParameterInteger
);
216 if(Status
== NDIS_STATUS_SUCCESS
)
218 NDIS_DbgPrint(MID_TRACE
,("NdisReadConfiguration for Irq returned successfully, irq 0x%x\n",
219 ConfigurationParameter
->ParameterData
.IntegerData
));
220 Adapter
->InterruptNumber
= ConfigurationParameter
->ParameterData
.IntegerData
;
223 NdisInitUnicodeString(&Keyword
, L
"Port");
224 NdisReadConfiguration(&Status
, &ConfigurationParameter
, ConfigurationHandle
, &Keyword
, NdisParameterInteger
);
225 if(Status
== NDIS_STATUS_SUCCESS
)
227 NDIS_DbgPrint(MID_TRACE
,("NdisReadConfiguration for Port returned successfully, port 0x%x\n",
228 ConfigurationParameter
->ParameterData
.IntegerData
));
229 Adapter
->IoBaseAddress
= ConfigurationParameter
->ParameterData
.IntegerData
;
232 /* the returned copy of the data is owned by NDIS and will be released on NdisCloseConfiguration */
233 NdisReadNetworkAddress(&Status
, (PVOID
*)&RegNetworkAddress
, &RegNetworkAddressLength
, ConfigurationHandle
);
234 if(Status
== NDIS_STATUS_SUCCESS
&& RegNetworkAddressLength
== DRIVER_LENGTH_OF_ADDRESS
)
237 NDIS_DbgPrint(MID_TRACE
,("NdisReadNetworkAddress returned successfully, address %x:%x:%x:%x:%x:%x\n",
238 RegNetworkAddress
[0], RegNetworkAddress
[1], RegNetworkAddress
[2], RegNetworkAddress
[3],
239 RegNetworkAddress
[4], RegNetworkAddress
[5]));
240 for(i
= 0; i
< DRIVER_LENGTH_OF_ADDRESS
; i
++)
241 Adapter
->StationAddress
[i
] = RegNetworkAddress
[i
];
244 NdisCloseConfiguration(ConfigurationHandle
);
248 if (!NICCheck(Adapter
)) {
249 NDIS_DbgPrint(MID_TRACE
, ("No adapter found at (0x%X).\n", Adapter
->IOBase
));
250 return NDIS_STATUS_ADAPTER_NOT_FOUND
;
252 NDIS_DbgPrint(MID_TRACE
, ("Adapter found at (0x%X).\n", Adapter
->IOBase
));
256 MiniportAdapterHandle
,
257 (NDIS_HANDLE
)Adapter
,
261 Status
= NdisMRegisterIoPortRange(
262 (PVOID
*)&Adapter
->IOBase
,
263 MiniportAdapterHandle
,
264 Adapter
->IoBaseAddress
,
267 if (Status
!= NDIS_STATUS_SUCCESS
) {
268 NDIS_DbgPrint(MIN_TRACE
, ("Cannot register port range. Status (0x%X).\n", Status
));
269 MiniportHalt((NDIS_HANDLE
)Adapter
);
273 Adapter
->IOPortRangeRegistered
= TRUE
;
277 Status
= NICInitialize(Adapter
);
278 if (Status
!= NDIS_STATUS_SUCCESS
) {
279 NDIS_DbgPrint(MIN_TRACE
,("No NE2000 or compatible network adapter found at address 0x%X.\n",
282 NDIS_DbgPrint(MID_TRACE
, ("Status (0x%X).\n", Status
));
283 MiniportHalt((NDIS_HANDLE
)Adapter
);
287 NDIS_DbgPrint(MID_TRACE
, ("BOARDDATA:\n"));
288 for (i
= 0; i
< 4; i
++) {
289 NDIS_DbgPrint(MID_TRACE
, ("%02X %02X %02X %02X\n",
290 Adapter
->SAPROM
[i
*4+0],
291 Adapter
->SAPROM
[i
*4+1],
292 Adapter
->SAPROM
[i
*4+2],
293 Adapter
->SAPROM
[i
*4+3]));
296 /* Setup adapter structure */
297 Adapter
->TXStart
= ((ULONG_PTR
)Adapter
->RamBase
>> 8);
298 Adapter
->TXCount
= DRIVER_DEFAULT_TX_BUFFER_COUNT
;
299 Adapter
->TXFree
= DRIVER_DEFAULT_TX_BUFFER_COUNT
;
300 Adapter
->TXCurrent
= -1;
301 Adapter
->PageStart
= Adapter
->TXStart
+ Adapter
->TXCount
;
302 Adapter
->PageStop
= Adapter
->TXStart
+ (Adapter
->RamSize
>> 8);
304 /* Initialize multicast address mask to accept all */
305 for (i
= 0; i
< 8; i
++)
306 Adapter
->MulticastAddressMask
[i
] = 0xFF;
311 NDIS_DbgPrint(MID_TRACE
, ("TXStart (0x%X) TXCount (0x%X) PageStart (0x%X)\n",
314 Adapter
->PageStart
));
316 NDIS_DbgPrint(MID_TRACE
, ("PageStop (0x%X) CurrentPage (0x%X) NextPacket (0x%X).\n",
318 Adapter
->CurrentPage
,
319 Adapter
->NextPacket
));
321 /* Register the interrupt */
322 Status
= NdisMRegisterInterrupt(
324 MiniportAdapterHandle
,
325 Adapter
->InterruptNumber
,
326 Adapter
->InterruptNumber
,
329 NdisInterruptLatched
);
330 if (Status
!= NDIS_STATUS_SUCCESS
) {
331 NDIS_DbgPrint(MIN_TRACE
, ("Cannot register interrupt. Status (0x%X).\n", Status
));
332 MiniportHalt((NDIS_HANDLE
)Adapter
);
336 Adapter
->InterruptRegistered
= TRUE
;
341 /* Add adapter to the global adapter list */
342 InsertTailList(&DriverInfo
.AdapterListHead
, &Adapter
->ListEntry
);
344 NDIS_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
346 return NDIS_STATUS_SUCCESS
;
351 OUT PBOOLEAN InterruptRecognized
,
352 OUT PBOOLEAN QueueMiniportHandleInterrupt
,
353 IN NDIS_HANDLE MiniportAdapterContext
)
355 * FUNCTION: Interrupt Service Routine for controlled adapters
357 * InterruptRecognized = Address of buffer to place wether
358 * the adapter generated the interrupt
359 * QueueMiniportHandleInterrupt = Address of buffer to place wether
360 * MiniportHandleInterrupt should be called
361 * MiniportAdapterContext = Pointer to adapter context area
363 * All pending interrupts are handled
366 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
368 NICDisableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
370 *InterruptRecognized
= TRUE
;
371 *QueueMiniportHandleInterrupt
= TRUE
;
375 NDIS_STATUS
MiniportQueryInformation(
376 IN NDIS_HANDLE MiniportAdapterContext
,
378 IN PVOID InformationBuffer
,
379 IN ULONG InformationBufferLength
,
380 OUT PULONG BytesWritten
,
381 OUT PULONG BytesNeeded
)
383 * FUNCTION: Handler to process queries
385 * MiniportAdapterContext = Pointer to adapter context area
386 * Oid = OID code designating query operation
387 * InformationBuffer = Address of return buffer
388 * InformationBufferLength = Length of return buffer
389 * BytesWritten = Address of buffer to place number of bytes returned
390 * BytesNeeded = Address of buffer to place number of bytes needed
391 * in InformationBuffer for specified OID
393 * Status of operation
400 USHORT GenericUSHORT
;
401 NDIS_MEDIUM Medium
= NdisMedium802_3
;
402 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
404 NDIS_DbgPrint(MAX_TRACE
, ("Called. Oid (0x%X).\n", Oid
));
406 Status
= NDIS_STATUS_SUCCESS
;
407 CopyFrom
= (PVOID
)&GenericULONG
;
408 CopySize
= sizeof(ULONG
);
411 case OID_GEN_SUPPORTED_LIST
:
412 CopyFrom
= (PVOID
)&MiniportOIDList
;
413 CopySize
= sizeof(MiniportOIDList
);
415 case OID_GEN_HARDWARE_STATUS
:
416 GenericULONG
= (ULONG
)NdisHardwareStatusReady
;
418 case OID_GEN_MEDIA_SUPPORTED
:
419 case OID_GEN_MEDIA_IN_USE
:
420 CopyFrom
= (PVOID
)&Medium
;
421 CopySize
= sizeof(NDIS_MEDIUM
);
423 case OID_GEN_MAXIMUM_LOOKAHEAD
:
424 GenericULONG
= DRIVER_MAXIMUM_LOOKAHEAD
;
426 case OID_GEN_MAXIMUM_FRAME_SIZE
:
427 GenericULONG
= DRIVER_FRAME_SIZE
- DRIVER_HEADER_SIZE
;
429 case OID_GEN_LINK_SPEED
:
430 GenericULONG
= 100000; /* 10Mbps */
432 case OID_GEN_TRANSMIT_BUFFER_SPACE
:
433 GenericULONG
= Adapter
->TXCount
* DRIVER_BLOCK_SIZE
;
435 case OID_GEN_RECEIVE_BUFFER_SPACE
:
436 GenericULONG
= Adapter
->RamSize
-
437 (ULONG_PTR
)Adapter
->RamBase
-
438 (Adapter
->TXCount
* DRIVER_BLOCK_SIZE
);
440 case OID_GEN_TRANSMIT_BLOCK_SIZE
:
441 GenericULONG
= DRIVER_BLOCK_SIZE
;
443 case OID_GEN_RECEIVE_BLOCK_SIZE
:
444 GenericULONG
= DRIVER_BLOCK_SIZE
;
446 case OID_GEN_VENDOR_ID
:
447 NdisMoveMemory(&GenericULONG
, &Adapter
->PermanentAddress
, 3);
448 GenericULONG
&= 0xFFFFFF00;
449 GenericULONG
|= 0x01;
451 case OID_GEN_VENDOR_DESCRIPTION
:
452 CopyFrom
= (PVOID
)&DRIVER_VENDOR_DESCRIPTION
;
453 CopySize
= sizeof(DRIVER_VENDOR_DESCRIPTION
);
455 case OID_GEN_VENDOR_DRIVER_VERSION
:
456 GenericUSHORT
= (USHORT
)DRIVER_VENDOR_DRIVER_VERSION
;
457 CopyFrom
= (PVOID
)&GenericUSHORT
;
458 CopySize
= sizeof(USHORT
);
460 case OID_GEN_CURRENT_PACKET_FILTER
:
461 GenericULONG
= Adapter
->PacketFilter
;
463 case OID_GEN_CURRENT_LOOKAHEAD
:
464 GenericULONG
= Adapter
->LookaheadSize
;
466 case OID_GEN_DRIVER_VERSION
:
467 GenericUSHORT
= ((USHORT
)DRIVER_NDIS_MAJOR_VERSION
<< 8) | DRIVER_NDIS_MINOR_VERSION
;
468 CopyFrom
= (PVOID
)&GenericUSHORT
;
469 CopySize
= sizeof(USHORT
);
471 case OID_GEN_MAXIMUM_TOTAL_SIZE
:
472 GenericULONG
= DRIVER_FRAME_SIZE
;
474 case OID_GEN_PROTOCOL_OPTIONS
:
475 NDIS_DbgPrint(MID_TRACE
, ("OID_GEN_PROTOCOL_OPTIONS.\n"));
476 Status
= NDIS_STATUS_NOT_SUPPORTED
;
478 case OID_GEN_MAC_OPTIONS
:
479 GenericULONG
= NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA
|
480 NDIS_MAC_OPTION_RECEIVE_SERIALIZED
|
481 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND
|
482 NDIS_MAC_OPTION_NO_LOOPBACK
;
484 case OID_GEN_MEDIA_CONNECT_STATUS
:
485 GenericULONG
= (ULONG
)NdisMediaStateConnected
;
487 case OID_GEN_MAXIMUM_SEND_PACKETS
:
490 case OID_802_3_PERMANENT_ADDRESS
:
491 CopyFrom
= (PVOID
)&Adapter
->PermanentAddress
;
492 CopySize
= DRIVER_LENGTH_OF_ADDRESS
;
494 case OID_802_3_CURRENT_ADDRESS
:
495 CopyFrom
= (PVOID
)&Adapter
->StationAddress
;
496 CopySize
= DRIVER_LENGTH_OF_ADDRESS
;
498 case OID_802_3_MULTICAST_LIST
:
499 NDIS_DbgPrint(MID_TRACE
, ("OID_802_3_MULTICAST_LIST.\n"));
500 Status
= NDIS_STATUS_NOT_SUPPORTED
;
502 case OID_802_3_MAXIMUM_LIST_SIZE
:
503 GenericULONG
= Adapter
->MaxMulticastListSize
;
505 case OID_802_3_MAC_OPTIONS
:
506 NDIS_DbgPrint(MID_TRACE
, ("OID_802_3_MAC_OPTIONS.\n"));
507 Status
= NDIS_STATUS_NOT_SUPPORTED
;
510 NDIS_DbgPrint(MIN_TRACE
, ("Unknown OID (0x%X).\n", Oid
));
511 Status
= NDIS_STATUS_INVALID_OID
;
515 if (Status
== NDIS_STATUS_SUCCESS
) {
516 if (CopySize
> InformationBufferLength
) {
517 *BytesNeeded
= (CopySize
- InformationBufferLength
);
519 Status
= NDIS_STATUS_INVALID_LENGTH
;
521 NdisMoveMemory(InformationBuffer
, CopyFrom
, CopySize
);
522 *BytesWritten
= CopySize
;
527 NDIS_DbgPrint(MAX_TRACE
, ("Leaving. Status is (0x%X).\n", Status
));
533 NDIS_STATUS
MiniportReconfigure(
534 OUT PNDIS_STATUS OpenErrorStatus
,
535 IN NDIS_HANDLE MiniportAdapterContext
,
536 IN NDIS_HANDLE WrapperConfigurationContext
)
538 * FUNCTION: Reconfigures an adapter
540 * OpenErrorStatus = Address of buffer to place additional status information
541 * MiniportAdapterContext = Pointer to adapter context area
542 * WrapperConfigurationContext = Handle used to identify configuration context
544 * Status of operation
546 * Never called by NDIS library
549 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
551 return NDIS_STATUS_FAILURE
;
556 NDIS_STATUS
MiniportReset(
557 OUT PBOOLEAN AddressingReset
,
558 IN NDIS_HANDLE MiniportAdapterContext
)
560 * FUNCTION: Resets an adapter
562 * AddressingReset = Address of a buffer to place value indicating
563 * wether NDIS library should call MiniportSetInformation
564 * to restore addressing information
565 * MiniportAdapterContext = Pointer to adapter context area
567 * Status of operation
570 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
572 return NDIS_STATUS_FAILURE
;
576 NDIS_STATUS
MiniportSend(
577 IN NDIS_HANDLE MiniportAdapterContext
,
578 IN PNDIS_PACKET Packet
,
581 * FUNCTION: Transmits a packet
583 * MiniportAdapterContext = Pointer to adapter context area
584 * Packet = Pointer to a packet descriptor specifying
585 * the data to be transmitted
586 * Flags = Specifies optional packet flags
588 * Status of operation
591 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
593 NDIS_DbgPrint(MID_TRACE
, ("Queueing packet.\n"));
596 NdisMSendComplete(Adapter
->MiniportAdapterHandle
,
598 NDIS_STATUS_SUCCESS
);
600 /* Queue the packet on the transmit queue */
601 RESERVED(Packet
)->Next
= NULL
;
602 if (Adapter
->TXQueueHead
== NULL
) {
603 Adapter
->TXQueueHead
= Packet
;
605 RESERVED(Adapter
->TXQueueTail
)->Next
= Packet
;
608 Adapter
->TXQueueTail
= Packet
;
610 /* Transmit the packet */
611 NICTransmit(Adapter
);
613 return NDIS_STATUS_PENDING
;
617 NDIS_STATUS
MiniportSetInformation(
618 IN NDIS_HANDLE MiniportAdapterContext
,
620 IN PVOID InformationBuffer
,
621 IN ULONG InformationBufferLength
,
622 OUT PULONG BytesRead
,
623 OUT PULONG BytesNeeded
)
625 * FUNCTION: Changes state information in the driver
627 * MiniportAdapterContext = Pointer to adapter context area
628 * Oid = OID code designating set operation
629 * InformationBuffer = Pointer to buffer with state information
630 * InformationBufferLength = Length of InformationBuffer
631 * BytesRead = Address of buffer to place number of bytes read
632 * BytesNeeded = Address of buffer to place number of extra bytes
633 * needed in InformationBuffer for specified OID
635 * Status of operation
639 NDIS_STATUS Status
= NDIS_STATUS_SUCCESS
;
640 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
642 NDIS_DbgPrint(MAX_TRACE
, ("Called. Oid (0x%X).\n", Oid
));
645 case OID_GEN_CURRENT_PACKET_FILTER
:
647 if (InformationBufferLength
< sizeof(ULONG
)) {
649 *BytesNeeded
= sizeof(ULONG
) - InformationBufferLength
;
650 Status
= NDIS_STATUS_INVALID_LENGTH
;
654 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
655 /* Check for properties the driver don't support */
657 (NDIS_PACKET_TYPE_ALL_FUNCTIONAL
|
658 NDIS_PACKET_TYPE_FUNCTIONAL
|
659 NDIS_PACKET_TYPE_GROUP
|
660 NDIS_PACKET_TYPE_MAC_FRAME
|
661 NDIS_PACKET_TYPE_SMT
|
662 NDIS_PACKET_TYPE_SOURCE_ROUTING
)) {
665 Status
= NDIS_STATUS_NOT_SUPPORTED
;
669 Adapter
->PacketFilter
= GenericULONG
;
671 /* FIXME: Set filter on hardware */
674 case OID_GEN_CURRENT_LOOKAHEAD
:
676 if (InformationBufferLength
< sizeof(ULONG
)) {
678 *BytesNeeded
= sizeof(ULONG
) - InformationBufferLength
;
679 Status
= NDIS_STATUS_INVALID_LENGTH
;
683 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
684 if (GenericULONG
> DRIVER_MAXIMUM_LOOKAHEAD
)
685 Status
= NDIS_STATUS_INVALID_LENGTH
;
687 Adapter
->LookaheadSize
= GenericULONG
;
689 case OID_802_3_MULTICAST_LIST
:
690 /* Verify length. Must be multiplum of hardware address length */
691 if ((InformationBufferLength
% DRIVER_LENGTH_OF_ADDRESS
) != 0) {
694 Status
= NDIS_STATUS_INVALID_LENGTH
;
698 /* Set new multicast address list */
699 NdisMoveMemory(Adapter
->Addresses
, InformationBuffer
, InformationBufferLength
);
701 /* FIXME: Update hardware */
705 NDIS_DbgPrint(MIN_TRACE
, ("Invalid object ID (0x%X).\n", Oid
));
708 Status
= NDIS_STATUS_INVALID_OID
;
712 if (Status
== NDIS_STATUS_SUCCESS
) {
713 *BytesRead
= InformationBufferLength
;
717 NDIS_DbgPrint(MAX_TRACE
, ("Leaving. Status (0x%X).\n", Status
));
723 NDIS_STATUS
MiniportTransferData(
724 OUT PNDIS_PACKET Packet
,
725 OUT PUINT BytesTransferred
,
726 IN NDIS_HANDLE MiniportAdapterContext
,
727 IN NDIS_HANDLE MiniportReceiveContext
,
729 IN UINT BytesToTransfer
)
731 * FUNCTION: Transfers data from a received frame into an NDIS packet
733 * Packet = Address of packet to copy received data into
734 * BytesTransferred = Address of buffer to place number of bytes transmitted
735 * MiniportAdapterContext = Pointer to adapter context area
736 * MiniportReceiveContext = Pointer to receive context area (actually NULL)
737 * ByteOffset = Offset within received packet to begin copying
738 * BytesToTransfer = Number of bytes to copy into packet
740 * Status of operation
743 PNDIS_BUFFER DstBuffer
;
744 UINT BytesCopied
, BytesToCopy
, DstSize
;
749 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
751 NDIS_DbgPrint(MAX_TRACE
, ("Called. Packet (0x%X) ByteOffset (0x%X) BytesToTransfer (%d).\n",
752 Packet
, ByteOffset
, BytesToTransfer
));
754 if (BytesToTransfer
== 0) {
755 *BytesTransferred
= 0;
756 return NDIS_STATUS_SUCCESS
;
759 RecvStart
= Adapter
->PageStart
* DRIVER_BLOCK_SIZE
;
760 RecvStop
= Adapter
->PageStop
* DRIVER_BLOCK_SIZE
;
762 NdisQueryPacket(Packet
, NULL
, NULL
, &DstBuffer
, NULL
);
763 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
765 SrcData
= Adapter
->PacketOffset
+ sizeof(PACKET_HEADER
) + ByteOffset
;
766 if (ByteOffset
+ sizeof(PACKET_HEADER
) + BytesToTransfer
> Adapter
->PacketHeader
.PacketLength
)
767 BytesToTransfer
= Adapter
->PacketHeader
.PacketLength
- sizeof(PACKET_HEADER
) - ByteOffset
;
769 /* Start copying the data */
772 BytesToCopy
= (DstSize
< BytesToTransfer
)? DstSize
: BytesToTransfer
;
773 if (SrcData
+ BytesToCopy
> RecvStop
)
774 BytesToCopy
= (RecvStop
- SrcData
);
776 NICReadData(Adapter
, DstData
, SrcData
, BytesToCopy
);
778 BytesCopied
+= BytesToCopy
;
779 SrcData
+= BytesToCopy
;
780 (ULONG_PTR
)DstData
+= BytesToCopy
;
781 BytesToTransfer
-= BytesToCopy
;
782 if (BytesToTransfer
== 0)
785 DstSize
-= BytesToCopy
;
787 /* No more bytes in destination buffer. Proceed to
788 the next buffer in the destination buffer chain */
789 NdisGetNextBuffer(DstBuffer
, &DstBuffer
);
793 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
796 if (SrcData
== RecvStop
)
800 NDIS_DbgPrint(MID_TRACE
, ("Transferred (%d) bytes.\n", BytesToTransfer
));
802 *BytesTransferred
= BytesCopied
;
804 return NDIS_STATUS_SUCCESS
;
813 PDRIVER_OBJECT DriverObject
,
814 PUNICODE_STRING RegistryPath
)
816 * FUNCTION: Main driver entry point
818 * DriverObject = Pointer to a driver object for this driver
819 * RegistryPath = Registry node for configuration parameters
821 * Status of driver initialization
825 NDIS_HANDLE NdisWrapperHandle
;
826 NDIS_MINIPORT_CHARACTERISTICS Miniport
;
828 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
830 NdisZeroMemory(&Miniport
, sizeof(Miniport
));
831 Miniport
.MajorNdisVersion
= DRIVER_NDIS_MAJOR_VERSION
;
832 Miniport
.MinorNdisVersion
= DRIVER_NDIS_MINOR_VERSION
;
833 Miniport
.CheckForHangHandler
= NULL
; //MiniportCheckForHang;
834 Miniport
.DisableInterruptHandler
= MiniportDisableInterrupt
;
835 Miniport
.EnableInterruptHandler
= MiniportEnableInterrupt
;
836 Miniport
.HaltHandler
= MiniportHalt
;
837 Miniport
.HandleInterruptHandler
= MiniportHandleInterrupt
;
838 Miniport
.InitializeHandler
= MiniportInitialize
;
839 Miniport
.ISRHandler
= MiniportISR
;
840 Miniport
.QueryInformationHandler
= MiniportQueryInformation
;
841 Miniport
.ReconfigureHandler
= MiniportReconfigure
;
842 Miniport
.ResetHandler
= MiniportReset
;
843 Miniport
.u1
.SendHandler
= MiniportSend
;
844 Miniport
.SetInformationHandler
= MiniportSetInformation
;
845 Miniport
.u2
.TransferDataHandler
= MiniportTransferData
;
847 NdisMInitializeWrapper(&NdisWrapperHandle
,
852 DriverInfo
.NdisWrapperHandle
= NdisWrapperHandle
;
853 DriverInfo
.NdisMacHandle
= NULL
;
854 InitializeListHead(&DriverInfo
.AdapterListHead
);
856 Status
= NdisMRegisterMiniport(NdisWrapperHandle
,
858 sizeof(NDIS_MINIPORT_CHARACTERISTICS
));
859 if (Status
!= NDIS_STATUS_SUCCESS
) {
860 NDIS_DbgPrint(MIN_TRACE
, ("NdisMRegisterMiniport() failed with status code (0x%X).\n", Status
));
861 NdisTerminateWrapper(NdisWrapperHandle
, NULL
);
862 return STATUS_UNSUCCESSFUL
;
865 return STATUS_SUCCESS
;
869 /* while i'm here - some basic registry sanity checks */
872 NDIS_CONFIGURATION_PARAMETER ParameterValue
;
874 ParameterValue
.ParameterType
= NdisParameterInteger
;
875 ParameterValue
.ParameterData
.IntegerData
= 0x12345678;
876 NdisInitUnicodeString(&Keyword
, L
"DwordTest");
877 NdisWriteConfiguration(&Status
, ConfigurationHandle
, &Keyword
, &ParameterValue
);
879 if(Status
!= NDIS_STATUS_SUCCESS
)
881 DbgPrint("ne2000!MiniportInitialize: failed to set DwordTest: 0x%x\n", Status
);
885 DbgPrint("ne2000!MiniportInitialize: DwordTest successfully set\n");
887 NdisInitUnicodeString(&Keyword
, L
"StringTest");
888 ParameterValue
.ParameterType
= NdisParameterString
;
889 NdisInitUnicodeString(&ParameterValue
.ParameterData
.StringData
, L
"Testing123");
891 NdisWriteConfiguration(&Status
, ConfigurationHandle
, &Keyword
, &ParameterValue
);
893 if(Status
!= NDIS_STATUS_SUCCESS
)
895 DbgPrint("ne2000!MiniportInitialize: failed to set StringTest: 0x%x\n", Status
);
899 DbgPrint("ne2000!MiniportInitialize: StringTest successfully set\n");
903 /* read back the test values */
904 NDIS_CONFIGURATION_PARAMETER
*ParameterValue
= 0;
906 NdisInitUnicodeString(&Keyword
, L
"DwordTest");
907 NdisReadConfiguration(&Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterInteger
);
909 if(Status
!= NDIS_STATUS_SUCCESS
)
911 DbgPrint("ne2000!MiniportInitialize: failed to read DwordTest: 0x%x\n", Status
);
915 if(ParameterValue
->ParameterData
.IntegerData
!= 0x12345678)
917 DbgPrint("ne2000!MiniportInitialize: DwordTest value is wrong: 0x%x\n",
918 ParameterValue
->ParameterData
.IntegerData
);
922 DbgPrint("ne2000!MiniportInitialize: DwordTest value was correctly read\n");
924 NdisInitUnicodeString(&Keyword
, L
"StringTest");
925 NdisReadConfiguration(&Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterString
);
927 if(Status
!= NDIS_STATUS_SUCCESS
)
929 DbgPrint("ne2000!MiniportInitialize: failed to read StringTest: 0x%x\n", Status
);
933 if(wcsncmp(ParameterValue
->ParameterData
.StringData
.Buffer
, L
"Testing123",
934 wcslen(L
"Testing123")))
936 DbgPrint("ne2000!MiniportInitialize: StringTest value is wrong: %wZ\n",
937 &ParameterValue
->ParameterData
.StringData
);
941 DbgPrint("ne2000!MiniportInitialize: StringTest value was correctly read\n");