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");