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
17 /* See debug.h for debug/trace constants */
18 ULONG DebugTraceLevel
= MIN_TRACE
;
23 /* List of supported OIDs */
24 static ULONG MiniportOIDList
[] = {
25 OID_GEN_SUPPORTED_LIST
,
26 OID_GEN_HARDWARE_STATUS
,
27 OID_GEN_MEDIA_SUPPORTED
,
29 OID_GEN_MAXIMUM_LOOKAHEAD
,
30 OID_GEN_MAXIMUM_FRAME_SIZE
,
32 OID_GEN_TRANSMIT_BUFFER_SPACE
,
33 OID_GEN_RECEIVE_BUFFER_SPACE
,
34 OID_GEN_TRANSMIT_BLOCK_SIZE
,
35 OID_GEN_RECEIVE_BLOCK_SIZE
,
37 OID_GEN_VENDOR_DESCRIPTION
,
38 OID_GEN_VENDOR_DRIVER_VERSION
,
39 OID_GEN_CURRENT_PACKET_FILTER
,
40 OID_GEN_CURRENT_LOOKAHEAD
,
41 OID_GEN_DRIVER_VERSION
,
42 OID_GEN_MAXIMUM_TOTAL_SIZE
,
43 OID_GEN_PROTOCOL_OPTIONS
,
45 OID_GEN_MEDIA_CONNECT_STATUS
,
46 OID_GEN_MAXIMUM_SEND_PACKETS
,
47 OID_802_3_PERMANENT_ADDRESS
,
48 OID_802_3_CURRENT_ADDRESS
,
49 OID_802_3_MULTICAST_LIST
,
50 OID_802_3_MAXIMUM_LIST_SIZE
,
54 DRIVER_INFORMATION DriverInfo
= {0};
55 NDIS_PHYSICAL_ADDRESS HighestAcceptableMax
= NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
58 BOOLEAN
MiniportCheckForHang(
59 IN NDIS_HANDLE MiniportAdapterContext
)
61 * FUNCTION: Examines if an adapter has hung
63 * MiniportAdapterContext = Pointer to adapter context area
65 * TRUE if the adapter has hung, FALSE if not
68 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
74 VOID STDCALL
MiniportDisableInterrupt(
75 IN NDIS_HANDLE MiniportAdapterContext
)
77 * FUNCTION: Disables interrupts from an adapter
79 * MiniportAdapterContext = Pointer to adapter context area
82 NDIS_DbgPrint(MAX_TRACE
, ("Called. (MiniportDisableInterrupt).\n"));
84 NICDisableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
89 VOID STDCALL
MiniportEnableInterrupt(
90 IN NDIS_HANDLE MiniportAdapterContext
)
92 * FUNCTION: Enables interrupts from an adapter
94 * MiniportAdapterContext = Pointer to adapter context area
97 NDIS_DbgPrint(MAX_TRACE
, ("Called. (MiniportEnableInterrupt).\n"));
99 NICEnableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
104 VOID STDCALL
MiniportHalt(
105 IN NDIS_HANDLE MiniportAdapterContext
)
107 * FUNCTION: Deallocates resources for and halts an adapter
109 * MiniportAdapterContext = Pointer to adapter context area
112 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
114 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
119 /* Wait for any DPCs to complete. FIXME: Use something else */
120 NdisStallExecution(250000);
122 if (Adapter
->InterruptRegistered
)
123 /* Deregister interrupt */
124 NdisMDeregisterInterrupt(&Adapter
->Interrupt
);
126 if (Adapter
->IOPortRangeRegistered
)
127 /* Deregister I/O port range */
128 NdisMDeregisterIoPortRange(
129 Adapter
->MiniportAdapterHandle
,
130 Adapter
->IoBaseAddress
,
134 /* Remove adapter from global adapter list */
135 if ((&Adapter
->ListEntry
)->Blink
!= NULL
) {
136 RemoveEntryList(&Adapter
->ListEntry
);
139 /* Free adapter context area */
140 NdisFreeMemory(Adapter
, sizeof(NIC_ADAPTER
), 0);
144 NDIS_STATUS STDCALL
MiniportInitialize(
145 OUT PNDIS_STATUS OpenErrorStatus
,
146 OUT PUINT SelectedMediumIndex
,
147 IN PNDIS_MEDIUM MediumArray
,
148 IN UINT MediumArraySize
,
149 IN NDIS_HANDLE MiniportAdapterHandle
,
150 IN NDIS_HANDLE WrapperConfigurationContext
)
152 * FUNCTION: Adapter initialization function
154 * OpenErrorStatus = Address of buffer to place additional status information
155 * SelectedMediumIndex = Address of buffer to place selected medium index
156 * MediumArray = Pointer to an array of NDIS_MEDIUMs
157 * MediaArraySize = Number of elements in MediumArray
158 * MiniportAdapterHandle = Miniport adapter handle assigned by NDIS
159 * WrapperConfigurationContext = Handle used to identify configuration context
161 * Status of operation
166 PNIC_ADAPTER Adapter
;
168 NDIS_DbgPrint(MAX_TRACE
, ("Called (Adapter %X).\n", MiniportAdapterHandle
));
170 /* Search for 802.3 media which is the only one we support */
171 for (i
= 0; i
< MediumArraySize
; i
++) {
172 if (MediumArray
[i
] == NdisMedium802_3
)
176 if (i
== MediumArraySize
) {
177 NDIS_DbgPrint(MIN_TRACE
, ("No supported media.\n"));
178 return NDIS_STATUS_UNSUPPORTED_MEDIA
;
181 *SelectedMediumIndex
= i
;
183 Status
= NdisAllocateMemory((PVOID
)&Adapter
,
186 HighestAcceptableMax
);
187 if (Status
!= NDIS_STATUS_SUCCESS
) {
188 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
192 NdisZeroMemory(Adapter
, sizeof(NIC_ADAPTER
));
193 Adapter
->MiniportAdapterHandle
= MiniportAdapterHandle
;
194 Adapter
->IoBaseAddress
= DRIVER_DEFAULT_IO_BASE_ADDRESS
;
195 Adapter
->InterruptNumber
= DRIVER_DEFAULT_INTERRUPT_NUMBER
;
196 Adapter
->MaxMulticastListSize
= DRIVER_MAX_MULTICAST_LIST_SIZE
;
197 Adapter
->InterruptMask
= DRIVER_INTERRUPT_MASK
;
198 Adapter
->LookaheadSize
= DRIVER_MAXIMUM_LOOKAHEAD
;
200 /* get the port, irq, and MAC address from registry */
203 PNDIS_CONFIGURATION_PARAMETER ConfigurationParameter
;
204 NDIS_HANDLE ConfigurationHandle
;
205 UNICODE_STRING Keyword
;
206 UINT
*RegNetworkAddress
= 0;
207 UINT RegNetworkAddressLength
= 0;
209 NdisOpenConfiguration(&Status
, &ConfigurationHandle
, WrapperConfigurationContext
);
210 if(Status
!= NDIS_STATUS_SUCCESS
)
212 NDIS_DbgPrint(MIN_TRACE
,("NdisOpenConfiguration returned error 0x%x\n", Status
));
216 NdisInitUnicodeString(&Keyword
, L
"Irq");
217 NdisReadConfiguration(&Status
, &ConfigurationParameter
, ConfigurationHandle
, &Keyword
, NdisParameterInteger
);
218 if(Status
== NDIS_STATUS_SUCCESS
)
220 NDIS_DbgPrint(MID_TRACE
,("NdisReadConfiguration for Irq returned successfully, irq 0x%x\n",
221 ConfigurationParameter
->ParameterData
.IntegerData
));
222 Adapter
->InterruptNumber
= ConfigurationParameter
->ParameterData
.IntegerData
;
225 NdisInitUnicodeString(&Keyword
, L
"Port");
226 NdisReadConfiguration(&Status
, &ConfigurationParameter
, ConfigurationHandle
, &Keyword
, NdisParameterInteger
);
227 if(Status
== NDIS_STATUS_SUCCESS
)
229 NDIS_DbgPrint(MID_TRACE
,("NdisReadConfiguration for Port returned successfully, port 0x%x\n",
230 ConfigurationParameter
->ParameterData
.IntegerData
));
231 Adapter
->IoBaseAddress
= ConfigurationParameter
->ParameterData
.IntegerData
;
234 /* the returned copy of the data is owned by NDIS and will be released on NdisCloseConfiguration */
235 NdisReadNetworkAddress(&Status
, (PVOID
*)&RegNetworkAddress
, &RegNetworkAddressLength
, ConfigurationHandle
);
236 if(Status
== NDIS_STATUS_SUCCESS
&& RegNetworkAddressLength
== DRIVER_LENGTH_OF_ADDRESS
)
239 NDIS_DbgPrint(MID_TRACE
,("NdisReadNetworkAddress returned successfully, address %x:%x:%x:%x:%x:%x\n",
240 RegNetworkAddress
[0], RegNetworkAddress
[1], RegNetworkAddress
[2], RegNetworkAddress
[3],
241 RegNetworkAddress
[4], RegNetworkAddress
[5]));
242 for(i
= 0; i
< DRIVER_LENGTH_OF_ADDRESS
; i
++)
243 Adapter
->StationAddress
[i
] = RegNetworkAddress
[i
];
246 NdisCloseConfiguration(ConfigurationHandle
);
250 if (!NICCheck(Adapter
)) {
251 NDIS_DbgPrint(MID_TRACE
, ("No adapter found at (0x%X).\n", Adapter
->IOBase
));
252 return NDIS_STATUS_ADAPTER_NOT_FOUND
;
254 NDIS_DbgPrint(MID_TRACE
, ("Adapter found at (0x%X).\n", Adapter
->IOBase
));
258 MiniportAdapterHandle
,
259 (NDIS_HANDLE
)Adapter
,
263 Status
= NdisMRegisterIoPortRange(
264 (PVOID
*)&Adapter
->IOBase
,
265 MiniportAdapterHandle
,
266 Adapter
->IoBaseAddress
,
269 if (Status
!= NDIS_STATUS_SUCCESS
) {
270 NDIS_DbgPrint(MIN_TRACE
, ("Cannot register port range. Status (0x%X).\n", Status
));
271 MiniportHalt((NDIS_HANDLE
)Adapter
);
275 Adapter
->IOPortRangeRegistered
= TRUE
;
279 Status
= NICInitialize(Adapter
);
280 if (Status
!= NDIS_STATUS_SUCCESS
) {
281 NDIS_DbgPrint(MIN_TRACE
,("No NE2000 or compatible network adapter found at address 0x%X.\n",
284 NDIS_DbgPrint(MID_TRACE
, ("Status (0x%X).\n", Status
));
285 MiniportHalt((NDIS_HANDLE
)Adapter
);
289 NDIS_DbgPrint(MID_TRACE
, ("BOARDDATA:\n"));
290 for (i
= 0; i
< 4; i
++) {
291 NDIS_DbgPrint(MID_TRACE
, ("%02X %02X %02X %02X\n",
292 Adapter
->SAPROM
[i
*4+0],
293 Adapter
->SAPROM
[i
*4+1],
294 Adapter
->SAPROM
[i
*4+2],
295 Adapter
->SAPROM
[i
*4+3]));
298 /* Setup adapter structure */
299 Adapter
->TXStart
= ((ULONG_PTR
)Adapter
->RamBase
>> 8);
300 Adapter
->TXCount
= DRIVER_DEFAULT_TX_BUFFER_COUNT
;
301 Adapter
->TXFree
= DRIVER_DEFAULT_TX_BUFFER_COUNT
;
302 Adapter
->TXCurrent
= -1;
303 Adapter
->PageStart
= Adapter
->TXStart
+ Adapter
->TXCount
;
304 Adapter
->PageStop
= Adapter
->TXStart
+ (Adapter
->RamSize
>> 8);
306 /* Initialize multicast address mask to accept all */
307 for (i
= 0; i
< 8; i
++)
308 Adapter
->MulticastAddressMask
[i
] = 0xFF;
313 NDIS_DbgPrint(MID_TRACE
, ("TXStart (0x%X) TXCount (0x%X) PageStart (0x%X)\n",
316 Adapter
->PageStart
));
318 NDIS_DbgPrint(MID_TRACE
, ("PageStop (0x%X) CurrentPage (0x%X) NextPacket (0x%X).\n",
320 Adapter
->CurrentPage
,
321 Adapter
->NextPacket
));
323 /* Register the interrupt */
324 Status
= NdisMRegisterInterrupt(
326 MiniportAdapterHandle
,
327 Adapter
->InterruptNumber
,
328 Adapter
->InterruptNumber
,
331 NdisInterruptLatched
);
332 if (Status
!= NDIS_STATUS_SUCCESS
) {
333 NDIS_DbgPrint(MIN_TRACE
, ("Cannot register interrupt. Status (0x%X).\n", Status
));
334 MiniportHalt((NDIS_HANDLE
)Adapter
);
338 Adapter
->InterruptRegistered
= TRUE
;
343 /* Add adapter to the global adapter list */
344 InsertTailList(&DriverInfo
.AdapterListHead
, &Adapter
->ListEntry
);
346 NDIS_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
348 return NDIS_STATUS_SUCCESS
;
352 VOID STDCALL
MiniportISR(
353 OUT PBOOLEAN InterruptRecognized
,
354 OUT PBOOLEAN QueueMiniportHandleInterrupt
,
355 IN NDIS_HANDLE MiniportAdapterContext
)
357 * FUNCTION: Interrupt Service Routine for controlled adapters
359 * InterruptRecognized = Address of buffer to place wether
360 * the adapter generated the interrupt
361 * QueueMiniportHandleInterrupt = Address of buffer to place wether
362 * MiniportHandleInterrupt should be called
363 * MiniportAdapterContext = Pointer to adapter context area
365 * All pending interrupts are handled
368 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
370 NICDisableInterrupts((PNIC_ADAPTER
)MiniportAdapterContext
);
372 *InterruptRecognized
= TRUE
;
373 *QueueMiniportHandleInterrupt
= TRUE
;
377 NDIS_STATUS STDCALL
MiniportQueryInformation(
378 IN NDIS_HANDLE MiniportAdapterContext
,
380 IN PVOID InformationBuffer
,
381 IN ULONG InformationBufferLength
,
382 OUT PULONG BytesWritten
,
383 OUT PULONG BytesNeeded
)
385 * FUNCTION: Handler to process queries
387 * MiniportAdapterContext = Pointer to adapter context area
388 * Oid = OID code designating query operation
389 * InformationBuffer = Address of return buffer
390 * InformationBufferLength = Length of return buffer
391 * BytesWritten = Address of buffer to place number of bytes returned
392 * BytesNeeded = Address of buffer to place number of bytes needed
393 * in InformationBuffer for specified OID
395 * Status of operation
402 USHORT GenericUSHORT
;
403 NDIS_MEDIUM Medium
= NdisMedium802_3
;
404 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
406 NDIS_DbgPrint(MAX_TRACE
, ("Called. Oid (0x%X).\n", Oid
));
408 Status
= NDIS_STATUS_SUCCESS
;
409 CopyFrom
= (PVOID
)&GenericULONG
;
410 CopySize
= sizeof(ULONG
);
413 case OID_GEN_SUPPORTED_LIST
:
414 CopyFrom
= (PVOID
)&MiniportOIDList
;
415 CopySize
= sizeof(MiniportOIDList
);
417 case OID_GEN_HARDWARE_STATUS
:
418 GenericULONG
= (ULONG
)NdisHardwareStatusReady
;
420 case OID_GEN_MEDIA_SUPPORTED
:
421 case OID_GEN_MEDIA_IN_USE
:
422 CopyFrom
= (PVOID
)&Medium
;
423 CopySize
= sizeof(NDIS_MEDIUM
);
425 case OID_GEN_MAXIMUM_LOOKAHEAD
:
426 GenericULONG
= DRIVER_MAXIMUM_LOOKAHEAD
;
428 case OID_GEN_MAXIMUM_FRAME_SIZE
:
429 GenericULONG
= DRIVER_FRAME_SIZE
- DRIVER_HEADER_SIZE
;
431 case OID_GEN_LINK_SPEED
:
432 GenericULONG
= 100000; /* 10Mbps */
434 case OID_GEN_TRANSMIT_BUFFER_SPACE
:
435 GenericULONG
= Adapter
->TXCount
* DRIVER_BLOCK_SIZE
;
437 case OID_GEN_RECEIVE_BUFFER_SPACE
:
438 GenericULONG
= Adapter
->RamSize
-
439 (ULONG_PTR
)Adapter
->RamBase
-
440 (Adapter
->TXCount
* DRIVER_BLOCK_SIZE
);
442 case OID_GEN_TRANSMIT_BLOCK_SIZE
:
443 GenericULONG
= DRIVER_BLOCK_SIZE
;
445 case OID_GEN_RECEIVE_BLOCK_SIZE
:
446 GenericULONG
= DRIVER_BLOCK_SIZE
;
448 case OID_GEN_VENDOR_ID
:
449 NdisMoveMemory(&GenericULONG
, &Adapter
->PermanentAddress
, 3);
450 GenericULONG
&= 0xFFFFFF00;
451 GenericULONG
|= 0x01;
453 case OID_GEN_VENDOR_DESCRIPTION
:
454 CopyFrom
= (PVOID
)&DRIVER_VENDOR_DESCRIPTION
;
455 CopySize
= sizeof(DRIVER_VENDOR_DESCRIPTION
);
457 case OID_GEN_VENDOR_DRIVER_VERSION
:
458 GenericUSHORT
= (USHORT
)DRIVER_VENDOR_DRIVER_VERSION
;
459 CopyFrom
= (PVOID
)&GenericUSHORT
;
460 CopySize
= sizeof(USHORT
);
462 case OID_GEN_CURRENT_PACKET_FILTER
:
463 GenericULONG
= Adapter
->PacketFilter
;
465 case OID_GEN_CURRENT_LOOKAHEAD
:
466 GenericULONG
= Adapter
->LookaheadSize
;
468 case OID_GEN_DRIVER_VERSION
:
469 GenericUSHORT
= ((USHORT
)DRIVER_NDIS_MAJOR_VERSION
<< 8) | DRIVER_NDIS_MINOR_VERSION
;
470 CopyFrom
= (PVOID
)&GenericUSHORT
;
471 CopySize
= sizeof(USHORT
);
473 case OID_GEN_MAXIMUM_TOTAL_SIZE
:
474 GenericULONG
= DRIVER_FRAME_SIZE
;
476 case OID_GEN_PROTOCOL_OPTIONS
:
477 NDIS_DbgPrint(MID_TRACE
, ("OID_GEN_PROTOCOL_OPTIONS.\n"));
478 Status
= NDIS_STATUS_NOT_SUPPORTED
;
480 case OID_GEN_MAC_OPTIONS
:
481 GenericULONG
= NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA
|
482 NDIS_MAC_OPTION_RECEIVE_SERIALIZED
|
483 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND
|
484 NDIS_MAC_OPTION_NO_LOOPBACK
;
486 case OID_GEN_MEDIA_CONNECT_STATUS
:
487 GenericULONG
= (ULONG
)NdisMediaStateConnected
;
489 case OID_GEN_MAXIMUM_SEND_PACKETS
:
492 case OID_802_3_PERMANENT_ADDRESS
:
493 CopyFrom
= (PVOID
)&Adapter
->PermanentAddress
;
494 CopySize
= DRIVER_LENGTH_OF_ADDRESS
;
496 case OID_802_3_CURRENT_ADDRESS
:
497 CopyFrom
= (PVOID
)&Adapter
->StationAddress
;
498 CopySize
= DRIVER_LENGTH_OF_ADDRESS
;
500 case OID_802_3_MULTICAST_LIST
:
501 NDIS_DbgPrint(MID_TRACE
, ("OID_802_3_MULTICAST_LIST.\n"));
502 Status
= NDIS_STATUS_NOT_SUPPORTED
;
504 case OID_802_3_MAXIMUM_LIST_SIZE
:
505 GenericULONG
= Adapter
->MaxMulticastListSize
;
507 case OID_802_3_MAC_OPTIONS
:
508 NDIS_DbgPrint(MID_TRACE
, ("OID_802_3_MAC_OPTIONS.\n"));
509 Status
= NDIS_STATUS_NOT_SUPPORTED
;
512 NDIS_DbgPrint(MIN_TRACE
, ("Unknown OID (0x%X).\n", Oid
));
513 Status
= NDIS_STATUS_INVALID_OID
;
517 if (Status
== NDIS_STATUS_SUCCESS
) {
518 if (CopySize
> InformationBufferLength
) {
519 *BytesNeeded
= (CopySize
- InformationBufferLength
);
521 Status
= NDIS_STATUS_INVALID_LENGTH
;
523 NdisMoveMemory(InformationBuffer
, CopyFrom
, CopySize
);
524 *BytesWritten
= CopySize
;
529 NDIS_DbgPrint(MAX_TRACE
, ("Leaving. Status is (0x%X).\n", Status
));
535 NDIS_STATUS STDCALL
MiniportReconfigure(
536 OUT PNDIS_STATUS OpenErrorStatus
,
537 IN NDIS_HANDLE MiniportAdapterContext
,
538 IN NDIS_HANDLE WrapperConfigurationContext
)
540 * FUNCTION: Reconfigures an adapter
542 * OpenErrorStatus = Address of buffer to place additional status information
543 * MiniportAdapterContext = Pointer to adapter context area
544 * WrapperConfigurationContext = Handle used to identify configuration context
546 * Status of operation
548 * Never called by NDIS library
551 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
553 return NDIS_STATUS_FAILURE
;
558 NDIS_STATUS STDCALL
MiniportReset(
559 OUT PBOOLEAN AddressingReset
,
560 IN NDIS_HANDLE MiniportAdapterContext
)
562 * FUNCTION: Resets an adapter
564 * AddressingReset = Address of a buffer to place value indicating
565 * wether NDIS library should call MiniportSetInformation
566 * to restore addressing information
567 * MiniportAdapterContext = Pointer to adapter context area
569 * Status of operation
572 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
574 return NDIS_STATUS_FAILURE
;
578 NDIS_STATUS STDCALL
MiniportSend(
579 IN NDIS_HANDLE MiniportAdapterContext
,
580 IN PNDIS_PACKET Packet
,
583 * FUNCTION: Transmits a packet
585 * MiniportAdapterContext = Pointer to adapter context area
586 * Packet = Pointer to a packet descriptor specifying
587 * the data to be transmitted
588 * Flags = Specifies optional packet flags
590 * Status of operation
593 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
595 NDIS_DbgPrint(MID_TRACE
, ("Queueing packet.\n"));
598 NdisMSendComplete(Adapter
->MiniportAdapterHandle
,
600 NDIS_STATUS_SUCCESS
);
602 /* Queue the packet on the transmit queue */
603 RESERVED(Packet
)->Next
= NULL
;
604 if (Adapter
->TXQueueHead
== NULL
) {
605 Adapter
->TXQueueHead
= Packet
;
607 RESERVED(Adapter
->TXQueueTail
)->Next
= Packet
;
610 Adapter
->TXQueueTail
= Packet
;
612 /* Transmit the packet */
613 NICTransmit(Adapter
);
615 return NDIS_STATUS_PENDING
;
619 NDIS_STATUS STDCALL
MiniportSetInformation(
620 IN NDIS_HANDLE MiniportAdapterContext
,
622 IN PVOID InformationBuffer
,
623 IN ULONG InformationBufferLength
,
624 OUT PULONG BytesRead
,
625 OUT PULONG BytesNeeded
)
627 * FUNCTION: Changes state information in the driver
629 * MiniportAdapterContext = Pointer to adapter context area
630 * Oid = OID code designating set operation
631 * InformationBuffer = Pointer to buffer with state information
632 * InformationBufferLength = Length of InformationBuffer
633 * BytesRead = Address of buffer to place number of bytes read
634 * BytesNeeded = Address of buffer to place number of extra bytes
635 * needed in InformationBuffer for specified OID
637 * Status of operation
641 NDIS_STATUS Status
= NDIS_STATUS_SUCCESS
;
642 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
644 NDIS_DbgPrint(MAX_TRACE
, ("Called. Oid (0x%X).\n", Oid
));
647 case OID_GEN_CURRENT_PACKET_FILTER
:
649 if (InformationBufferLength
< sizeof(ULONG
)) {
651 *BytesNeeded
= sizeof(ULONG
) - InformationBufferLength
;
652 Status
= NDIS_STATUS_INVALID_LENGTH
;
656 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
657 /* Check for properties the driver don't support */
659 (NDIS_PACKET_TYPE_ALL_FUNCTIONAL
|
660 NDIS_PACKET_TYPE_FUNCTIONAL
|
661 NDIS_PACKET_TYPE_GROUP
|
662 NDIS_PACKET_TYPE_MAC_FRAME
|
663 NDIS_PACKET_TYPE_SMT
|
664 NDIS_PACKET_TYPE_SOURCE_ROUTING
)) {
667 Status
= NDIS_STATUS_NOT_SUPPORTED
;
671 Adapter
->PacketFilter
= GenericULONG
;
673 /* FIXME: Set filter on hardware */
676 case OID_GEN_CURRENT_LOOKAHEAD
:
678 if (InformationBufferLength
< sizeof(ULONG
)) {
680 *BytesNeeded
= sizeof(ULONG
) - InformationBufferLength
;
681 Status
= NDIS_STATUS_INVALID_LENGTH
;
685 NdisMoveMemory(&GenericULONG
, InformationBuffer
, sizeof(ULONG
));
686 if (GenericULONG
> DRIVER_MAXIMUM_LOOKAHEAD
)
687 Status
= NDIS_STATUS_INVALID_LENGTH
;
689 Adapter
->LookaheadSize
= GenericULONG
;
691 case OID_802_3_MULTICAST_LIST
:
692 /* Verify length. Must be multiplum of hardware address length */
693 if ((InformationBufferLength
% DRIVER_LENGTH_OF_ADDRESS
) != 0) {
696 Status
= NDIS_STATUS_INVALID_LENGTH
;
700 /* Set new multicast address list */
701 NdisMoveMemory(Adapter
->Addresses
, InformationBuffer
, InformationBufferLength
);
703 /* FIXME: Update hardware */
707 NDIS_DbgPrint(MIN_TRACE
, ("Invalid object ID (0x%X).\n", Oid
));
710 Status
= NDIS_STATUS_INVALID_OID
;
714 if (Status
== NDIS_STATUS_SUCCESS
) {
715 *BytesRead
= InformationBufferLength
;
719 NDIS_DbgPrint(MAX_TRACE
, ("Leaving. Status (0x%X).\n", Status
));
725 NDIS_STATUS STDCALL
MiniportTransferData(
726 OUT PNDIS_PACKET Packet
,
727 OUT PUINT BytesTransferred
,
728 IN NDIS_HANDLE MiniportAdapterContext
,
729 IN NDIS_HANDLE MiniportReceiveContext
,
731 IN UINT BytesToTransfer
)
733 * FUNCTION: Transfers data from a received frame into an NDIS packet
735 * Packet = Address of packet to copy received data into
736 * BytesTransferred = Address of buffer to place number of bytes transmitted
737 * MiniportAdapterContext = Pointer to adapter context area
738 * MiniportReceiveContext = Pointer to receive context area (actually NULL)
739 * ByteOffset = Offset within received packet to begin copying
740 * BytesToTransfer = Number of bytes to copy into packet
742 * Status of operation
745 PNDIS_BUFFER DstBuffer
;
746 UINT BytesCopied
, BytesToCopy
, DstSize
;
751 PNIC_ADAPTER Adapter
= (PNIC_ADAPTER
)MiniportAdapterContext
;
753 NDIS_DbgPrint(MAX_TRACE
, ("Called. Packet (0x%X) ByteOffset (0x%X) BytesToTransfer (%d).\n",
754 Packet
, ByteOffset
, BytesToTransfer
));
756 if (BytesToTransfer
== 0) {
757 *BytesTransferred
= 0;
758 return NDIS_STATUS_SUCCESS
;
761 RecvStart
= Adapter
->PageStart
* DRIVER_BLOCK_SIZE
;
762 RecvStop
= Adapter
->PageStop
* DRIVER_BLOCK_SIZE
;
764 NdisQueryPacket(Packet
, NULL
, NULL
, &DstBuffer
, NULL
);
765 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
767 SrcData
= Adapter
->PacketOffset
+ sizeof(DISCARD_HEADER
) + ByteOffset
;
768 if (ByteOffset
+ sizeof(DISCARD_HEADER
) + BytesToTransfer
>
769 Adapter
->PacketHeader
.PacketLength
)
770 BytesToTransfer
= Adapter
->PacketHeader
.PacketLength
-
771 sizeof(DISCARD_HEADER
) - ByteOffset
;
773 /* Start copying the data */
776 BytesToCopy
= (DstSize
< BytesToTransfer
) ? DstSize
: BytesToTransfer
;
777 if (SrcData
+ BytesToCopy
> RecvStop
)
778 BytesToCopy
= (RecvStop
- SrcData
);
780 NICReadData(Adapter
, DstData
, SrcData
, BytesToCopy
);
782 BytesCopied
+= BytesToCopy
;
783 SrcData
+= BytesToCopy
;
784 DstData
= (PUCHAR
)((ULONG_PTR
) DstData
+ BytesToCopy
);
785 BytesToTransfer
-= BytesToCopy
;
786 if (BytesToTransfer
== 0)
789 DstSize
-= BytesToCopy
;
791 /* No more bytes in destination buffer. Proceed to
792 the next buffer in the destination buffer chain */
793 NdisGetNextBuffer(DstBuffer
, &DstBuffer
);
797 NdisQueryBuffer(DstBuffer
, (PVOID
)&DstData
, &DstSize
);
800 if (SrcData
== RecvStop
)
804 NDIS_DbgPrint(MID_TRACE
, ("Transferred (%d) bytes.\n", BytesToTransfer
));
806 *BytesTransferred
= BytesCopied
;
808 return NDIS_STATUS_SUCCESS
;
817 PDRIVER_OBJECT DriverObject
,
818 PUNICODE_STRING RegistryPath
)
820 * FUNCTION: Main driver entry point
822 * DriverObject = Pointer to a driver object for this driver
823 * RegistryPath = Registry node for configuration parameters
825 * Status of driver initialization
829 NDIS_HANDLE NdisWrapperHandle
;
830 NDIS_MINIPORT_CHARACTERISTICS Miniport
;
832 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
834 NdisZeroMemory(&Miniport
, sizeof(Miniport
));
835 Miniport
.MajorNdisVersion
= DRIVER_NDIS_MAJOR_VERSION
;
836 Miniport
.MinorNdisVersion
= DRIVER_NDIS_MINOR_VERSION
;
837 Miniport
.CheckForHangHandler
= NULL
; //MiniportCheckForHang;
838 Miniport
.DisableInterruptHandler
= MiniportDisableInterrupt
;
839 Miniport
.EnableInterruptHandler
= MiniportEnableInterrupt
;
840 Miniport
.HaltHandler
= MiniportHalt
;
841 Miniport
.HandleInterruptHandler
= MiniportHandleInterrupt
;
842 Miniport
.InitializeHandler
= MiniportInitialize
;
843 Miniport
.ISRHandler
= MiniportISR
;
844 Miniport
.QueryInformationHandler
= MiniportQueryInformation
;
845 Miniport
.ReconfigureHandler
= MiniportReconfigure
;
846 Miniport
.ResetHandler
= MiniportReset
;
847 Miniport
.SendHandler
= MiniportSend
;
848 Miniport
.SetInformationHandler
= MiniportSetInformation
;
849 Miniport
.TransferDataHandler
= MiniportTransferData
;
851 NdisMInitializeWrapper(&NdisWrapperHandle
,
856 DriverInfo
.NdisWrapperHandle
= NdisWrapperHandle
;
857 DriverInfo
.NdisMacHandle
= NULL
;
858 InitializeListHead(&DriverInfo
.AdapterListHead
);
860 Status
= NdisMRegisterMiniport(NdisWrapperHandle
,
862 sizeof(NDIS_MINIPORT_CHARACTERISTICS
));
863 if (Status
!= NDIS_STATUS_SUCCESS
) {
864 NDIS_DbgPrint(MIN_TRACE
, ("NdisMRegisterMiniport() failed with status code (0x%X).\n", Status
));
865 NdisTerminateWrapper(NdisWrapperHandle
, NULL
);
866 return STATUS_UNSUCCESSFUL
;
869 return STATUS_SUCCESS
;
873 /* while i'm here - some basic registry sanity checks */
876 NDIS_CONFIGURATION_PARAMETER ParameterValue
;
878 ParameterValue
.ParameterType
= NdisParameterInteger
;
879 ParameterValue
.ParameterData
.IntegerData
= 0x12345678;
880 NdisInitUnicodeString(&Keyword
, L
"DwordTest");
881 NdisWriteConfiguration(&Status
, ConfigurationHandle
, &Keyword
, &ParameterValue
);
883 if(Status
!= NDIS_STATUS_SUCCESS
)
885 DbgPrint("ne2000!MiniportInitialize: failed to set DwordTest: 0x%x\n", Status
);
889 DbgPrint("ne2000!MiniportInitialize: DwordTest successfully set\n");
891 NdisInitUnicodeString(&Keyword
, L
"StringTest");
892 ParameterValue
.ParameterType
= NdisParameterString
;
893 NdisInitUnicodeString(&ParameterValue
.ParameterData
.StringData
, L
"Testing123");
895 NdisWriteConfiguration(&Status
, ConfigurationHandle
, &Keyword
, &ParameterValue
);
897 if(Status
!= NDIS_STATUS_SUCCESS
)
899 DbgPrint("ne2000!MiniportInitialize: failed to set StringTest: 0x%x\n", Status
);
903 DbgPrint("ne2000!MiniportInitialize: StringTest successfully set\n");
907 /* read back the test values */
908 NDIS_CONFIGURATION_PARAMETER
*ParameterValue
= 0;
910 NdisInitUnicodeString(&Keyword
, L
"DwordTest");
911 NdisReadConfiguration(&Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterInteger
);
913 if(Status
!= NDIS_STATUS_SUCCESS
)
915 DbgPrint("ne2000!MiniportInitialize: failed to read DwordTest: 0x%x\n", Status
);
919 if(ParameterValue
->ParameterData
.IntegerData
!= 0x12345678)
921 DbgPrint("ne2000!MiniportInitialize: DwordTest value is wrong: 0x%x\n",
922 ParameterValue
->ParameterData
.IntegerData
);
926 DbgPrint("ne2000!MiniportInitialize: DwordTest value was correctly read\n");
928 NdisInitUnicodeString(&Keyword
, L
"StringTest");
929 NdisReadConfiguration(&Status
, &ParameterValue
, ConfigurationHandle
, &Keyword
, NdisParameterString
);
931 if(Status
!= NDIS_STATUS_SUCCESS
)
933 DbgPrint("ne2000!MiniportInitialize: failed to read StringTest: 0x%x\n", Status
);
937 if(wcsncmp(ParameterValue
->ParameterData
.StringData
.Buffer
, L
"Testing123",
938 wcslen(L
"Testing123")))
940 DbgPrint("ne2000!MiniportInitialize: StringTest value is wrong: %wZ\n",
941 &ParameterValue
->ParameterData
.StringData
);
945 DbgPrint("ne2000!MiniportInitialize: StringTest value was correctly read\n");