#include "Headers.h"
NTSTATUS DriverEntry ( PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath )
{
NDIS_STATUS status ;
NDIS_HANDLE NdisWrapperHandle ;
NDIS_MINIPORT_CHARACTERISTICS D100char ;
//KdPrint(("DriverEntry Version 2"));
NdisMInitializeWrapper ( &NdisWrapperHandle,
DriverObject,
RegistryPath,
NULL ) ;
NdisZeroMemory ( &D100char, sizeof(D100char)) ;
D100char.MajorNdisVersion = D100_NDIS_MAJOR_VERSION ;
D100char.MinorNdisVersion = D100_NDIS_MINOR_VERSION ;
D100char.CheckForHangHandler = D100CheckForHang;
D100char.DisableInterruptHandler = D100DisableInterrupt;
D100char.EnableInterruptHandler = D100EnableInterrupt;
D100char.HaltHandler = D100Halt;
D100char.HandleInterruptHandler = D100HandleInterrupt;
D100char.InitializeHandler = D100Initialize ;
D100char.ISRHandler = D100Isr;
D100char.QueryInformationHandler = D100QueryInformation;
D100char.ResetHandler = D100Reset;
D100char.SetInformationHandler = D100SetInformation;
D100char.SendHandler = D100Send;
// D100char.SendPacketHandler = NULL;//D100MultipleSend;
D100char.ReturnPacketHandler = D100ReturnPacket;
status = NdisMRegisterMiniport( NdisWrapperHandle,
&D100char,
sizeof(NDIS_MINIPORT_CHARACTERISTICS)) ;
if ( status == NDIS_STATUS_SUCCESS )
{
//KdPrint(("Exiting DriverEntry successfully"));
return STATUS_SUCCESS ;
}
return status;
}
NDIS_STATUS D100Initialize ( PNDIS_STATUS OpenErrorStatus,
PUINT SelectedMediumIndex,
PNDIS_MEDIUM MediumArray,
UINT MediumArraySize,
NDIS_HANDLE MiniportAdapterHandle,
NDIS_HANDLE WrapperConfigurationContext )
{
USHORT i ;
NDIS_STATUS Status ;
PD100_ADAPTER Adapter ;
NDIS_HANDLE ConfigHandle;
NDIS_INTERFACE_TYPE IfType ;
//KdPrint(("D100Initialize"));
for ( i = 0; i < MediumArraySize ; i++ )
{
if( MediumArray[i] == NdisMedium802_3)
break;
}
if (i == MediumArraySize )
return NDIS_STATUS_UNSUPPORTED_MEDIA ;
*SelectedMediumIndex = i ;
Status = D100_ALLOC_MEM ( &Adapter ,
sizeof( D100_ADAPTER ));
if (Status != NDIS_STATUS_SUCCESS )
return Status;
NdisZeroMemory (Adapter,sizeof( D100_ADAPTER));
Adapter->D100AdapterHandle = MiniportAdapterHandle ;
Adapter->InterruptMode = NdisInterruptLevelSensitive;
/**returns a handle for a registry key
in which an NDIS NIC driver's configuration
parameters are stored.***/
NdisOpenConfiguration(&Status,&ConfigHandle,
WrapperConfigurationContext);
if(Status!=NDIS_STATUS_SUCCESS)
return NDIS_STATUS_FAILURE;
NdisCloseConfiguration(ConfigHandle);
IfType = NdisInterfacePci ;
/**informs the NDIS library about significant
features of the caller's NIC or virtual NIC
during initialization***/
NdisMSetAttributesEx ( Adapter->D100AdapterHandle,
(NDIS_HANDLE) Adapter,
0,//check for hang Time in seconds
( ULONG ) NDIS_ATTRIBUTE_DESERIALIZE | NDIS_ATTRIBUTE_BUS_MASTER ,
IfType );
if ( ClaimAdapter( Adapter ) != NDIS_STATUS_SUCCESS )
{
//KdPrint(("****D100 failure***"));
return NDIS_STATUS_FAILURE ;
}
/******Setting Shared Adapter Memory****/
Status = SetupSharedAdapterMemory(Adapter);
// Check the status returned from SetupSharedAdapterMemory
if (Status != NDIS_STATUS_SUCCESS)
{
//KdPrint(("Shared Memory Allocation failed (Status = 0x%x)\n", Status));
FreeAdapter(Adapter);
return NDIS_STATUS_FAILURE;
}
ResetPhy(Adapter);
AutoNegotiate( Adapter );
/** Disabling The Interrupt Mask Register***/
D100DisableInterrupt(Adapter);
Status = SetupTransQ ( Adapter );
if (Status != NDIS_STATUS_SUCCESS)
{
FreeAdapter(Adapter);
return NDIS_STATUS_FAILURE;
}
// Setup receive queue
Status = SetupRecvQ ( Adapter );
if (Status != NDIS_STATUS_SUCCESS)
{
Adapter->RecvUnCached=0;
DeleteSharedMemoryAdapter(Adapter);
return NDIS_STATUS_FAILURE;
}
// Register interrupt with the NDIS wrapper.
NdisAllocateSpinLock (&Adapter->Lock);
Status = NdisMRegisterInterrupt(&Adapter->Interrupt,
Adapter->D100AdapterHandle,
Adapter->AiVector, // bus-relative vector number used by the NIC.
Adapter->AiInterrupt, // bus-relative DIRQL for the interrupt
TRUE, // MiniportISR function should be called each time the NIC interrupts
TRUE, // Other devices on the I/O bus can use this interrupt line
Adapter->InterruptMode); // using LevelSensitive Inerrupts
if (Status != NDIS_STATUS_SUCCESS)
{
//KdPrint(("Failed to register Interrupt wth NDIS\n"));
return NDIS_STATUS_FAILURE;
}
//KdPrint(("Successfully registered Interrupt with NDIS\n"));
//InitializePower(Adapter);
// register a shutdown handler...
/* NdisMRegisterAdapterShutdownHandler(Adapter->D100AdapterHandle,
(PVOID) Adapter,
(ADAPTER_SHUTDOWN_HANDLER) D100ShutdownHandler);
*/
//Adapter->LinkIsActive = NdisMediaStateConnected;
Adapter->CurrentPowerState = NdisDeviceStateD0;
Adapter->NextPowerState = NdisDeviceStateD0;
D100EnableInterrupt(Adapter);
/***Deallocatting all allocated memory and
DeRegistering the Interrupt******/
//DeleteAllAllocatedMemory(Adapter);
//KdPrint(("*** EXITING D100init ***"));
return NDIS_STATUS_SUCCESS;
}
NDIS_STATUS ClaimAdapter( PD100_ADAPTER Adapter )
{
USHORT NumPciBoardsFound;
USHORT VendorID = D100_VENDOR_ID;
USHORT DeviceID = D100_DEVICE_ID;
PCI_CARDS_FOUND_STRUC PciCardsFound;
UINT i=0;
//KdPrint(("********** I AM IN ClaimAdapter*******"));
NumPciBoardsFound=FindPciDevice50Scan(Adapter,VendorID,
DeviceID,&PciCardsFound);
Adapter->AiSlot = PciCardsFound.PciSlotInfo[i].SlotNumber;
Adapter->AiInterrupt = PciCardsFound.PciSlotInfo[i].Irq;
Adapter->AiVector=PciCardsFound.PciSlotInfo[i].Irq;
Adapter->CSRPhysicalAddress = PciCardsFound.PciSlotInfo[i].MemPhysAddress;
Adapter->AiBaseIo = (USHORT)PciCardsFound.PciSlotInfo[i].BaseIo;
//KdPrint(("VECTOR: %X DIRQL :%X",Adapter->AiVector,Adapter->AiInterrupt));
//KdPrint((" **Exiting ClaimAdapter Successfully**"));
return NDIS_STATUS_SUCCESS;
}
USHORT FindPciDevice50Scan(IN PD100_ADAPTER Adapter,
IN USHORT VendorID,IN USHORT DeviceID,
OUT PPCI_CARDS_FOUND_STRUC pPciCardsFound)
{
UINT i;
USHORT found = 0;
NDIS_STATUS Status;
ULONG Slot=0;
PNDIS_RESOURCE_LIST AssignedResources;
//KdPrint(("***** I AM IN FindPciDevice50Scan ****"));
Status = NdisMPciAssignResources(
Adapter->D100AdapterHandle,
Slot,
&AssignedResources);
for (i=0;i < AssignedResources->Count;i++ )
{
switch (AssignedResources->PartialDescriptors[i].Type)
{
case CmResourceTypePort:
if (AssignedResources->PartialDescriptors[i].Flags & CM_RESOURCE_PORT_IO)
{
pPciCardsFound->PciSlotInfo[found].BaseIo =
(ULONG) ((AssignedResources)->PartialDescriptors[i].u.Port.Start.u.LowPart);
//KdPrint(("Base IO : %x ", pPciCardsFound->PciSlotInfo[found].BaseIo));
}
break;
case CmResourceTypeInterrupt:
pPciCardsFound->PciSlotInfo[found].Irq =
(UCHAR) ((AssignedResources)->PartialDescriptors[i].u.Interrupt.Level);
break;
case CmResourceTypeMemory:
pPciCardsFound->PciSlotInfo[found].MemPhysAddress =
(ULONG) ((AssignedResources)->PartialDescriptors[i].u.Memory.Start.u.LowPart);
break;
}
}
return found;
}
NDIS_STATUS SetupSharedAdapterMemory(IN PD100_ADAPTER Adapter)
{
UINT i;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
NDIS_PHYSICAL_ADDRESS NdisPhysicalCsrAddress;
//KdPrint(("I AM IN SetupSharedAdapterMemory"));
Adapter->NumMapRegisters = NO_OF_MAP_REGISTERS;
Adapter->MaxPhysicalMappings = MAXIMUM_ETHERNET_PACKET_SIZE;
//KdPrint(("%x..",Adapter->D100AdapterHandle));
// Get a virtual address for our CSR structure. So that we can access
// the CSR's registers via memory mapping.
NdisSetPhysicalAddressLow (NdisPhysicalCsrAddress, (ULONG)Adapter->CSRPhysicalAddress);
NdisSetPhysicalAddressHigh (NdisPhysicalCsrAddress, 0);
//KdPrint(("Adapter->CSRAddress before mapping :%X\n",Adapter->CSRAddress));
//KdPrint(("NdisPhysicalCsrAddress: %X\n",NdisPhysicalCsrAddress));
Status = NdisMMapIoSpace ( OUT (PVOID *) &(Adapter->CSRAddress),
Adapter->D100AdapterHandle,
NdisPhysicalCsrAddress,
256);
// If we couldn't get a virtual memory address for our CSR, then error out.
if (Status != NDIS_STATUS_SUCCESS) //|| (Adapter->CSRAddress == NULL))
{
//KdPrint(("Could not memory map the CSR phys = %x\n", Adapter->CSRPhysicalAddress));
//KdPrint((" Status : %x",Status));
return Status;
}
//KdPrint(("D100 CSR phys = %x, D100 CSR virt = %x\n", Adapter->CSRPhysicalAddress,Adapter->CSRAddress));
//KdPrint(("*******MAC ADDRESS*********"));
for(i=0;i<ETH_LENGTH_OF_ADDRESS;i++)
{
NdisReadRegisterUchar((PUCHAR)(Adapter->CSRAddress+MAC+i),&Adapter->AiNodeAddress[i]);
//KdPrint(("\t%X ",Adapter->AiNodeAddress[i]));
Adapter->AiPermanentNodeAddress[i]=Adapter->AiNodeAddress[i];
}
//KdPrint(("Allocating %x map registers\n", Adapter->NumMapRegisters));
Status = NdisMAllocateMapRegisters(Adapter->D100AdapterHandle,
0,
TRUE,
Adapter->NumMapRegisters,
Adapter->MaxPhysicalMappings);
if (Status != NDIS_STATUS_SUCCESS)
{
//KdPrint(("NdisMAllocateMapRegister Failed - %x\n", Status));
Adapter->NumMapRegisters = 0;
return Status;
}
return NDIS_STATUS_SUCCESS;
}
VOID ResetPhy(IN PD100_ADAPTER Adapter)
{
UCHAR rdata;
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG),&rdata ) ;
//KdPrint(("Command Reg = %X\n",rdata));
NdisWriteRegisterUchar( (PUCHAR)(Adapter->CSRAddress+ CMND_REG), 0x10 ) ;
NdisStallExecution(2000);
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG),&rdata ) ;
//KdPrint(("Command Reg After Reset = %X\n\n",rdata));
return;
}
NDIS_STATUS SetupTransQ(IN PD100_ADAPTER Adapter)
{
USHORT i;
ULONG DATA;
ULONG rdata ;
UCHAR commandReg ;
ULONG transConfReg ;
ULONG SIZE_OF_DESC = 0x0 ;
Adapter->TransUnCachedSize = MAX_TRANS_BUFFER_SIZE;
//KdPrint(("Begin SetupTransQ \n"));
/**** Allocate SharedMemory for Transmit Buffer Descriptors
allocates and maps a host memory range so it is simultaneously
accessible from both the system and a busmaster DMA NIC.****/
for(i=0;i<NUM_OF_TRANS_DESC;i++)
{
NdisMAllocateSharedMemory( Adapter->D100AdapterHandle,
Adapter->TransUnCachedSize,
FALSE,
( PVOID ) &Adapter->TransUnCached[i],
&Adapter->TransUnCachedPhys[i]);
//KdPrint(("VIRTUAL ADDRESS OF TRANSMIT BUFFER[%d] = %X\n",i, Adapter->TransUnCached[i]));
//KdPrint(("PHYSICAL ADDRESS OF TRANSMIT BUFFER[%d] = %X\n\n",i, Adapter->TransUnCachedPhys[i]));
}
// Set Transmit Enable bit
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ),&commandReg ) ;
//KdPrint(("Command Reg Before Transmit Enable = %X\n",commandReg ));
commandReg |= TRANS_ENABLE ;
NdisWriteRegisterUchar( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), commandReg ) ;
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), &commandReg ) ;
//KdPrint(("Command Reg After Transmit Enable = %X\n\n",commandReg ));
// Set Transmit Configuration register
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + TRANS_CONFIG_REG ),&transConfReg ) ;
//KdPrint(("Transmit Configuration Reg Before Enable = %X\n",transConfReg ));
transConfReg &=0;
transConfReg |= TCR_ENABLE;
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + TRANS_CONFIG_REG ), transConfReg ) ;
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + TRANS_CONFIG_REG ), &transConfReg ) ;
//KdPrint(("Transmit Configuration Reg After Enable = %X\n\n",transConfReg ));
// Set the Transmit Start Address registers
for ( i = 0 ; i < NUM_OF_TRANS_DESC ; i++ )
{
// update TSAD
DATA=Adapter->TransUnCachedPhys[i].LowPart ;
// DATA+=3;
// DATA&=~3;
NdisWriteRegisterUlong(
(PULONG)(Adapter->CSRAddress + TSAD0+ SIZE_OF_DESC ),
DATA) ;
// read the updated TSAD
NdisReadRegisterUlong (
(PULONG)(Adapter->CSRAddress + TSAD0+ SIZE_OF_DESC),
&rdata) ;
//KdPrint(("Virtual Start Address of TSAD%d :%X \n\n",i,rdata));
SIZE_OF_DESC += 4 ;
}
Adapter->NoPackets=0;
Adapter->ReadDesc=0;
Adapter->WriteDesc=0;
//KdPrint(("End SetupTransQ \n\n"));
return NDIS_STATUS_SUCCESS;
}
NDIS_STATUS SetupRecvQ(IN PD100_ADAPTER Adapter)
{
ULONG rdata ;
UCHAR commandReg ;
ULONG recvConfReg ;
NDIS_STATUS Status;
UINT NumberOfDescriptors=1;
Adapter->RecvUnCachedSize = MAX_RECV_BUFF_SIZE ;
//KdPrint(("Begin SetupRecvQ \n"));
// Allocate SharedMemory for Receive Buffer.
// NdisMAllocateSharedMemory allocates and maps a host memory range so it
// is simultaneously accessible from both the system and a busmaster DMA NIC.
NdisMAllocateSharedMemory( Adapter->D100AdapterHandle,
Adapter->RecvUnCachedSize,
FALSE,
( PVOID ) &Adapter->RecvUnCached,
&Adapter->RecvUnCachedPhys);
//KdPrint(("VIRTUAL ADDRESS OF RECEIVE BUFFER = %X\n",Adapter->RecvUnCached));
//KdPrint(("PHYSICAL ADDRESS OF RECEIVE BUFFER = %X\n\n",Adapter->RecvUnCachedPhys));
// Set Receive Enable bit
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ),&commandReg ) ;
//KdPrint(("Command Reg Before Receive Enable = %X\n",commandReg));
commandReg |= RECV_ENABLE ;
NdisWriteRegisterUchar( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), commandReg ) ;
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), &commandReg ) ;
// Read the status of the Command Register
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG),&commandReg ) ;
//KdPrint(("Command Reg After Receive Enable = %X\n\n",commandReg));
// Set Receive Configuration register
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + RECV_CONFIG_REG ),&recvConfReg ) ;
//KdPrint(("Receive Configuration Reg Before Enable = %X\n",recvConfReg ));
recvConfReg |= RCR_ENABLE ;
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + RECV_CONFIG_REG ), recvConfReg ) ;
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + RECV_CONFIG_REG ), &recvConfReg ) ;
//KdPrint(("Receive Configuration Reg After Enable = %X\n\n",recvConfReg ));
// Set Receive Buffer start register
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + RBSTART ), Adapter->RecvUnCachedPhys.LowPart ) ;
// read the updated RBSTART
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + RBSTART ), &rdata ) ;
//KdPrint(("Receive Buffer Start Address Regsister %X \n\n",rdata));
//****GETTING PACKET POOL HANDLE****************/
NdisAllocatePacketPool( &Status,
&Adapter->RxPacketPoolHandle,
NumberOfDescriptors,
16);
if(Status!=NDIS_STATUS_SUCCESS )
{
KdPrint(("~~~~Ndis Allocate Packet Pool Failed~~~~"));
}
//******GETTING BUFFER POOL HANDLE****************/
NdisAllocateBufferPool( &Status,
&Adapter->RxBufferPoolHandle,
NumberOfDescriptors);
if(Status!=NDIS_STATUS_SUCCESS )
{
KdPrint(("~~~~Ndis Allocate Buffer Pool Failed~~~~"));
}
//KdPrint(("End SetupRecvQ \n\n"));
return NDIS_STATUS_SUCCESS;
}
VOID D100DisableInterrupt(IN PD100_ADAPTER Adapter)
{
USHORT intrmskReg;
NdisReadRegisterUshort ( (PUSHORT)(Adapter->CSRAddress + IMR ),&intrmskReg ) ;
//KdPrint(("Interrupt Mask Reg Before Disable = %X\n",intrmskReg ));
// Disable the interrupts
NdisWriteRegisterUshort( (PUSHORT)(Adapter->CSRAddress + IMR ),0x0000 ) ;
// check the status of IMR
NdisReadRegisterUshort ( (PUSHORT)(Adapter->CSRAddress + IMR ), &intrmskReg ) ;
//KdPrint(("Interrupt Mask Reg After Disable = %X\n\n",intrmskReg ));
//KdPrint(("End D100DisableInterrupt"));
}
VOID D100EnableInterrupt(IN PD100_ADAPTER Adapter)
{
USHORT IMRREG;
NdisWriteRegisterUshort((PUSHORT)(Adapter->CSRAddress+IMR),0x002F);
NdisReadRegisterUshort((PUSHORT)(Adapter->CSRAddress+IMR),&IMRREG);
//KdPrint(("IMR REG AFTER ENABLE : %X",IMRREG));
}
VOID AutoNegotiate(IN PD100_ADAPTER Adapter )
{
USHORT bmcrdata;
USHORT BMSRDATA;
UINT i=0;
//KdPrint(("Begin AutoNegotiate\n"));
//seting 93C56Command Register
NdisWriteRegisterUchar((PUCHAR)(Adapter->CSRAddress + CMREG93C56 ),EEM) ;
NdisReadRegisterUshort ( (PUSHORT) (Adapter->CSRAddress + BASIC_MODE_CTRL_REG ),&bmcrdata ) ;
//KdPrint(("BMCR BEFORE RESET :: %X",bmcrdata));
/**RESETTING BMCR **/
NdisWriteRegisterUshort((PUSHORT) (Adapter->CSRAddress + BASIC_MODE_CTRL_REG ),BMCR_RESET) ;
NdisStallExecution(10000);
NdisReadRegisterUshort ( (PUSHORT) (Adapter->CSRAddress + BASIC_MODE_CTRL_REG ),&bmcrdata ) ;
//KdPrint(("BMCR AFTER RESET :: %X",bmcrdata));
//KdPrint(("BMCR BEFORE AUOTONEG::%X",bmcrdata));
NdisReadRegisterUshort( (PUSHORT) (Adapter->CSRAddress +0x0064 ),&BMSRDATA);
//KdPrint(("BMSR BEFORE AUTO NEGO:: %X",BMSRDATA));
bmcrdata |= BMCR_ENABLE;
NdisWriteRegisterUshort ( (PUSHORT) (Adapter->CSRAddress + BASIC_MODE_CTRL_REG ),bmcrdata ) ;
NdisReadRegisterUshort ( (PUSHORT) (Adapter->CSRAddress + BASIC_MODE_CTRL_REG ),&bmcrdata ) ;
//KdPrint(("BMCR AFTER AUTONEGOTIATE %X\n",bmcrdata));
do
{
NdisStallExecution(1000000);
NdisReadRegisterUshort( (PUSHORT) (Adapter->CSRAddress +0x0064 ),&BMSRDATA);
//KdPrint(("BMSR :: %X",BMSRDATA));
BMSRDATA &= 0x0020;
if(BMSRDATA== 0x0020)
{
KdPrint(("**AUTONEGOTIATION COMPLETED SUCCESSFULLY**"));
break;
}
i++;
}while(i<5);
//if(BMSRDATA!= 0x0020)
//KdPrint(("** AutoNegotiation Timeout/Failed**"));
//KdPrint(("End AutoNegotiate\n"));
}
VOID DeleteAllAllocatedMemory(PD100_ADAPTER Adapter)
{
//KdPrint(( "I am in DeleteAll "));
//KdPrint(("***************"));
DeleteSharedMemoryAdapter(Adapter);
if(Adapter->NumMapRegisters)
{
NdisMFreeMapRegisters(Adapter->D100AdapterHandle);
//KdPrint((" After Free Map Register the interrupt"));
}
if(Adapter->CSRAddress)
NdisMUnmapIoSpace((Adapter->D100AdapterHandle),
(PVOID)(Adapter->CSRAddress),256);
NdisFreeSpinLock (&Adapter->Lock);
FreeAdapter(Adapter);
//KdPrint((" Deallocation is finished"));
}
VOID DeleteSharedMemoryAdapter(IN PD100_ADAPTER Adapter)
{
UINT i=0;
//KdPrint(("****I AM IN DELETE SHARED MEMORY ADAPTER****"));
if(Adapter->TransUnCached[0])
{
//KdPrint((" DEALLOCATING TRANSMIT BUFFER\n"));
for(i=0;i<NUM_OF_TRANS_DESC;i++)
{
NdisMFreeSharedMemory( Adapter->D100AdapterHandle,
Adapter->TransUnCachedSize,
FALSE,
( PVOID ) Adapter->TransUnCached[i],
Adapter->TransUnCachedPhys[i]);
}
}
if(Adapter->RxPacketPoolHandle)
NdisFreePacketPool(Adapter->RxPacketPoolHandle);
if(Adapter->RxBufferPoolHandle)
NdisFreeBufferPool(Adapter->RxBufferPoolHandle);
if(Adapter->RecvUnCached)
{
//KdPrint(("DEALLOCATING RECV BUFFER"));
NdisMFreeSharedMemory( Adapter->D100AdapterHandle,
Adapter->RecvUnCachedSize,
FALSE,
( PVOID ) Adapter->RecvUnCached,
Adapter->RecvUnCachedPhys );
}
//KdPrint(("END OF DELETE SHARED MEMORY ADAPTER"));
}
VOID FreeAdapter(IN PD100_ADAPTER Adapter)
{
//KdPrint((" ***** FREE ADAPTER ****"));
D100_FREE_MEM (Adapter,sizeof( D100_ADAPTER ));
}
//-----------------------------------------------------------------------------
// Procedure: D100QueryInformation
//
// Description: D100QueryInformation handles a query operation for a single
// OID. Basically we return information about the current state of
// the OID in question.
//-----------------------------------------------------------------------------
NDIS_STATUS
D100QueryInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesWritten,
OUT PULONG BytesNeeded
)
{
// order is important here because the OIDs should be in order
// of increasing value
static
NDIS_OID D100GlobalSupportedOids[] =
{
OID_GEN_SUPPORTED_LIST,
OID_GEN_HARDWARE_STATUS,
OID_GEN_MEDIA_SUPPORTED,
OID_GEN_MEDIA_IN_USE,
OID_GEN_MAXIMUM_LOOKAHEAD,
OID_GEN_MAXIMUM_FRAME_SIZE,
OID_GEN_LINK_SPEED,
OID_GEN_TRANSMIT_BUFFER_SPACE,
OID_GEN_RECEIVE_BUFFER_SPACE,
OID_GEN_TRANSMIT_BLOCK_SIZE,
OID_GEN_RECEIVE_BLOCK_SIZE,
OID_GEN_VENDOR_ID,
OID_GEN_VENDOR_DESCRIPTION,
OID_GEN_CURRENT_PACKET_FILTER,
OID_GEN_CURRENT_LOOKAHEAD,
OID_GEN_DRIVER_VERSION,
OID_GEN_MAXIMUM_TOTAL_SIZE,
OID_GEN_PROTOCOL_OPTIONS,
OID_GEN_MAC_OPTIONS,
OID_GEN_MEDIA_CONNECT_STATUS,
OID_GEN_MAXIMUM_SEND_PACKETS,
OID_GEN_SUPPORTED_GUIDS,
OID_GEN_XMIT_OK,
OID_GEN_RCV_OK,
OID_GEN_XMIT_ERROR,
OID_GEN_RCV_ERROR,
OID_GEN_RCV_NO_BUFFER,
OID_GEN_RCV_CRC_ERROR,
OID_GEN_TRANSMIT_QUEUE_LENGTH,
OID_802_3_PERMANENT_ADDRESS,
OID_802_3_CURRENT_ADDRESS,
OID_802_3_MULTICAST_LIST,
OID_802_3_MAXIMUM_LIST_SIZE,
// for ndis 4 packet priority
//OID_802_3_MAC_OPTIONS,
/* OID_802_3_RCV_ERROR_ALIGNMENT,
OID_802_3_XMIT_ONE_COLLISION,
OID_802_3_XMIT_MORE_COLLISIONS,
OID_802_3_XMIT_DEFERRED,
OID_802_3_XMIT_MAX_COLLISIONS,
OID_802_3_RCV_OVERRUN,
OID_802_3_XMIT_UNDERRUN,
OID_802_3_XMIT_HEARTBEAT_FAILURE,
OID_802_3_XMIT_TIMES_CRS_LOST,
OID_802_3_XMIT_LATE_COLLISIONS,
*/ // tcp/ip checksum offload
// OID_TCP_TASK_OFFLOAD
// powermanagement
OID_PNP_CAPABILITIES,
OID_PNP_SET_POWER,
OID_PNP_QUERY_POWER,
OID_PNP_ADD_WAKE_UP_PATTERN,
OID_PNP_REMOVE_WAKE_UP_PATTERN,
OID_PNP_ENABLE_WAKE_UP
};
// String describing our adapter
char VendorDescriptor[] = VENDORDESCRIPTOR;
PD100_ADAPTER Adapter;
UCHAR VendorId[4];
NDIS_MEDIUM Medium = NdisMedium802_3;
NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady;
UINT GenericUlong;
USHORT GenericUShort;
UCHAR GenericArray[6];
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
NDIS_PNP_CAPABILITIES Power_Management_Capabilities;
// Common variables for pointing to result of query
PVOID MoveSource = (PVOID) (&GenericUlong);
ULONG MoveBytes = sizeof(GenericUlong);
UCHAR read;
Adapter = (PD100_ADAPTER)(MiniportAdapterContext);
// Initialize the result
*BytesWritten = 0;
*BytesNeeded = 0;
// Switch on request type
switch (Oid)
{
case OID_GEN_MAC_OPTIONS:
//KdPrint(("QUERY:OID_GEN_MAC_OPTIONS \n"));
GenericUlong = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
NDIS_MAC_OPTION_NO_LOOPBACK
);
break;
case OID_GEN_SUPPORTED_LIST:
//KdPrint(("QUERY:OID_GEN_SUPPORTED_LIST\n"));
MoveSource = (PVOID) (D100GlobalSupportedOids);
MoveBytes = sizeof(D100GlobalSupportedOids);
break;
case OID_GEN_HARDWARE_STATUS:
//KdPrint(("QUERY:OID_GEN_HARDWARE_STATUS \n"));
MoveSource = (PVOID)(&HardwareStatus);
MoveBytes = sizeof(NDIS_HARDWARE_STATUS);
break;
case OID_GEN_MEDIA_SUPPORTED:
case OID_GEN_MEDIA_IN_USE:
//KdPrint(("QUERY: OID_GEN_MEDIA_SUPPORTED\n"));
MoveSource = (PVOID) (&Medium);
MoveBytes = sizeof(NDIS_MEDIUM);
break;
case OID_GEN_MAXIMUM_LOOKAHEAD:
case OID_GEN_CURRENT_LOOKAHEAD:
case OID_GEN_MAXIMUM_FRAME_SIZE:
//KdPrint(("QUERY: OID_GEN_MAXIMUM_LOOKAHEAD\n"));
GenericUlong = MAXIMUM_ETHERNET_PACKET_SIZE - ENET_HEADER_SIZE;
break;
case OID_GEN_MAXIMUM_TOTAL_SIZE:
case OID_GEN_TRANSMIT_BLOCK_SIZE:
case OID_GEN_RECEIVE_BLOCK_SIZE:
//KdPrint(("QUERY: OID_GEN_MAXIMUM_TOTAL_SIZE\n"));
GenericUlong = (ULONG) MAXIMUM_ETHERNET_PACKET_SIZE;
break;
case OID_GEN_LINK_SPEED:
//KdPrint(("QUERY:OID_GEN_LINK_SPEED \n"));
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + MSR),&read ) ;
if(read & 8)
Adapter->AiLineSpeedCur = 10; //10MHz
else
Adapter->AiLineSpeedCur = 100; //100MHz
GenericUlong = (((ULONG) Adapter->AiLineSpeedCur) * 10000);
//KdPrint(("SPEED : %d Mbps",Adapter->AiLineSpeedCur));
break;
case OID_GEN_TRANSMIT_BUFFER_SPACE:
//KdPrint(("QUERY TRANSMIT BUFFER SPACE "));
GenericUlong = (ULONG) MAXIMUM_ETHERNET_PACKET_SIZE *NUM_OF_TRANS_DESC;
break;
case OID_GEN_RECEIVE_BUFFER_SPACE:
//KdPrint(("RCV BUFFER SPACE"));
GenericUlong = (ULONG) MAXIMUM_ETHERNET_PACKET_SIZE;
break;
case OID_GEN_VENDOR_ID:
//KdPrint(("QUERY:OID_GEN_VENDOR_ID \n"));
NdisMoveMemory(VendorId, Adapter->AiNodeAddress, 3);
VendorId[3] = 0x0;
MoveSource = (PVOID) VendorId;
MoveBytes = sizeof(VendorId);
break;
case OID_GEN_VENDOR_DESCRIPTION:
//KdPrint(("QUERY:OID_GEN_VENDOR_DESCRIPTION \n"));
MoveSource = (PVOID) VendorDescriptor;
MoveBytes = sizeof(VendorDescriptor);
break;
case OID_GEN_DRIVER_VERSION:
//KdPrint(("QUERY:OID_GEN_DRIVER_VERSION \n"));
GenericUShort = (USHORT) D100_DRIVER_VERSION;
MoveSource = (PVOID)(&GenericUShort);
MoveBytes = sizeof(GenericUShort);
break;
case OID_802_3_PERMANENT_ADDRESS:
//KdPrint(("QUERY: OID_802_3_PERMANENT_ADDRESS\n"));
ETH_COPY_NETWORK_ADDRESS(
(PCHAR) GenericArray,
Adapter->AiPermanentNodeAddress);
MoveSource = (PVOID) (GenericArray);
MoveBytes = ETH_LENGTH_OF_ADDRESS;
break;
case OID_802_3_CURRENT_ADDRESS:
//KdPrint(("QUERY:OID_802_3_CURRENT_ADDRESS \n"));
ETH_COPY_NETWORK_ADDRESS(
GenericArray,
Adapter->AiNodeAddress);
MoveSource = (PVOID) (GenericArray);
MoveBytes = ETH_LENGTH_OF_ADDRESS;
break;
case OID_802_3_MAXIMUM_LIST_SIZE:
//KdPrint(("QUERY:OID_802_3_MAXIMUM_LIST_SIZE \n"));
GenericUlong = (ULONG) MAX_MULTICAST_ADDRESSES;
break;
case OID_GEN_MAXIMUM_SEND_PACKETS:
//KdPrint(("QUERY:OID_GEN_MAXIMUM_SEND_PACKETS \n"));
GenericUlong = 1;
break;
case OID_GEN_MEDIA_CONNECT_STATUS:
//KdPrint(("QUERY:OID_GEN_MEDIA_CONNECT_STATUS \n"));
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress +MSR),&read ) ;
if(read & 4)
{
Adapter->LinkIsActive = NdisMediaStateDisconnected;
//KdPrint(("~~~NETWORK CABLE STATUS UNPLUGGED~~~"));
}
else
{
Adapter->LinkIsActive = NdisMediaStateConnected;
//KdPrint(("^^^^^NETWORK CABLE STATUS CONNECTED^^^^^"));
}
GenericUlong = (ULONG) Adapter->LinkIsActive;
break;
case OID_GEN_XMIT_OK :
//KdPrint(("QUERY:OID_GEN_XMIT_OK \n"));
GenericUlong = Adapter->GoodTransmits;
break;
case OID_GEN_RCV_OK :
//KdPrint(("QUERY:OID_GEN_RCV_OK \n"));
GenericUlong = Adapter->GoodReceives ;
break;
case OID_GEN_XMIT_ERROR :
//KdPrint(("QUERY:OID_GEN_XMIT_ERROR \n"));
GenericUlong = Adapter->Trans_Error ;
break;
case OID_GEN_RCV_ERROR :
//KdPrint(("QUERY:OID_GEN_RCV_ERROR \n"));
GenericUlong = Adapter->Rcv_Error ;
break;
case OID_GEN_RCV_NO_BUFFER :
//KdPrint(("OID_GEN_RCV_NO_BUFFER \n"));
GenericUlong = Adapter->Rcv_No_Buffer ;
break;
case OID_PNP_CAPABILITIES:
//KdPrint(("QUERY:PNP CAPABILITIES"));
// since we are stubbing power management, return only the
// D0 power state indicating that the lowest power state we
// support is D0 (full power)
Power_Management_Capabilities.Flags=NDIS_DEVICE_WAKE_UP_ENABLE ;
Power_Management_Capabilities.WakeUpCapabilities.MinLinkChangeWakeUp = NdisDeviceStateD1;
Power_Management_Capabilities.WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateD1;
Power_Management_Capabilities.WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateD1;
MoveSource = (PVOID) &Power_Management_Capabilities;
MoveBytes = sizeof(NDIS_PNP_CAPABILITIES);
Status = NDIS_STATUS_SUCCESS;
break;
case OID_PNP_QUERY_POWER:
Status = NDIS_STATUS_SUCCESS; //stub
break;
default:
//KdPrint(("QUERY:Default"));
Status = NDIS_STATUS_NOT_SUPPORTED;
break;
}
if (Status == NDIS_STATUS_SUCCESS)
{
if (MoveBytes > InformationBufferLength)
{
// Not enough room in InformationBuffer. Punt
*BytesNeeded = MoveBytes;
Status = NDIS_STATUS_BUFFER_TOO_SHORT;
}
else
{
// Copy result into InformationBuffer
*BytesWritten = MoveBytes;
if (MoveBytes > 0)
NdisMoveMemory(InformationBuffer, MoveSource, MoveBytes);
}
}
return (Status);
} // end of D100QueryInformation
NDIS_STATUS
D100SetInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesRead,
OUT PULONG BytesNeeded
)
{
NDIS_STATUS Status;
ULONG PacketFilter;
PD100_ADAPTER Adapter;
UCHAR commandReg;
ULONG transConfReg;
ULONG recvConfReg;
USHORT i;
ULONG DATA;
ULONG SIZE_OF_DESC = 0x0 ;
Adapter = (PD100_ADAPTER)(MiniportAdapterContext);
*BytesRead = 0;
*BytesNeeded = 0;
Status=NDIS_STATUS_SUCCESS;
switch (Oid)
{
case OID_802_3_MULTICAST_LIST:
//KdPrint(("SETINFORMATION : OID_802_3_MULTICAST_LIST\n"));
if (InformationBufferLength % ETH_LENGTH_OF_ADDRESS != 0)
return (NDIS_STATUS_INVALID_LENGTH);
NdisMoveMemory(Adapter->PrivateMulticastBuffer,
InformationBuffer,
InformationBufferLength);
// Save the number of MC address in our adapter object
Adapter->NumberOfMcAddresses =
(InformationBufferLength / ETH_LENGTH_OF_ADDRESS);
//Status = D100ChangeMCAddresses(
// Adapter,
//InformationBufferLength /
//ETH_LENGTH_OF_ADDRESS);
Status = NDIS_STATUS_SUCCESS;
*BytesRead = InformationBufferLength;
break;
case OID_GEN_CURRENT_PACKET_FILTER:
//KdPrint(("SETINFORMATION : OID_GEN_CURRENT_PACKET_FILTER\n"));
if (InformationBufferLength != 4)
return (NDIS_STATUS_INVALID_LENGTH);
// Now call the filter package to set the packet filter.
NdisMoveMemory((PVOID)&PacketFilter, InformationBuffer, sizeof(ULONG));
// Verify bits, if any bits are set that we don't support, leave
if (PacketFilter &
~(NDIS_PACKET_TYPE_DIRECTED |
NDIS_PACKET_TYPE_MULTICAST |
NDIS_PACKET_TYPE_BROADCAST |
NDIS_PACKET_TYPE_PROMISCUOUS |
NDIS_PACKET_TYPE_ALL_MULTICAST))
{
KdPrint(("********************"));
Status = NDIS_STATUS_NOT_SUPPORTED;
*BytesRead = 4;
break;
}
// If this is a miniport driver, the submit the packet filter change
// to our hardware,by directly calling D100SetPacketFilter.
// Status = D100SetPacketFilter(
// Adapter,
// PacketFilter);
Status = NDIS_STATUS_SUCCESS;
*BytesRead = InformationBufferLength;
break;
case OID_GEN_CURRENT_LOOKAHEAD:
//KdPrint(("SETINFORMATION : case OID_GEN_CURRENT_LOOKAHEAD\n"));
// Verify the Length
if (InformationBufferLength != 4)
return (NDIS_STATUS_INVALID_LENGTH);
*BytesRead = 4;
Status = NDIS_STATUS_SUCCESS;
break;
case OID_PNP_SET_POWER:
KdPrint(("**** POWER MANAGEMENT ****"));
KdPrint(("*** I AM IN SET POWER ***"));
Adapter->IsrReg=0;
Adapter->WriteDesc=0;
Adapter->ReadDesc=0;
Adapter->NoPackets=0;
ResetPhy(Adapter);
AutoNegotiate(Adapter);
D100DisableInterrupt(Adapter);
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ),&commandReg ) ;
commandReg |= TRANS_ENABLE ;
NdisWriteRegisterUchar( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), commandReg ) ;
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + TRANS_CONFIG_REG ),&transConfReg ) ;
transConfReg &=0;
transConfReg |= TCR_ENABLE;
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + TRANS_CONFIG_REG ), transConfReg ) ;
for ( i = 0 ; i < NUM_OF_TRANS_DESC ; i++ )
{
DATA=Adapter->TransUnCachedPhys[i].LowPart ;
NdisWriteRegisterUlong(
(PULONG)(Adapter->CSRAddress + TSAD0+ SIZE_OF_DESC ),
DATA) ;
SIZE_OF_DESC += 4 ;
}
/****************/
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ),&commandReg ) ;
commandReg |= RECV_ENABLE ;
NdisWriteRegisterUchar( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), commandReg ) ;
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + RECV_CONFIG_REG ),&recvConfReg ) ;
recvConfReg |= RCR_ENABLE ;
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + RECV_CONFIG_REG ), recvConfReg ) ;
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + RBSTART ), Adapter->RecvUnCachedPhys.LowPart ) ;
NdisWriteRegisterUshort((PUSHORT)(Adapter->CSRAddress+CAPR),0xfff0);
D100EnableInterrupt(Adapter);
*BytesRead = InformationBufferLength;
Status = NDIS_STATUS_SUCCESS;
//BytesRead = 0; //stub
//Status = NDIS_STATUS_NOT_SUPPORTED; //stub
break;
/*
case OID_PNP_ADD_WAKE_UP_PATTERN:
// call a function that would program the adapter's wake
// up pattern, return success
*BytesRead = InformationBufferLength;
Status = NDIS_STATUS_SUCCESS;
//*BytesRead = 0; //stub
//Status = NDIS_STATUS_NOT_SUPPORTED; //stub
break;
case OID_PNP_REMOVE_WAKE_UP_PATTERN:
// call a function that would remove the adapter's wake
// up pattern, return success
*BytesRead = InformationBufferLength;
//*BytesRead = 0;
Status = NDIS_STATUS_SUCCESS;//stub
//Status = NDIS_STATUS_NOT_SUPPORTED; //stub
break;
*/
case OID_PNP_ENABLE_WAKE_UP:
// call a function that would enable wake up on the adapter
// return success
KdPrint(("**** POWER MANAGEMENT ****"));
KdPrint(("*** I AM IN ENABLE WAKE UP ***"));
D100DisableInterrupt(Adapter);
while(Adapter->NoPackets)
{
Adapter->GoodTransmits++;
//KdPrint(("Adapter->Packet:%X",Adapter->Packet));
//KdPrint(("Total Packets Transmitted : %d\n", Adapter->ReadDesc));
//KdPrint(("TxREAD_DESC : %d",Adapter->ReadDesc));
NdisMSendComplete(Adapter->D100AdapterHandle,
Adapter->Packet[Adapter->ReadDesc],
NDIS_STATUS_SUCCESS);
Adapter->ReadDesc=(Adapter->ReadDesc+1) % NUM_OF_TRANS_DESC;
//KdPrint(("PACKETS COMPLETED : %d ",Adapter->NoPackets));
Adapter->NoPackets--;
//KdPrint(("______TRANSMISSION IS SUCCESS_____"));
}
NdisMEthIndicateReceiveComplete(Adapter->D100AdapterHandle);
InitializePower(Adapter);
*BytesRead = InformationBufferLength;
Status = NDIS_STATUS_SUCCESS;
// *BytesRead = 0;//stub
// Status = NDIS_STATUS_NOT_SUPPORTED; //stub
break;
default:
//KdPrint(("Default SetOID...\n"));
Status = NDIS_STATUS_INVALID_OID;
break;
} // end of switch construct
return Status;
}
//-----------------------------------------------------------------------------
// Procedure: D100Isr (miniport)
//
// Description: This is the interrupt service routine. It will check to see
// if there are any interrupts pending, and if there are, it will
// disable board interrupts and schedule a HandleInterrupt
// callback.
//-----------------------------------------------------------------------------
VOID D100Isr(
OUT PBOOLEAN InterruptRecognized,
OUT PBOOLEAN QueueMiniportHandleInterrupt,
IN NDIS_HANDLE MiniportAdapterContext
)
{
PD100_ADAPTER Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
//KdPrint(("****** I AM IN ISR******"));
NdisReadRegisterUshort((PUSHORT) (Adapter->CSRAddress +ISR),&Adapter->IsrReg);
NdisWriteRegisterUshort((PUSHORT)(Adapter->CSRAddress+ISR),Adapter->IsrReg);
//KdPrint(("ISR = %4X(Hex)", Adapter->IsrReg));
// We want to process the interrupt if the output from our interrupt line
// is high, and our interrupt is not masked. If our interrupt line
// is already masked, then we must be currently processing interrupts.
if (Adapter->IsrReg)
{
// DEBUGSTR(("Our INT -- slot %x\n", Adapter->AiSlot));
//KdPrint((" **** I AM IN ISR INSIDE IF LOOP*****"));
*InterruptRecognized = TRUE;
*QueueMiniportHandleInterrupt = TRUE;
D100DisableInterrupt(Adapter);
}
else
{
*InterruptRecognized = FALSE;
*QueueMiniportHandleInterrupt = FALSE;
}
return;
}
//-----------------------------------------------------------------------------
// Procedure: D100HandleInterrupt
//
// Description: This routine is queued by the ISR when some interrupt
// processing needs to be done. It's main job is to call the
// interrupt processing code (process receives, cleanup completed
// transmits, etc). It will only be called with the adapter's
// interrupts masked. This is the DPC for this driver.
//-----------------------------------------------------------------------------
VOID D100HandleInterrupt(
IN NDIS_HANDLE MiniportAdapterContext
)
{
// Context is actually our adapter
PD100_ADAPTER Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
USHORT LNK;
USHORT rdata;
ULONG TSR_STATUS;
rdata = Adapter->IsrReg;
//NdisAllocateSpinLock (&Adapter->Lock);
while(rdata)
{
if(rdata & BIT1)
{
//KdPrint(("Receive Successful\n"));
ProcessRXInterrupt(Adapter);
}
if(rdata & BIT2) //RER IS SET
KdPrint(("Receive Unsuccessful\n"));
if(rdata & BIT3)
{
//KdPrint(("********TOK********"));
while(Adapter->NoPackets)
{
NdisReadRegisterUlong((PULONG)(Adapter->CSRAddress+TSD0+ Adapter->ReadDesc*4),&TSR_STATUS);
//if(TSR_STATUS & 0x0000A000)
{
Adapter->GoodTransmits++;
//KdPrint(("Adapter->Packet:%X",Adapter->Packet));
//KdPrint(("Total Packets Transmitted : %d\n", Adapter->ReadDesc));
//KdPrint(("TxREAD_DESC : %d",Adapter->ReadDesc));
NdisMSendComplete(Adapter->D100AdapterHandle,
Adapter->Packet[Adapter->ReadDesc],
NDIS_STATUS_SUCCESS);
Adapter->ReadDesc=(Adapter->ReadDesc+1) % NUM_OF_TRANS_DESC;
//KdPrint(("PACKETS COMPLETED : %d ",Adapter->NoPackets));
Adapter->NoPackets--;
KdPrint(("______TRANSMISSION IS SUCCESS_____"));
}
}
}
if(rdata & BIT4)
{
//KdPrint(("Transmission Error"));
while(Adapter->NoPackets)
{
Adapter->Trans_Error++;
NdisMSendComplete(
Adapter->D100AdapterHandle,
Adapter->Packet[Adapter->ReadDesc],
NDIS_STATUS_FAILURE);
Adapter->NoPackets--;
}
}
if(rdata & BIT5)
KdPrint(("Receive buffer overflow\n"));
if(rdata & BIT6)
{
//KdPrint(("LINK STATUS CHANGED"));
NdisReadRegisterUshort((PUSHORT) (Adapter->CSRAddress +BMSR),&LNK);
if (LNK & BIT3)
{
//KdPrint(("***VALID LINK ESTABLISHED***"));
NdisMIndicateStatus(Adapter->D100AdapterHandle,
NDIS_STATUS_MEDIA_CONNECT,
(PVOID)0,
0);
}
else
{
//KdPrint(("*** LINK FAILURE **"));
NdisMIndicateStatus(Adapter->D100AdapterHandle,
NDIS_STATUS_MEDIA_DISCONNECT,
(PVOID)0,
0);
}
}
if(rdata & BIT7)
KdPrint(("receive fifo overflow\n"));
NdisReadRegisterUshort((PUSHORT)(Adapter->CSRAddress+ISR),&Adapter->IsrReg);
NdisWriteRegisterUshort((PUSHORT)(Adapter->CSRAddress+ISR),Adapter->IsrReg);
rdata=Adapter->IsrReg;
//KdPrint(("isr:=%x\n",rdata));
}
//NdisReleaseSpinLock(&Adapter->Lock);
D100EnableInterrupt(Adapter);
//KdPrint(("we r exiting InterruptHandle\n"));
}
/*********************************************************************************
-------------------------TRANSMISSION---------------------------------------------
**********************************************************************************/
NDIS_STATUS D100Send(IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet,
IN UINT Flags )
{
PD100_ADAPTER Adapter;
PNDIS_BUFFER FirstBuffer;
UINT TotalPacketLength;
UINT PhysicalBufferCount;
UINT BufferCount;
ULONG TSR_STATUS;
UINT BytesCopied;
Adapter = (PD100_ADAPTER) MiniportAdapterContext;
Adapter->Packet[Adapter->WriteDesc] = Packet;
//KdPrint(("_________________________________________\n"));
//KdPrint(("------------I AM IN TRANSMIT-------------"));
//KdPrint(("_________________________________________"));
//****CHECK IF ANY TRANSMIT DESCRIPTOR IS AVAILABLE
if (Adapter->NoPackets >= NUM_OF_TRANS_DESC)
{
//KdPrint(("****** TSAD UNAVAILABLE *****"));
NDIS_SET_PACKET_STATUS(Packet,NDIS_STATUS_RESOURCES );
return NDIS_STATUS_RESOURCES ;
}
else
{
NdisQueryPacket(Packet, //* Returns
&PhysicalBufferCount , //* Information
&BufferCount, //* About a Given
&FirstBuffer, //* Packet
&TotalPacketLength);
if(TotalPacketLength < 64)//** MIN. PACKET LENGTH
TotalPacketLength=64; //** SHOULD BE 64
if(TotalPacketLength > MAXIMUM_ETHERNET_PACKET_SIZE)
{
NDIS_SET_PACKET_STATUS(Packet,NDIS_STATUS_FAILURE );
return NDIS_STATUS_FAILURE;
}
//KdPrint(("BUFFER COUNT :%X",BufferCount));
//KdPrint(("PACKET SIZE :%X",TotalPacketLength));
//KdPrint(("FIRST BUFFER :%X",FirstBuffer));
//*** THIS ROUTINE COPIES A PACKET TO THE TRANSMIT BUFFER
CopyPacketToTransmitBuffer(TotalPacketLength,
(PCHAR)Adapter->TransUnCached[Adapter->WriteDesc],
FirstBuffer,
&BytesCopied );
Adapter->NoPackets++;
//KdPrint(("PACKET NO:%d",Adapter->NoPackets));
NdisReadRegisterUlong((PULONG)(Adapter->CSRAddress+TSD0+Adapter->WriteDesc * 4),&TSR_STATUS);
//KdPrint(("TSR BEFORE UPDATION : %X",TSR_STATUS));
TSR_STATUS &= 0xFFFFE000; //*** CLEARS THE PACKET DESC FIELD
TSR_STATUS |= TotalPacketLength;//*** SETS PACKET LENGTH DESC
TSR_STATUS |= 0x00200000; //***EARLY THRESHOLD
TSR_STATUS &= 0xFFFFDFFF; //***CLEARS OWN BIT
//*** UPDATING THE TRASMIT STATUS REGISTER
NdisWriteRegisterUlong((PULONG)(Adapter->CSRAddress+TSD0 +Adapter->WriteDesc* 4),TSR_STATUS);
Adapter->WriteDesc=(Adapter->WriteDesc+1)% NUM_OF_TRANS_DESC;
//KdPrint(("TxWRITE_DESC :%d",Adapter->WriteDesc));
NdisReadRegisterUlong((PULONG)(Adapter->CSRAddress+TSD0+ Adapter->WriteDesc*4),&TSR_STATUS);
//KdPrint(("TSR AFTER UPDATATION : %X",TSR_STATUS));
}
NDIS_SET_PACKET_STATUS(Packet,NDIS_STATUS_PENDING);
return NDIS_STATUS_PENDING;
}
//-----------------------------------------------------------------------------
// Procedure: D100CheckForHang
//
// Description: This routine should check to see if the adapter is "hung", and
// fix it if it is. Right now this routine does not check for a
// hang, because the adapter should never "timeout". In the
// future, this is where the code to check for a timeout would go,
// if there were bugs in the chipset that could cause transmit
// "timeouts".
//-----------------------------------------------------------------------------
BOOLEAN D100CheckForHang(NDIS_HANDLE MiniportAdapterContext)
{
PD100_ADAPTER Adapter;
UCHAR read;
//KdPrint(("********In CheckForHang************\n"));
Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
// this is the implementation of the NDIS 4 feature for detecting
// link status change. It effectively checks every two seconds
// for link.
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress +MSR),&read ) ;
if(read & 4)
{
Adapter->LinkIsActive = NdisMediaStateDisconnected;
NdisMIndicateStatus(Adapter->D100AdapterHandle,
NDIS_STATUS_MEDIA_DISCONNECT,
(PVOID)0,
0);
//KdPrint(("~~~NETWORK CABLE STATUS UNPLUGGED~~~"));
}
else
{
Adapter->LinkIsActive = NdisMediaStateConnected;
NdisMIndicateStatus(Adapter->D100AdapterHandle,
NDIS_STATUS_MEDIA_CONNECT,
(PVOID)0,
0);
//KdPrint(("^^^^^NETWORK CABLE STATUS CONNECTED^^^^^"));
}
// have to indicate status complete every time you indicate status
NdisMIndicateStatusComplete(Adapter->D100AdapterHandle);
// return false to indicate that the adapter is not hung, and that
// D100Reset does NOT need to be called by the wrapper
return(FALSE) ;
}
/// ==================================================================
/// -------------------RESET-----------------------------------------
///INSTRUCTS THE MINIPORT TO ISSUE A HARDWARE RESET TO THE
// NETWORK ADAPTER. THE DRIVER ALSO RESETS ITS SOFTWARE STATE.
// THIS FUNCTION ALSO RESETS THE TRANSMIT QUEUES.
//---------------------------------------------------------------
///==================================================================
NDIS_STATUS
D100Reset(PBOOLEAN AddressingReset,
NDIS_HANDLE MiniportAdapterContext)
{
PD100_ADAPTER Adapter;
/* UCHAR commandReg;
ULONG transConfReg;
ULONG recvConfReg;
*/
//KdPrint(("*** InReset ***"));
Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
///***NDIS LIBRARY SHOULD CALL MINIPORTSETINFORMATION
///***TO RESTORE ADDRESSING INFORMATION TO THE CURRENT VALUES.
*AddressingReset = TRUE;
D100DisableInterrupt(Adapter);////***DISABLES THE INTERRUPT
Adapter->IsrReg=0;
///**** WE WILL COMPLETE ALL SENDS THAT WE HAVE LEFT RIGHT NOW.
while(Adapter->NoPackets > 0)
{
NdisMSendComplete(Adapter->D100AdapterHandle,
Adapter->Packet[Adapter->ReadDesc],
NDIS_STATUS_SUCCESS);
Adapter->ReadDesc=(Adapter->ReadDesc+1) % NUM_OF_TRANS_DESC;
Adapter->NoPackets--;
}
ResetPhy(Adapter); //// RESETTING COMMAND REGISTER
AutoNegotiate(Adapter); //// RE INITIALIZE AUTONEGOTIATION
DeleteSharedMemoryAdapter(Adapter);
SetupRecvQ(Adapter); //// RE-INITIALIZE RECEIVE QUEUES
SetupTransQ(Adapter); //// RE-INITIALIZE TRANSMIT QUEUES
/* NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ),&commandReg ) ;
//KdPrint(("Command Reg Before Transmit Enable = %X\n",commandReg ));
commandReg |= TRANS_ENABLE ;
NdisWriteRegisterUchar( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), commandReg ) ;
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), &commandReg ) ;
//KdPrint(("Command Reg After Transmit Enable = %X\n\n",commandReg ));
// Set Transmit Configuration register
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + TRANS_CONFIG_REG ),&transConfReg ) ;
//KdPrint(("Transmit Configuration Reg Before Enable = %X\n",transConfReg ));
transConfReg &=0;
transConfReg |= TCR_ENABLE;
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + TRANS_CONFIG_REG ), transConfReg ) ;
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + TRANS_CONFIG_REG ), &transConfReg ) ;
//KdPrint(("Transmit Configuration Reg After Enable = %X\n\n",transConfReg ));
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ),&commandReg ) ;
//KdPrint(("Command Reg Before Receive Enable = %X\n",commandReg));
commandReg |= RECV_ENABLE ;
NdisWriteRegisterUchar( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), commandReg ) ;
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), &commandReg ) ;
// Read the status of the Command Register
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG),&commandReg ) ;
//KdPrint(("Command Reg After Receive Enable = %X\n\n",commandReg));
// Set Receive Configuration register
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + RECV_CONFIG_REG ),&recvConfReg ) ;
//KdPrint(("Receive Configuration Reg Before Enable = %X\n",recvConfReg ));
recvConfReg |= RCR_ENABLE ;
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + RECV_CONFIG_REG ), recvConfReg ) ;
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + RECV_CONFIG_REG ), &recvConfReg ) ;
//KdPrint(("Receive Configuration Reg After Enable = %X\n\n",recvConfReg ));
// Set Receive Buffer start register
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + RBSTART ), Adapter->RecvUnCachedPhys.LowPart ) ;
Adapter->WriteDesc=0;
Adapter->ReadDesc=0;
Adapter->NoPackets=0;
*/
///****NOTIFIES NDIS THAT AN ETHERNET RECEIVE PACKET,
//***IDENTIFIED IN A PRECEDING CALL TO NdisMEthIndicateReceive,
//**HAS BEEN FULLY TRANSFERRED BY THE NIC SO THAT NDIS CAN NOTIFY
//**THE APPROPRIATE BOUND PROTOCOLS.
NdisMEthIndicateReceiveComplete(Adapter->D100AdapterHandle);
//***NdisMResetComplete RETURNS THE FINAL STATUS OF A RESET REQUEST
//**FOR WITH THE NIC DRIVER PREVIOUSLY RETURNED NDIS_STATUS_PENDING.
NdisMResetComplete(Adapter->D100AdapterHandle,
(NDIS_STATUS) NDIS_STATUS_SUCCESS,
FALSE);
return NDIS_STATUS_SUCCESS;
}
///=============================================================================
//-----------COPIES ONE PACKET TO THE TRANSMIT BUFFER-------------------
//======================================================================
VOID CopyPacketToTransmitBuffer( UINT BytesToCopy,
PCHAR DestBuffer,
PNDIS_BUFFER FirstBuffer,
PUINT BytesCopied )
{PNDIS_BUFFER CurrentBuffer;
PVOID VirtualAddress;
UINT CurrentLength;
UINT AmountToMove;
*BytesCopied = 0;
if (!BytesToCopy)
return;
CurrentBuffer = FirstBuffer;
NdisQueryBuffer(
CurrentBuffer,
&VirtualAddress,
&CurrentLength);
while (BytesToCopy)
{
while (!CurrentLength)
{
NdisGetNextBuffer(
CurrentBuffer,
&CurrentBuffer);
// If we've reached the end of the packet. We return with what
// we've done so far (which must be shorter than requested).
if (!CurrentBuffer)
return;
NdisQueryBuffer(
CurrentBuffer,
&VirtualAddress,
&CurrentLength);
}
// Compute how much data to move from this fragment
if (CurrentLength > BytesToCopy)
AmountToMove = BytesToCopy;
else
AmountToMove = CurrentLength;
// Copy the data.
NdisMoveMemory(
DestBuffer,
VirtualAddress,
AmountToMove);
// Update destination pointer
DestBuffer = (PCHAR) DestBuffer + AmountToMove;
// Update counters
*BytesCopied += AmountToMove;
BytesToCopy -= AmountToMove;
CurrentLength = 0;
}
}
//==========================================================================
//--------------Process Receive Interrupt-----------------------------------
//===========================================================================
VOID ProcessRXInterrupt(IN PD100_ADAPTER Adapter)
{
NDIS_STATUS Status;
//USHORT CAPR_REG;
//USHORT CBR_REG;
USHORT ReadPtr;
UCHAR COMMANDREG;
NdisReadRegisterUchar((PUCHAR)(Adapter->CSRAddress+CMND_REG),&COMMANDREG);
while(!(COMMANDREG & BUFE))
{
NdisReadRegisterUshort((PUSHORT)(Adapter->CSRAddress+CBR),&ReadPtr);
//KdPrint((" CBR(Write Pointer) := %x(HEX)\n",ReadPtr));
//***** THE FIRST TWO BYTES CONTAINING THE STATUS OF THE PACKET
ReadPtr = *((PUSHORT)(Adapter->RecvUnCached + Adapter->RHead));
//KdPrint(("PACKET STATUS :=%x\n",ReadPtr));
if(ReadPtr & (Rx_FAE|Rx_CRC|Rx_LONG|Rx_RUNT|Rx_ISE))
{
//KdPrint(("******* RECEIVE PACKET ERROR *****"));
return;
}
//***** IF GOOD PACKET IS RECEIVED
if (ReadPtr & Rx_ROK)
{
//KdPrint(("GOOD PACKET IS RECEIVED "));
Adapter->GoodReceives++;
NdisAllocatePacket( &Status,
&Adapter->RxPacketDesc,
Adapter->RxPacketPoolHandle );
if(Status != NDIS_STATUS_SUCCESS)
{
KdPrint(("**** PACKET ALLOCATION FAILED ****"));
return;
}
//****** THE NEXT TWO BYTES CONTAINING THE LENGTH OF THE PACKET
Adapter->PacketLength=*((PUSHORT)(Adapter->RecvUnCached+Adapter->RHead+2));
NdisAllocateBuffer(
&Status,
&Adapter->RxBufferDesc,
Adapter->RxBufferPoolHandle,
(PVOID)(Adapter->RecvUnCached+Adapter->RHead+4),//STARTING VIRTUAL ADDRESS
Adapter->PacketLength-4 ); // EXCLUDING CRC
if(Status != NDIS_STATUS_SUCCESS)
{
KdPrint(("**** BUFFER ALLOCATION FAILED ****"));
return;
}
Adapter->RHead=((Adapter->PacketLength+Adapter->RHead+4+3) &(~(0x03))) % (64*1024);
//4:FOR HEADER LENGTH(PKTLENGTH INCLUDE 4 BYTES CRC)
//3:FOR DWORD ALIGNMENT
NdisReadRegisterUshort((PUSHORT)(Adapter->CSRAddress+CAPR),
&ReadPtr);
//KdPrint(("CAPR BEFORE UPDATE :%X",ReadPtr));
ReadPtr=(Adapter->RHead-0x10);///** 4 AVOID OVERFLOW;
NdisWriteRegisterUshort((PUSHORT)(Adapter->CSRAddress+CAPR),
ReadPtr);
NdisReadRegisterUshort((PUSHORT)(Adapter->CSRAddress+CAPR),
&ReadPtr);
//KdPrint(("CAPR AFTER UPDATE :%X",ReadPtr));
NdisReadRegisterUshort((PUSHORT)(Adapter->CSRAddress+CBR),
&ReadPtr);
//KdPrint(("CBR :%X",ReadPtr));
///****SETS THE HEADER SIZE VALUE IN THE OOB DATA BLOCK ASSOCIATED WITH A
//***GIVEN PACKET DESCRIPTOR FOR A SUBSEQUENT RECEIVE INDICATION
NDIS_SET_PACKET_HEADER_SIZE(Adapter->RxPacketDesc,ENET_HEADER_SIZE);
//**** SETS THE PACKET STATUS IN THE OOB DATA BLOCK
NDIS_SET_PACKET_STATUS(Adapter->RxPacketDesc,NDIS_STATUS_SUCCESS);
//NDIS_SET_PACKET_STATUS(Adapter->RxPacketDesc,NDIS_STATUS_RESOURCES);
///**** LINKS THE GIVEN BUFFER DESCRIPTOR AT THE TAIL
//*** OF THE CHAIN FOR THE GIVEN PACKET.
NdisChainBufferAtFront(Adapter->RxPacketDesc,Adapter->RxBufferDesc);
///**** NOTIFIES NDIS THAT RECEIVED PACKET IS AVAILABLE
///**** TO BE FORWARDED TO THE APPROPRIATE BOUND PROTOCOL DRIVER(S).
NdisMIndicateReceivePacket(Adapter->D100AdapterHandle,
&Adapter->RxPacketDesc , 1 );
//NdisStallExecution(100);
NdisReadRegisterUchar((PUCHAR)(Adapter->CSRAddress+CMND_REG),&COMMANDREG);
}
}
return ;
}
//---------------------------------------------------------------------------
// D100ReturnPacket
// DESCRIPTION: This function attempts to return to the receive free list the
// packet passed to us by NDIS
//----------------------------------------------------------------------------
VOID D100ReturnPacket(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet
)
{
PD100_ADAPTER Adapter = (PD100_ADAPTER) MiniportAdapterContext;
//KdPrint(("\n\n*****************D100ReturnPacket****************\n"));
/*if(Adapter->Status==NDIS_STATUS_PENDING)
{
NDIS_SET_PACKET_STATUS(Adapter->RxPacketDesc,NDIS_STATUS_SUCCESS);
NdisMIndicateReceivePacket(Adapter->D100AdapterHandle,
&Adapter->RxPacketDesc , 1 );
NdisUnchainBufferAtFront(Adapter->RxPacketDesc,&Adapter->RxBufferDesc);
}*/
NdisFreeBuffer(Adapter->RxBufferDesc);
NdisFreePacket(Adapter->RxPacketDesc);
return;
}
//-----------------------------------------------------------------------------
// Procedure: D100Halt
//
// Description: Removes an adapter instance that was previously initialized.
// To "halt" or "remove" an adapter, we disable its interrupt,
// abort its receive unit (otherwise it would continue to DMA in
// data), and release all of the resources (memory, i/o space,
// etc.) that the adapter instance was using.
// This routine is only called when the adapter is "stopped"
// or unloaded with a "net stop e100b". To see what is called
// at machine shutdown see D100ShutdownHandler.
//-----------------------------------------------------------------------------
VOID D100Halt(NDIS_HANDLE MiniportAdapterContext)
{
PD100_ADAPTER Adapter;
//KdPrint(("****D100Halt***"));
Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
// Disable the device's interrupt line.
D100DisableInterrupt(Adapter);
while(Adapter->NoPackets > 0)
{
NdisMSendComplete(Adapter->D100AdapterHandle,
Adapter->Packet[Adapter->ReadDesc],
NDIS_STATUS_SUCCESS);
Adapter->ReadDesc=(Adapter->ReadDesc+1) % NUM_OF_TRANS_DESC;
Adapter->NoPackets--;
}
NdisMDeregisterInterrupt(&Adapter->Interrupt);
//KdPrint((" After DeRegistering the interrupt"));
ResetPhy(Adapter);
DeleteAllAllocatedMemory(Adapter);
}
//-----------------------------------------------------------------------------
// Procedure: D100ShutdownHandler
//
// Description: Removes an adapter instance that was previously initialized.
// To Shutdown simply Disable interrupts and Stop the receive unit.
// Since the system is shutting down there is no need to release
// resources (memory, i/o space, etc.) that the adapter instance
// was using.
//
// Arguments:
// MiniportAdapterContext - pointer to the adapter object data area.
//
// Returns: (none)
//-----------------------------------------------------------------------------
/*VOID
D100ShutdownHandler(NDIS_HANDLE MiniportAdapterContext)
{
PD100_ADAPTER Adapter;
//KdPrint(("D100ShutdownHandler"));
Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
// Disable the device's interrupt line.
D100DisableInterrupt(Adapter);
//D100StallExecution(30);
// Reset the PHY chip. We do this so that after a warm boot, the PHY will
// be in a known state, with auto-negotiation enabled.
ResetPhy(Adapter);
}*/
VOID D100StallExecution( IN UINT MsecDelay)
{
// Delay in 100 usec increments
MsecDelay *= 10;
while (MsecDelay)
{
NdisStallExecution(100);
MsecDelay--;
}
}
VOID InitializePower(IN PD100_ADAPTER Adapter)
{
UCHAR Read;
//UNLOCK....
#ifdef __PM__
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+CMREG93C56,&Read);
Read|=0xc0;
NdisWriteRegisterUchar((PUCHAR)Adapter->CSRAddress+CMREG93C56,Read);
//PME Config1
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG1,&Read);
//KdPrint(("%%%% CNFG1=%x\n",Read));
Read|=0x31;
NdisWriteRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG1,Read);
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG1,&Read);
//KdPrint(("%%%% CNFG1=%x\n",Read));
//Disable Magic Packet Config 3
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG3,&Read);
KdPrint(("%%%% CNFG3=%x\n",Read));
#ifdef __LINK_WAKE_UP__ //Not Proper
Read &=0xdf;//Linkup
Read |=0x10;
#endif
/*#ifdef __MAGIC_WAKE_UP__
Read &=0xef;
Read |=0x20;
#endif*/
NdisWriteRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG3,Read);
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG3,&Read);
KdPrint(("%%%% CNFG3=%x\n",Read));
//LANWAKE vs PMEB Packet Config 4
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG4,&Read);
//KdPrint(("%%%% CNFG4=%x\n",Read));
Read&=0x9F;
NdisWriteRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG4,Read);
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG4,&Read);
//KdPrint(("%%%% CNFG4=%x\n",Read));
//LANWAKE... Config5
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG5,&Read);
//KdPrint(("%%%% CNFG5=%x\n",Read));
Read|=0x42;
Read&=0xFB;
NdisWriteRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG5,Read);
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+0xd8,&Read);
//KdPrint(("%%%% CNFG5=%x\n",Read));
#endif
}
NDIS_STATUS
D100ChangeMCAddresses(
IN PD100_ADAPTER Adapter,
IN UINT AddressCount
)
{
// Holds the change that should be returned to the filtering package.
PUCHAR McAddress;
UINT i, j;
NDIS_STATUS Status;
KdPrint(("CHANGE MC ADDRESS"));
// Setup the command block for the multicast command.
for (i = 0;(i < AddressCount) && (i < MAX_MULTICAST_ADDRESSES);i++)
{
McAddress = &Adapter->NonTxCmdBlock->Multicast.McAddress[i*ETHERNET_ADDRESS_LENGTH];
for (j = 0; j < ETH_LENGTH_OF_ADDRESS; j++)
*(McAddress++) = Adapter->PrivateMulticastBuffer[i][j];
}
Adapter -> NonTxCmdBlock ->Multicast.McCount =
(USHORT) (AddressCount * ETH_LENGTH_OF_ADDRESS);
Adapter->NonTxCmdBlockHdr->CbStatus = 0;
Adapter->NonTxCmdBlockHdr->CbCommand = 3;
Status = (NDIS_STATUS_SUCCESS);
KdPrint(("***END***"));
return(Status);
}
NTSTATUS DriverEntry ( PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath )
{
NDIS_STATUS status ;
NDIS_HANDLE NdisWrapperHandle ;
NDIS_MINIPORT_CHARACTERISTICS D100char ;
//KdPrint(("DriverEntry Version 2"));
NdisMInitializeWrapper ( &NdisWrapperHandle,
DriverObject,
RegistryPath,
NULL ) ;
NdisZeroMemory ( &D100char, sizeof(D100char)) ;
D100char.MajorNdisVersion = D100_NDIS_MAJOR_VERSION ;
D100char.MinorNdisVersion = D100_NDIS_MINOR_VERSION ;
D100char.CheckForHangHandler = D100CheckForHang;
D100char.DisableInterruptHandler = D100DisableInterrupt;
D100char.EnableInterruptHandler = D100EnableInterrupt;
D100char.HaltHandler = D100Halt;
D100char.HandleInterruptHandler = D100HandleInterrupt;
D100char.InitializeHandler = D100Initialize ;
D100char.ISRHandler = D100Isr;
D100char.QueryInformationHandler = D100QueryInformation;
D100char.ResetHandler = D100Reset;
D100char.SetInformationHandler = D100SetInformation;
D100char.SendHandler = D100Send;
// D100char.SendPacketHandler = NULL;//D100MultipleSend;
D100char.ReturnPacketHandler = D100ReturnPacket;
status = NdisMRegisterMiniport( NdisWrapperHandle,
&D100char,
sizeof(NDIS_MINIPORT_CHARACTERISTICS)) ;
if ( status == NDIS_STATUS_SUCCESS )
{
//KdPrint(("Exiting DriverEntry successfully"));
return STATUS_SUCCESS ;
}
return status;
}
NDIS_STATUS D100Initialize ( PNDIS_STATUS OpenErrorStatus,
PUINT SelectedMediumIndex,
PNDIS_MEDIUM MediumArray,
UINT MediumArraySize,
NDIS_HANDLE MiniportAdapterHandle,
NDIS_HANDLE WrapperConfigurationContext )
{
USHORT i ;
NDIS_STATUS Status ;
PD100_ADAPTER Adapter ;
NDIS_HANDLE ConfigHandle;
NDIS_INTERFACE_TYPE IfType ;
//KdPrint(("D100Initialize"));
for ( i = 0; i < MediumArraySize ; i++ )
{
if( MediumArray[i] == NdisMedium802_3)
break;
}
if (i == MediumArraySize )
return NDIS_STATUS_UNSUPPORTED_MEDIA ;
*SelectedMediumIndex = i ;
Status = D100_ALLOC_MEM ( &Adapter ,
sizeof( D100_ADAPTER ));
if (Status != NDIS_STATUS_SUCCESS )
return Status;
NdisZeroMemory (Adapter,sizeof( D100_ADAPTER));
Adapter->D100AdapterHandle = MiniportAdapterHandle ;
Adapter->InterruptMode = NdisInterruptLevelSensitive;
/**returns a handle for a registry key
in which an NDIS NIC driver's configuration
parameters are stored.***/
NdisOpenConfiguration(&Status,&ConfigHandle,
WrapperConfigurationContext);
if(Status!=NDIS_STATUS_SUCCESS)
return NDIS_STATUS_FAILURE;
NdisCloseConfiguration(ConfigHandle);
IfType = NdisInterfacePci ;
/**informs the NDIS library about significant
features of the caller's NIC or virtual NIC
during initialization***/
NdisMSetAttributesEx ( Adapter->D100AdapterHandle,
(NDIS_HANDLE) Adapter,
0,//check for hang Time in seconds
( ULONG ) NDIS_ATTRIBUTE_DESERIALIZE | NDIS_ATTRIBUTE_BUS_MASTER ,
IfType );
if ( ClaimAdapter( Adapter ) != NDIS_STATUS_SUCCESS )
{
//KdPrint(("****D100 failure***"));
return NDIS_STATUS_FAILURE ;
}
/******Setting Shared Adapter Memory****/
Status = SetupSharedAdapterMemory(Adapter);
// Check the status returned from SetupSharedAdapterMemory
if (Status != NDIS_STATUS_SUCCESS)
{
//KdPrint(("Shared Memory Allocation failed (Status = 0x%x)\n", Status));
FreeAdapter(Adapter);
return NDIS_STATUS_FAILURE;
}
ResetPhy(Adapter);
AutoNegotiate( Adapter );
/** Disabling The Interrupt Mask Register***/
D100DisableInterrupt(Adapter);
Status = SetupTransQ ( Adapter );
if (Status != NDIS_STATUS_SUCCESS)
{
FreeAdapter(Adapter);
return NDIS_STATUS_FAILURE;
}
// Setup receive queue
Status = SetupRecvQ ( Adapter );
if (Status != NDIS_STATUS_SUCCESS)
{
Adapter->RecvUnCached=0;
DeleteSharedMemoryAdapter(Adapter);
return NDIS_STATUS_FAILURE;
}
// Register interrupt with the NDIS wrapper.
NdisAllocateSpinLock (&Adapter->Lock);
Status = NdisMRegisterInterrupt(&Adapter->Interrupt,
Adapter->D100AdapterHandle,
Adapter->AiVector, // bus-relative vector number used by the NIC.
Adapter->AiInterrupt, // bus-relative DIRQL for the interrupt
TRUE, // MiniportISR function should be called each time the NIC interrupts
TRUE, // Other devices on the I/O bus can use this interrupt line
Adapter->InterruptMode); // using LevelSensitive Inerrupts
if (Status != NDIS_STATUS_SUCCESS)
{
//KdPrint(("Failed to register Interrupt wth NDIS\n"));
return NDIS_STATUS_FAILURE;
}
//KdPrint(("Successfully registered Interrupt with NDIS\n"));
//InitializePower(Adapter);
// register a shutdown handler...
/* NdisMRegisterAdapterShutdownHandler(Adapter->D100AdapterHandle,
(PVOID) Adapter,
(ADAPTER_SHUTDOWN_HANDLER) D100ShutdownHandler);
*/
//Adapter->LinkIsActive = NdisMediaStateConnected;
Adapter->CurrentPowerState = NdisDeviceStateD0;
Adapter->NextPowerState = NdisDeviceStateD0;
D100EnableInterrupt(Adapter);
/***Deallocatting all allocated memory and
DeRegistering the Interrupt******/
//DeleteAllAllocatedMemory(Adapter);
//KdPrint(("*** EXITING D100init ***"));
return NDIS_STATUS_SUCCESS;
}
NDIS_STATUS ClaimAdapter( PD100_ADAPTER Adapter )
{
USHORT NumPciBoardsFound;
USHORT VendorID = D100_VENDOR_ID;
USHORT DeviceID = D100_DEVICE_ID;
PCI_CARDS_FOUND_STRUC PciCardsFound;
UINT i=0;
//KdPrint(("********** I AM IN ClaimAdapter*******"));
NumPciBoardsFound=FindPciDevice50Scan(Adapter,VendorID,
DeviceID,&PciCardsFound);
Adapter->AiSlot = PciCardsFound.PciSlotInfo[i].SlotNumber;
Adapter->AiInterrupt = PciCardsFound.PciSlotInfo[i].Irq;
Adapter->AiVector=PciCardsFound.PciSlotInfo[i].Irq;
Adapter->CSRPhysicalAddress = PciCardsFound.PciSlotInfo[i].MemPhysAddress;
Adapter->AiBaseIo = (USHORT)PciCardsFound.PciSlotInfo[i].BaseIo;
//KdPrint(("VECTOR: %X DIRQL :%X",Adapter->AiVector,Adapter->AiInterrupt));
//KdPrint((" **Exiting ClaimAdapter Successfully**"));
return NDIS_STATUS_SUCCESS;
}
USHORT FindPciDevice50Scan(IN PD100_ADAPTER Adapter,
IN USHORT VendorID,IN USHORT DeviceID,
OUT PPCI_CARDS_FOUND_STRUC pPciCardsFound)
{
UINT i;
USHORT found = 0;
NDIS_STATUS Status;
ULONG Slot=0;
PNDIS_RESOURCE_LIST AssignedResources;
//KdPrint(("***** I AM IN FindPciDevice50Scan ****"));
Status = NdisMPciAssignResources(
Adapter->D100AdapterHandle,
Slot,
&AssignedResources);
for (i=0;i < AssignedResources->Count;i++ )
{
switch (AssignedResources->PartialDescriptors[i].Type)
{
case CmResourceTypePort:
if (AssignedResources->PartialDescriptors[i].Flags & CM_RESOURCE_PORT_IO)
{
pPciCardsFound->PciSlotInfo[found].BaseIo =
(ULONG) ((AssignedResources)->PartialDescriptors[i].u.Port.Start.u.LowPart);
//KdPrint(("Base IO : %x ", pPciCardsFound->PciSlotInfo[found].BaseIo));
}
break;
case CmResourceTypeInterrupt:
pPciCardsFound->PciSlotInfo[found].Irq =
(UCHAR) ((AssignedResources)->PartialDescriptors[i].u.Interrupt.Level);
break;
case CmResourceTypeMemory:
pPciCardsFound->PciSlotInfo[found].MemPhysAddress =
(ULONG) ((AssignedResources)->PartialDescriptors[i].u.Memory.Start.u.LowPart);
break;
}
}
return found;
}
NDIS_STATUS SetupSharedAdapterMemory(IN PD100_ADAPTER Adapter)
{
UINT i;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
NDIS_PHYSICAL_ADDRESS NdisPhysicalCsrAddress;
//KdPrint(("I AM IN SetupSharedAdapterMemory"));
Adapter->NumMapRegisters = NO_OF_MAP_REGISTERS;
Adapter->MaxPhysicalMappings = MAXIMUM_ETHERNET_PACKET_SIZE;
//KdPrint(("%x..",Adapter->D100AdapterHandle));
// Get a virtual address for our CSR structure. So that we can access
// the CSR's registers via memory mapping.
NdisSetPhysicalAddressLow (NdisPhysicalCsrAddress, (ULONG)Adapter->CSRPhysicalAddress);
NdisSetPhysicalAddressHigh (NdisPhysicalCsrAddress, 0);
//KdPrint(("Adapter->CSRAddress before mapping :%X\n",Adapter->CSRAddress));
//KdPrint(("NdisPhysicalCsrAddress: %X\n",NdisPhysicalCsrAddress));
Status = NdisMMapIoSpace ( OUT (PVOID *) &(Adapter->CSRAddress),
Adapter->D100AdapterHandle,
NdisPhysicalCsrAddress,
256);
// If we couldn't get a virtual memory address for our CSR, then error out.
if (Status != NDIS_STATUS_SUCCESS) //|| (Adapter->CSRAddress == NULL))
{
//KdPrint(("Could not memory map the CSR phys = %x\n", Adapter->CSRPhysicalAddress));
//KdPrint((" Status : %x",Status));
return Status;
}
//KdPrint(("D100 CSR phys = %x, D100 CSR virt = %x\n", Adapter->CSRPhysicalAddress,Adapter->CSRAddress));
//KdPrint(("*******MAC ADDRESS*********"));
for(i=0;i<ETH_LENGTH_OF_ADDRESS;i++)
{
NdisReadRegisterUchar((PUCHAR)(Adapter->CSRAddress+MAC+i),&Adapter->AiNodeAddress[i]);
//KdPrint(("\t%X ",Adapter->AiNodeAddress[i]));
Adapter->AiPermanentNodeAddress[i]=Adapter->AiNodeAddress[i];
}
//KdPrint(("Allocating %x map registers\n", Adapter->NumMapRegisters));
Status = NdisMAllocateMapRegisters(Adapter->D100AdapterHandle,
0,
TRUE,
Adapter->NumMapRegisters,
Adapter->MaxPhysicalMappings);
if (Status != NDIS_STATUS_SUCCESS)
{
//KdPrint(("NdisMAllocateMapRegister Failed - %x\n", Status));
Adapter->NumMapRegisters = 0;
return Status;
}
return NDIS_STATUS_SUCCESS;
}
VOID ResetPhy(IN PD100_ADAPTER Adapter)
{
UCHAR rdata;
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG),&rdata ) ;
//KdPrint(("Command Reg = %X\n",rdata));
NdisWriteRegisterUchar( (PUCHAR)(Adapter->CSRAddress+ CMND_REG), 0x10 ) ;
NdisStallExecution(2000);
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG),&rdata ) ;
//KdPrint(("Command Reg After Reset = %X\n\n",rdata));
return;
}
NDIS_STATUS SetupTransQ(IN PD100_ADAPTER Adapter)
{
USHORT i;
ULONG DATA;
ULONG rdata ;
UCHAR commandReg ;
ULONG transConfReg ;
ULONG SIZE_OF_DESC = 0x0 ;
Adapter->TransUnCachedSize = MAX_TRANS_BUFFER_SIZE;
//KdPrint(("Begin SetupTransQ \n"));
/**** Allocate SharedMemory for Transmit Buffer Descriptors
allocates and maps a host memory range so it is simultaneously
accessible from both the system and a busmaster DMA NIC.****/
for(i=0;i<NUM_OF_TRANS_DESC;i++)
{
NdisMAllocateSharedMemory( Adapter->D100AdapterHandle,
Adapter->TransUnCachedSize,
FALSE,
( PVOID ) &Adapter->TransUnCached[i],
&Adapter->TransUnCachedPhys[i]);
//KdPrint(("VIRTUAL ADDRESS OF TRANSMIT BUFFER[%d] = %X\n",i, Adapter->TransUnCached[i]));
//KdPrint(("PHYSICAL ADDRESS OF TRANSMIT BUFFER[%d] = %X\n\n",i, Adapter->TransUnCachedPhys[i]));
}
// Set Transmit Enable bit
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ),&commandReg ) ;
//KdPrint(("Command Reg Before Transmit Enable = %X\n",commandReg ));
commandReg |= TRANS_ENABLE ;
NdisWriteRegisterUchar( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), commandReg ) ;
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), &commandReg ) ;
//KdPrint(("Command Reg After Transmit Enable = %X\n\n",commandReg ));
// Set Transmit Configuration register
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + TRANS_CONFIG_REG ),&transConfReg ) ;
//KdPrint(("Transmit Configuration Reg Before Enable = %X\n",transConfReg ));
transConfReg &=0;
transConfReg |= TCR_ENABLE;
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + TRANS_CONFIG_REG ), transConfReg ) ;
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + TRANS_CONFIG_REG ), &transConfReg ) ;
//KdPrint(("Transmit Configuration Reg After Enable = %X\n\n",transConfReg ));
// Set the Transmit Start Address registers
for ( i = 0 ; i < NUM_OF_TRANS_DESC ; i++ )
{
// update TSAD
DATA=Adapter->TransUnCachedPhys[i].LowPart ;
// DATA+=3;
// DATA&=~3;
NdisWriteRegisterUlong(
(PULONG)(Adapter->CSRAddress + TSAD0+ SIZE_OF_DESC ),
DATA) ;
// read the updated TSAD
NdisReadRegisterUlong (
(PULONG)(Adapter->CSRAddress + TSAD0+ SIZE_OF_DESC),
&rdata) ;
//KdPrint(("Virtual Start Address of TSAD%d :%X \n\n",i,rdata));
SIZE_OF_DESC += 4 ;
}
Adapter->NoPackets=0;
Adapter->ReadDesc=0;
Adapter->WriteDesc=0;
//KdPrint(("End SetupTransQ \n\n"));
return NDIS_STATUS_SUCCESS;
}
NDIS_STATUS SetupRecvQ(IN PD100_ADAPTER Adapter)
{
ULONG rdata ;
UCHAR commandReg ;
ULONG recvConfReg ;
NDIS_STATUS Status;
UINT NumberOfDescriptors=1;
Adapter->RecvUnCachedSize = MAX_RECV_BUFF_SIZE ;
//KdPrint(("Begin SetupRecvQ \n"));
// Allocate SharedMemory for Receive Buffer.
// NdisMAllocateSharedMemory allocates and maps a host memory range so it
// is simultaneously accessible from both the system and a busmaster DMA NIC.
NdisMAllocateSharedMemory( Adapter->D100AdapterHandle,
Adapter->RecvUnCachedSize,
FALSE,
( PVOID ) &Adapter->RecvUnCached,
&Adapter->RecvUnCachedPhys);
//KdPrint(("VIRTUAL ADDRESS OF RECEIVE BUFFER = %X\n",Adapter->RecvUnCached));
//KdPrint(("PHYSICAL ADDRESS OF RECEIVE BUFFER = %X\n\n",Adapter->RecvUnCachedPhys));
// Set Receive Enable bit
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ),&commandReg ) ;
//KdPrint(("Command Reg Before Receive Enable = %X\n",commandReg));
commandReg |= RECV_ENABLE ;
NdisWriteRegisterUchar( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), commandReg ) ;
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), &commandReg ) ;
// Read the status of the Command Register
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG),&commandReg ) ;
//KdPrint(("Command Reg After Receive Enable = %X\n\n",commandReg));
// Set Receive Configuration register
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + RECV_CONFIG_REG ),&recvConfReg ) ;
//KdPrint(("Receive Configuration Reg Before Enable = %X\n",recvConfReg ));
recvConfReg |= RCR_ENABLE ;
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + RECV_CONFIG_REG ), recvConfReg ) ;
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + RECV_CONFIG_REG ), &recvConfReg ) ;
//KdPrint(("Receive Configuration Reg After Enable = %X\n\n",recvConfReg ));
// Set Receive Buffer start register
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + RBSTART ), Adapter->RecvUnCachedPhys.LowPart ) ;
// read the updated RBSTART
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + RBSTART ), &rdata ) ;
//KdPrint(("Receive Buffer Start Address Regsister %X \n\n",rdata));
//****GETTING PACKET POOL HANDLE****************/
NdisAllocatePacketPool( &Status,
&Adapter->RxPacketPoolHandle,
NumberOfDescriptors,
16);
if(Status!=NDIS_STATUS_SUCCESS )
{
KdPrint(("~~~~Ndis Allocate Packet Pool Failed~~~~"));
}
//******GETTING BUFFER POOL HANDLE****************/
NdisAllocateBufferPool( &Status,
&Adapter->RxBufferPoolHandle,
NumberOfDescriptors);
if(Status!=NDIS_STATUS_SUCCESS )
{
KdPrint(("~~~~Ndis Allocate Buffer Pool Failed~~~~"));
}
//KdPrint(("End SetupRecvQ \n\n"));
return NDIS_STATUS_SUCCESS;
}
VOID D100DisableInterrupt(IN PD100_ADAPTER Adapter)
{
USHORT intrmskReg;
NdisReadRegisterUshort ( (PUSHORT)(Adapter->CSRAddress + IMR ),&intrmskReg ) ;
//KdPrint(("Interrupt Mask Reg Before Disable = %X\n",intrmskReg ));
// Disable the interrupts
NdisWriteRegisterUshort( (PUSHORT)(Adapter->CSRAddress + IMR ),0x0000 ) ;
// check the status of IMR
NdisReadRegisterUshort ( (PUSHORT)(Adapter->CSRAddress + IMR ), &intrmskReg ) ;
//KdPrint(("Interrupt Mask Reg After Disable = %X\n\n",intrmskReg ));
//KdPrint(("End D100DisableInterrupt"));
}
VOID D100EnableInterrupt(IN PD100_ADAPTER Adapter)
{
USHORT IMRREG;
NdisWriteRegisterUshort((PUSHORT)(Adapter->CSRAddress+IMR),0x002F);
NdisReadRegisterUshort((PUSHORT)(Adapter->CSRAddress+IMR),&IMRREG);
//KdPrint(("IMR REG AFTER ENABLE : %X",IMRREG));
}
VOID AutoNegotiate(IN PD100_ADAPTER Adapter )
{
USHORT bmcrdata;
USHORT BMSRDATA;
UINT i=0;
//KdPrint(("Begin AutoNegotiate\n"));
//seting 93C56Command Register
NdisWriteRegisterUchar((PUCHAR)(Adapter->CSRAddress + CMREG93C56 ),EEM) ;
NdisReadRegisterUshort ( (PUSHORT) (Adapter->CSRAddress + BASIC_MODE_CTRL_REG ),&bmcrdata ) ;
//KdPrint(("BMCR BEFORE RESET :: %X",bmcrdata));
/**RESETTING BMCR **/
NdisWriteRegisterUshort((PUSHORT) (Adapter->CSRAddress + BASIC_MODE_CTRL_REG ),BMCR_RESET) ;
NdisStallExecution(10000);
NdisReadRegisterUshort ( (PUSHORT) (Adapter->CSRAddress + BASIC_MODE_CTRL_REG ),&bmcrdata ) ;
//KdPrint(("BMCR AFTER RESET :: %X",bmcrdata));
//KdPrint(("BMCR BEFORE AUOTONEG::%X",bmcrdata));
NdisReadRegisterUshort( (PUSHORT) (Adapter->CSRAddress +0x0064 ),&BMSRDATA);
//KdPrint(("BMSR BEFORE AUTO NEGO:: %X",BMSRDATA));
bmcrdata |= BMCR_ENABLE;
NdisWriteRegisterUshort ( (PUSHORT) (Adapter->CSRAddress + BASIC_MODE_CTRL_REG ),bmcrdata ) ;
NdisReadRegisterUshort ( (PUSHORT) (Adapter->CSRAddress + BASIC_MODE_CTRL_REG ),&bmcrdata ) ;
//KdPrint(("BMCR AFTER AUTONEGOTIATE %X\n",bmcrdata));
do
{
NdisStallExecution(1000000);
NdisReadRegisterUshort( (PUSHORT) (Adapter->CSRAddress +0x0064 ),&BMSRDATA);
//KdPrint(("BMSR :: %X",BMSRDATA));
BMSRDATA &= 0x0020;
if(BMSRDATA== 0x0020)
{
KdPrint(("**AUTONEGOTIATION COMPLETED SUCCESSFULLY**"));
break;
}
i++;
}while(i<5);
//if(BMSRDATA!= 0x0020)
//KdPrint(("** AutoNegotiation Timeout/Failed**"));
//KdPrint(("End AutoNegotiate\n"));
}
VOID DeleteAllAllocatedMemory(PD100_ADAPTER Adapter)
{
//KdPrint(( "I am in DeleteAll "));
//KdPrint(("***************"));
DeleteSharedMemoryAdapter(Adapter);
if(Adapter->NumMapRegisters)
{
NdisMFreeMapRegisters(Adapter->D100AdapterHandle);
//KdPrint((" After Free Map Register the interrupt"));
}
if(Adapter->CSRAddress)
NdisMUnmapIoSpace((Adapter->D100AdapterHandle),
(PVOID)(Adapter->CSRAddress),256);
NdisFreeSpinLock (&Adapter->Lock);
FreeAdapter(Adapter);
//KdPrint((" Deallocation is finished"));
}
VOID DeleteSharedMemoryAdapter(IN PD100_ADAPTER Adapter)
{
UINT i=0;
//KdPrint(("****I AM IN DELETE SHARED MEMORY ADAPTER****"));
if(Adapter->TransUnCached[0])
{
//KdPrint((" DEALLOCATING TRANSMIT BUFFER\n"));
for(i=0;i<NUM_OF_TRANS_DESC;i++)
{
NdisMFreeSharedMemory( Adapter->D100AdapterHandle,
Adapter->TransUnCachedSize,
FALSE,
( PVOID ) Adapter->TransUnCached[i],
Adapter->TransUnCachedPhys[i]);
}
}
if(Adapter->RxPacketPoolHandle)
NdisFreePacketPool(Adapter->RxPacketPoolHandle);
if(Adapter->RxBufferPoolHandle)
NdisFreeBufferPool(Adapter->RxBufferPoolHandle);
if(Adapter->RecvUnCached)
{
//KdPrint(("DEALLOCATING RECV BUFFER"));
NdisMFreeSharedMemory( Adapter->D100AdapterHandle,
Adapter->RecvUnCachedSize,
FALSE,
( PVOID ) Adapter->RecvUnCached,
Adapter->RecvUnCachedPhys );
}
//KdPrint(("END OF DELETE SHARED MEMORY ADAPTER"));
}
VOID FreeAdapter(IN PD100_ADAPTER Adapter)
{
//KdPrint((" ***** FREE ADAPTER ****"));
D100_FREE_MEM (Adapter,sizeof( D100_ADAPTER ));
}
//-----------------------------------------------------------------------------
// Procedure: D100QueryInformation
//
// Description: D100QueryInformation handles a query operation for a single
// OID. Basically we return information about the current state of
// the OID in question.
//-----------------------------------------------------------------------------
NDIS_STATUS
D100QueryInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesWritten,
OUT PULONG BytesNeeded
)
{
// order is important here because the OIDs should be in order
// of increasing value
static
NDIS_OID D100GlobalSupportedOids[] =
{
OID_GEN_SUPPORTED_LIST,
OID_GEN_HARDWARE_STATUS,
OID_GEN_MEDIA_SUPPORTED,
OID_GEN_MEDIA_IN_USE,
OID_GEN_MAXIMUM_LOOKAHEAD,
OID_GEN_MAXIMUM_FRAME_SIZE,
OID_GEN_LINK_SPEED,
OID_GEN_TRANSMIT_BUFFER_SPACE,
OID_GEN_RECEIVE_BUFFER_SPACE,
OID_GEN_TRANSMIT_BLOCK_SIZE,
OID_GEN_RECEIVE_BLOCK_SIZE,
OID_GEN_VENDOR_ID,
OID_GEN_VENDOR_DESCRIPTION,
OID_GEN_CURRENT_PACKET_FILTER,
OID_GEN_CURRENT_LOOKAHEAD,
OID_GEN_DRIVER_VERSION,
OID_GEN_MAXIMUM_TOTAL_SIZE,
OID_GEN_PROTOCOL_OPTIONS,
OID_GEN_MAC_OPTIONS,
OID_GEN_MEDIA_CONNECT_STATUS,
OID_GEN_MAXIMUM_SEND_PACKETS,
OID_GEN_SUPPORTED_GUIDS,
OID_GEN_XMIT_OK,
OID_GEN_RCV_OK,
OID_GEN_XMIT_ERROR,
OID_GEN_RCV_ERROR,
OID_GEN_RCV_NO_BUFFER,
OID_GEN_RCV_CRC_ERROR,
OID_GEN_TRANSMIT_QUEUE_LENGTH,
OID_802_3_PERMANENT_ADDRESS,
OID_802_3_CURRENT_ADDRESS,
OID_802_3_MULTICAST_LIST,
OID_802_3_MAXIMUM_LIST_SIZE,
// for ndis 4 packet priority
//OID_802_3_MAC_OPTIONS,
/* OID_802_3_RCV_ERROR_ALIGNMENT,
OID_802_3_XMIT_ONE_COLLISION,
OID_802_3_XMIT_MORE_COLLISIONS,
OID_802_3_XMIT_DEFERRED,
OID_802_3_XMIT_MAX_COLLISIONS,
OID_802_3_RCV_OVERRUN,
OID_802_3_XMIT_UNDERRUN,
OID_802_3_XMIT_HEARTBEAT_FAILURE,
OID_802_3_XMIT_TIMES_CRS_LOST,
OID_802_3_XMIT_LATE_COLLISIONS,
*/ // tcp/ip checksum offload
// OID_TCP_TASK_OFFLOAD
// powermanagement
OID_PNP_CAPABILITIES,
OID_PNP_SET_POWER,
OID_PNP_QUERY_POWER,
OID_PNP_ADD_WAKE_UP_PATTERN,
OID_PNP_REMOVE_WAKE_UP_PATTERN,
OID_PNP_ENABLE_WAKE_UP
};
// String describing our adapter
char VendorDescriptor[] = VENDORDESCRIPTOR;
PD100_ADAPTER Adapter;
UCHAR VendorId[4];
NDIS_MEDIUM Medium = NdisMedium802_3;
NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady;
UINT GenericUlong;
USHORT GenericUShort;
UCHAR GenericArray[6];
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
NDIS_PNP_CAPABILITIES Power_Management_Capabilities;
// Common variables for pointing to result of query
PVOID MoveSource = (PVOID) (&GenericUlong);
ULONG MoveBytes = sizeof(GenericUlong);
UCHAR read;
Adapter = (PD100_ADAPTER)(MiniportAdapterContext);
// Initialize the result
*BytesWritten = 0;
*BytesNeeded = 0;
// Switch on request type
switch (Oid)
{
case OID_GEN_MAC_OPTIONS:
//KdPrint(("QUERY:OID_GEN_MAC_OPTIONS \n"));
GenericUlong = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
NDIS_MAC_OPTION_NO_LOOPBACK
);
break;
case OID_GEN_SUPPORTED_LIST:
//KdPrint(("QUERY:OID_GEN_SUPPORTED_LIST\n"));
MoveSource = (PVOID) (D100GlobalSupportedOids);
MoveBytes = sizeof(D100GlobalSupportedOids);
break;
case OID_GEN_HARDWARE_STATUS:
//KdPrint(("QUERY:OID_GEN_HARDWARE_STATUS \n"));
MoveSource = (PVOID)(&HardwareStatus);
MoveBytes = sizeof(NDIS_HARDWARE_STATUS);
break;
case OID_GEN_MEDIA_SUPPORTED:
case OID_GEN_MEDIA_IN_USE:
//KdPrint(("QUERY: OID_GEN_MEDIA_SUPPORTED\n"));
MoveSource = (PVOID) (&Medium);
MoveBytes = sizeof(NDIS_MEDIUM);
break;
case OID_GEN_MAXIMUM_LOOKAHEAD:
case OID_GEN_CURRENT_LOOKAHEAD:
case OID_GEN_MAXIMUM_FRAME_SIZE:
//KdPrint(("QUERY: OID_GEN_MAXIMUM_LOOKAHEAD\n"));
GenericUlong = MAXIMUM_ETHERNET_PACKET_SIZE - ENET_HEADER_SIZE;
break;
case OID_GEN_MAXIMUM_TOTAL_SIZE:
case OID_GEN_TRANSMIT_BLOCK_SIZE:
case OID_GEN_RECEIVE_BLOCK_SIZE:
//KdPrint(("QUERY: OID_GEN_MAXIMUM_TOTAL_SIZE\n"));
GenericUlong = (ULONG) MAXIMUM_ETHERNET_PACKET_SIZE;
break;
case OID_GEN_LINK_SPEED:
//KdPrint(("QUERY:OID_GEN_LINK_SPEED \n"));
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + MSR),&read ) ;
if(read & 8)
Adapter->AiLineSpeedCur = 10; //10MHz
else
Adapter->AiLineSpeedCur = 100; //100MHz
GenericUlong = (((ULONG) Adapter->AiLineSpeedCur) * 10000);
//KdPrint(("SPEED : %d Mbps",Adapter->AiLineSpeedCur));
break;
case OID_GEN_TRANSMIT_BUFFER_SPACE:
//KdPrint(("QUERY TRANSMIT BUFFER SPACE "));
GenericUlong = (ULONG) MAXIMUM_ETHERNET_PACKET_SIZE *NUM_OF_TRANS_DESC;
break;
case OID_GEN_RECEIVE_BUFFER_SPACE:
//KdPrint(("RCV BUFFER SPACE"));
GenericUlong = (ULONG) MAXIMUM_ETHERNET_PACKET_SIZE;
break;
case OID_GEN_VENDOR_ID:
//KdPrint(("QUERY:OID_GEN_VENDOR_ID \n"));
NdisMoveMemory(VendorId, Adapter->AiNodeAddress, 3);
VendorId[3] = 0x0;
MoveSource = (PVOID) VendorId;
MoveBytes = sizeof(VendorId);
break;
case OID_GEN_VENDOR_DESCRIPTION:
//KdPrint(("QUERY:OID_GEN_VENDOR_DESCRIPTION \n"));
MoveSource = (PVOID) VendorDescriptor;
MoveBytes = sizeof(VendorDescriptor);
break;
case OID_GEN_DRIVER_VERSION:
//KdPrint(("QUERY:OID_GEN_DRIVER_VERSION \n"));
GenericUShort = (USHORT) D100_DRIVER_VERSION;
MoveSource = (PVOID)(&GenericUShort);
MoveBytes = sizeof(GenericUShort);
break;
case OID_802_3_PERMANENT_ADDRESS:
//KdPrint(("QUERY: OID_802_3_PERMANENT_ADDRESS\n"));
ETH_COPY_NETWORK_ADDRESS(
(PCHAR) GenericArray,
Adapter->AiPermanentNodeAddress);
MoveSource = (PVOID) (GenericArray);
MoveBytes = ETH_LENGTH_OF_ADDRESS;
break;
case OID_802_3_CURRENT_ADDRESS:
//KdPrint(("QUERY:OID_802_3_CURRENT_ADDRESS \n"));
ETH_COPY_NETWORK_ADDRESS(
GenericArray,
Adapter->AiNodeAddress);
MoveSource = (PVOID) (GenericArray);
MoveBytes = ETH_LENGTH_OF_ADDRESS;
break;
case OID_802_3_MAXIMUM_LIST_SIZE:
//KdPrint(("QUERY:OID_802_3_MAXIMUM_LIST_SIZE \n"));
GenericUlong = (ULONG) MAX_MULTICAST_ADDRESSES;
break;
case OID_GEN_MAXIMUM_SEND_PACKETS:
//KdPrint(("QUERY:OID_GEN_MAXIMUM_SEND_PACKETS \n"));
GenericUlong = 1;
break;
case OID_GEN_MEDIA_CONNECT_STATUS:
//KdPrint(("QUERY:OID_GEN_MEDIA_CONNECT_STATUS \n"));
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress +MSR),&read ) ;
if(read & 4)
{
Adapter->LinkIsActive = NdisMediaStateDisconnected;
//KdPrint(("~~~NETWORK CABLE STATUS UNPLUGGED~~~"));
}
else
{
Adapter->LinkIsActive = NdisMediaStateConnected;
//KdPrint(("^^^^^NETWORK CABLE STATUS CONNECTED^^^^^"));
}
GenericUlong = (ULONG) Adapter->LinkIsActive;
break;
case OID_GEN_XMIT_OK :
//KdPrint(("QUERY:OID_GEN_XMIT_OK \n"));
GenericUlong = Adapter->GoodTransmits;
break;
case OID_GEN_RCV_OK :
//KdPrint(("QUERY:OID_GEN_RCV_OK \n"));
GenericUlong = Adapter->GoodReceives ;
break;
case OID_GEN_XMIT_ERROR :
//KdPrint(("QUERY:OID_GEN_XMIT_ERROR \n"));
GenericUlong = Adapter->Trans_Error ;
break;
case OID_GEN_RCV_ERROR :
//KdPrint(("QUERY:OID_GEN_RCV_ERROR \n"));
GenericUlong = Adapter->Rcv_Error ;
break;
case OID_GEN_RCV_NO_BUFFER :
//KdPrint(("OID_GEN_RCV_NO_BUFFER \n"));
GenericUlong = Adapter->Rcv_No_Buffer ;
break;
case OID_PNP_CAPABILITIES:
//KdPrint(("QUERY:PNP CAPABILITIES"));
// since we are stubbing power management, return only the
// D0 power state indicating that the lowest power state we
// support is D0 (full power)
Power_Management_Capabilities.Flags=NDIS_DEVICE_WAKE_UP_ENABLE ;
Power_Management_Capabilities.WakeUpCapabilities.MinLinkChangeWakeUp = NdisDeviceStateD1;
Power_Management_Capabilities.WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateD1;
Power_Management_Capabilities.WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateD1;
MoveSource = (PVOID) &Power_Management_Capabilities;
MoveBytes = sizeof(NDIS_PNP_CAPABILITIES);
Status = NDIS_STATUS_SUCCESS;
break;
case OID_PNP_QUERY_POWER:
Status = NDIS_STATUS_SUCCESS; //stub
break;
default:
//KdPrint(("QUERY:Default"));
Status = NDIS_STATUS_NOT_SUPPORTED;
break;
}
if (Status == NDIS_STATUS_SUCCESS)
{
if (MoveBytes > InformationBufferLength)
{
// Not enough room in InformationBuffer. Punt
*BytesNeeded = MoveBytes;
Status = NDIS_STATUS_BUFFER_TOO_SHORT;
}
else
{
// Copy result into InformationBuffer
*BytesWritten = MoveBytes;
if (MoveBytes > 0)
NdisMoveMemory(InformationBuffer, MoveSource, MoveBytes);
}
}
return (Status);
} // end of D100QueryInformation
NDIS_STATUS
D100SetInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesRead,
OUT PULONG BytesNeeded
)
{
NDIS_STATUS Status;
ULONG PacketFilter;
PD100_ADAPTER Adapter;
UCHAR commandReg;
ULONG transConfReg;
ULONG recvConfReg;
USHORT i;
ULONG DATA;
ULONG SIZE_OF_DESC = 0x0 ;
Adapter = (PD100_ADAPTER)(MiniportAdapterContext);
*BytesRead = 0;
*BytesNeeded = 0;
Status=NDIS_STATUS_SUCCESS;
switch (Oid)
{
case OID_802_3_MULTICAST_LIST:
//KdPrint(("SETINFORMATION : OID_802_3_MULTICAST_LIST\n"));
if (InformationBufferLength % ETH_LENGTH_OF_ADDRESS != 0)
return (NDIS_STATUS_INVALID_LENGTH);
NdisMoveMemory(Adapter->PrivateMulticastBuffer,
InformationBuffer,
InformationBufferLength);
// Save the number of MC address in our adapter object
Adapter->NumberOfMcAddresses =
(InformationBufferLength / ETH_LENGTH_OF_ADDRESS);
//Status = D100ChangeMCAddresses(
// Adapter,
//InformationBufferLength /
//ETH_LENGTH_OF_ADDRESS);
Status = NDIS_STATUS_SUCCESS;
*BytesRead = InformationBufferLength;
break;
case OID_GEN_CURRENT_PACKET_FILTER:
//KdPrint(("SETINFORMATION : OID_GEN_CURRENT_PACKET_FILTER\n"));
if (InformationBufferLength != 4)
return (NDIS_STATUS_INVALID_LENGTH);
// Now call the filter package to set the packet filter.
NdisMoveMemory((PVOID)&PacketFilter, InformationBuffer, sizeof(ULONG));
// Verify bits, if any bits are set that we don't support, leave
if (PacketFilter &
~(NDIS_PACKET_TYPE_DIRECTED |
NDIS_PACKET_TYPE_MULTICAST |
NDIS_PACKET_TYPE_BROADCAST |
NDIS_PACKET_TYPE_PROMISCUOUS |
NDIS_PACKET_TYPE_ALL_MULTICAST))
{
KdPrint(("********************"));
Status = NDIS_STATUS_NOT_SUPPORTED;
*BytesRead = 4;
break;
}
// If this is a miniport driver, the submit the packet filter change
// to our hardware,by directly calling D100SetPacketFilter.
// Status = D100SetPacketFilter(
// Adapter,
// PacketFilter);
Status = NDIS_STATUS_SUCCESS;
*BytesRead = InformationBufferLength;
break;
case OID_GEN_CURRENT_LOOKAHEAD:
//KdPrint(("SETINFORMATION : case OID_GEN_CURRENT_LOOKAHEAD\n"));
// Verify the Length
if (InformationBufferLength != 4)
return (NDIS_STATUS_INVALID_LENGTH);
*BytesRead = 4;
Status = NDIS_STATUS_SUCCESS;
break;
case OID_PNP_SET_POWER:
KdPrint(("**** POWER MANAGEMENT ****"));
KdPrint(("*** I AM IN SET POWER ***"));
Adapter->IsrReg=0;
Adapter->WriteDesc=0;
Adapter->ReadDesc=0;
Adapter->NoPackets=0;
ResetPhy(Adapter);
AutoNegotiate(Adapter);
D100DisableInterrupt(Adapter);
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ),&commandReg ) ;
commandReg |= TRANS_ENABLE ;
NdisWriteRegisterUchar( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), commandReg ) ;
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + TRANS_CONFIG_REG ),&transConfReg ) ;
transConfReg &=0;
transConfReg |= TCR_ENABLE;
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + TRANS_CONFIG_REG ), transConfReg ) ;
for ( i = 0 ; i < NUM_OF_TRANS_DESC ; i++ )
{
DATA=Adapter->TransUnCachedPhys[i].LowPart ;
NdisWriteRegisterUlong(
(PULONG)(Adapter->CSRAddress + TSAD0+ SIZE_OF_DESC ),
DATA) ;
SIZE_OF_DESC += 4 ;
}
/****************/
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ),&commandReg ) ;
commandReg |= RECV_ENABLE ;
NdisWriteRegisterUchar( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), commandReg ) ;
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + RECV_CONFIG_REG ),&recvConfReg ) ;
recvConfReg |= RCR_ENABLE ;
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + RECV_CONFIG_REG ), recvConfReg ) ;
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + RBSTART ), Adapter->RecvUnCachedPhys.LowPart ) ;
NdisWriteRegisterUshort((PUSHORT)(Adapter->CSRAddress+CAPR),0xfff0);
D100EnableInterrupt(Adapter);
*BytesRead = InformationBufferLength;
Status = NDIS_STATUS_SUCCESS;
//BytesRead = 0; //stub
//Status = NDIS_STATUS_NOT_SUPPORTED; //stub
break;
/*
case OID_PNP_ADD_WAKE_UP_PATTERN:
// call a function that would program the adapter's wake
// up pattern, return success
*BytesRead = InformationBufferLength;
Status = NDIS_STATUS_SUCCESS;
//*BytesRead = 0; //stub
//Status = NDIS_STATUS_NOT_SUPPORTED; //stub
break;
case OID_PNP_REMOVE_WAKE_UP_PATTERN:
// call a function that would remove the adapter's wake
// up pattern, return success
*BytesRead = InformationBufferLength;
//*BytesRead = 0;
Status = NDIS_STATUS_SUCCESS;//stub
//Status = NDIS_STATUS_NOT_SUPPORTED; //stub
break;
*/
case OID_PNP_ENABLE_WAKE_UP:
// call a function that would enable wake up on the adapter
// return success
KdPrint(("**** POWER MANAGEMENT ****"));
KdPrint(("*** I AM IN ENABLE WAKE UP ***"));
D100DisableInterrupt(Adapter);
while(Adapter->NoPackets)
{
Adapter->GoodTransmits++;
//KdPrint(("Adapter->Packet:%X",Adapter->Packet));
//KdPrint(("Total Packets Transmitted : %d\n", Adapter->ReadDesc));
//KdPrint(("TxREAD_DESC : %d",Adapter->ReadDesc));
NdisMSendComplete(Adapter->D100AdapterHandle,
Adapter->Packet[Adapter->ReadDesc],
NDIS_STATUS_SUCCESS);
Adapter->ReadDesc=(Adapter->ReadDesc+1) % NUM_OF_TRANS_DESC;
//KdPrint(("PACKETS COMPLETED : %d ",Adapter->NoPackets));
Adapter->NoPackets--;
//KdPrint(("______TRANSMISSION IS SUCCESS_____"));
}
NdisMEthIndicateReceiveComplete(Adapter->D100AdapterHandle);
InitializePower(Adapter);
*BytesRead = InformationBufferLength;
Status = NDIS_STATUS_SUCCESS;
// *BytesRead = 0;//stub
// Status = NDIS_STATUS_NOT_SUPPORTED; //stub
break;
default:
//KdPrint(("Default SetOID...\n"));
Status = NDIS_STATUS_INVALID_OID;
break;
} // end of switch construct
return Status;
}
//-----------------------------------------------------------------------------
// Procedure: D100Isr (miniport)
//
// Description: This is the interrupt service routine. It will check to see
// if there are any interrupts pending, and if there are, it will
// disable board interrupts and schedule a HandleInterrupt
// callback.
//-----------------------------------------------------------------------------
VOID D100Isr(
OUT PBOOLEAN InterruptRecognized,
OUT PBOOLEAN QueueMiniportHandleInterrupt,
IN NDIS_HANDLE MiniportAdapterContext
)
{
PD100_ADAPTER Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
//KdPrint(("****** I AM IN ISR******"));
NdisReadRegisterUshort((PUSHORT) (Adapter->CSRAddress +ISR),&Adapter->IsrReg);
NdisWriteRegisterUshort((PUSHORT)(Adapter->CSRAddress+ISR),Adapter->IsrReg);
//KdPrint(("ISR = %4X(Hex)", Adapter->IsrReg));
// We want to process the interrupt if the output from our interrupt line
// is high, and our interrupt is not masked. If our interrupt line
// is already masked, then we must be currently processing interrupts.
if (Adapter->IsrReg)
{
// DEBUGSTR(("Our INT -- slot %x\n", Adapter->AiSlot));
//KdPrint((" **** I AM IN ISR INSIDE IF LOOP*****"));
*InterruptRecognized = TRUE;
*QueueMiniportHandleInterrupt = TRUE;
D100DisableInterrupt(Adapter);
}
else
{
*InterruptRecognized = FALSE;
*QueueMiniportHandleInterrupt = FALSE;
}
return;
}
//-----------------------------------------------------------------------------
// Procedure: D100HandleInterrupt
//
// Description: This routine is queued by the ISR when some interrupt
// processing needs to be done. It's main job is to call the
// interrupt processing code (process receives, cleanup completed
// transmits, etc). It will only be called with the adapter's
// interrupts masked. This is the DPC for this driver.
//-----------------------------------------------------------------------------
VOID D100HandleInterrupt(
IN NDIS_HANDLE MiniportAdapterContext
)
{
// Context is actually our adapter
PD100_ADAPTER Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
USHORT LNK;
USHORT rdata;
ULONG TSR_STATUS;
rdata = Adapter->IsrReg;
//NdisAllocateSpinLock (&Adapter->Lock);
while(rdata)
{
if(rdata & BIT1)
{
//KdPrint(("Receive Successful\n"));
ProcessRXInterrupt(Adapter);
}
if(rdata & BIT2) //RER IS SET
KdPrint(("Receive Unsuccessful\n"));
if(rdata & BIT3)
{
//KdPrint(("********TOK********"));
while(Adapter->NoPackets)
{
NdisReadRegisterUlong((PULONG)(Adapter->CSRAddress+TSD0+ Adapter->ReadDesc*4),&TSR_STATUS);
//if(TSR_STATUS & 0x0000A000)
{
Adapter->GoodTransmits++;
//KdPrint(("Adapter->Packet:%X",Adapter->Packet));
//KdPrint(("Total Packets Transmitted : %d\n", Adapter->ReadDesc));
//KdPrint(("TxREAD_DESC : %d",Adapter->ReadDesc));
NdisMSendComplete(Adapter->D100AdapterHandle,
Adapter->Packet[Adapter->ReadDesc],
NDIS_STATUS_SUCCESS);
Adapter->ReadDesc=(Adapter->ReadDesc+1) % NUM_OF_TRANS_DESC;
//KdPrint(("PACKETS COMPLETED : %d ",Adapter->NoPackets));
Adapter->NoPackets--;
KdPrint(("______TRANSMISSION IS SUCCESS_____"));
}
}
}
if(rdata & BIT4)
{
//KdPrint(("Transmission Error"));
while(Adapter->NoPackets)
{
Adapter->Trans_Error++;
NdisMSendComplete(
Adapter->D100AdapterHandle,
Adapter->Packet[Adapter->ReadDesc],
NDIS_STATUS_FAILURE);
Adapter->NoPackets--;
}
}
if(rdata & BIT5)
KdPrint(("Receive buffer overflow\n"));
if(rdata & BIT6)
{
//KdPrint(("LINK STATUS CHANGED"));
NdisReadRegisterUshort((PUSHORT) (Adapter->CSRAddress +BMSR),&LNK);
if (LNK & BIT3)
{
//KdPrint(("***VALID LINK ESTABLISHED***"));
NdisMIndicateStatus(Adapter->D100AdapterHandle,
NDIS_STATUS_MEDIA_CONNECT,
(PVOID)0,
0);
}
else
{
//KdPrint(("*** LINK FAILURE **"));
NdisMIndicateStatus(Adapter->D100AdapterHandle,
NDIS_STATUS_MEDIA_DISCONNECT,
(PVOID)0,
0);
}
}
if(rdata & BIT7)
KdPrint(("receive fifo overflow\n"));
NdisReadRegisterUshort((PUSHORT)(Adapter->CSRAddress+ISR),&Adapter->IsrReg);
NdisWriteRegisterUshort((PUSHORT)(Adapter->CSRAddress+ISR),Adapter->IsrReg);
rdata=Adapter->IsrReg;
//KdPrint(("isr:=%x\n",rdata));
}
//NdisReleaseSpinLock(&Adapter->Lock);
D100EnableInterrupt(Adapter);
//KdPrint(("we r exiting InterruptHandle\n"));
}
/*********************************************************************************
-------------------------TRANSMISSION---------------------------------------------
**********************************************************************************/
NDIS_STATUS D100Send(IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet,
IN UINT Flags )
{
PD100_ADAPTER Adapter;
PNDIS_BUFFER FirstBuffer;
UINT TotalPacketLength;
UINT PhysicalBufferCount;
UINT BufferCount;
ULONG TSR_STATUS;
UINT BytesCopied;
Adapter = (PD100_ADAPTER) MiniportAdapterContext;
Adapter->Packet[Adapter->WriteDesc] = Packet;
//KdPrint(("_________________________________________\n"));
//KdPrint(("------------I AM IN TRANSMIT-------------"));
//KdPrint(("_________________________________________"));
//****CHECK IF ANY TRANSMIT DESCRIPTOR IS AVAILABLE
if (Adapter->NoPackets >= NUM_OF_TRANS_DESC)
{
//KdPrint(("****** TSAD UNAVAILABLE *****"));
NDIS_SET_PACKET_STATUS(Packet,NDIS_STATUS_RESOURCES );
return NDIS_STATUS_RESOURCES ;
}
else
{
NdisQueryPacket(Packet, //* Returns
&PhysicalBufferCount , //* Information
&BufferCount, //* About a Given
&FirstBuffer, //* Packet
&TotalPacketLength);
if(TotalPacketLength < 64)//** MIN. PACKET LENGTH
TotalPacketLength=64; //** SHOULD BE 64
if(TotalPacketLength > MAXIMUM_ETHERNET_PACKET_SIZE)
{
NDIS_SET_PACKET_STATUS(Packet,NDIS_STATUS_FAILURE );
return NDIS_STATUS_FAILURE;
}
//KdPrint(("BUFFER COUNT :%X",BufferCount));
//KdPrint(("PACKET SIZE :%X",TotalPacketLength));
//KdPrint(("FIRST BUFFER :%X",FirstBuffer));
//*** THIS ROUTINE COPIES A PACKET TO THE TRANSMIT BUFFER
CopyPacketToTransmitBuffer(TotalPacketLength,
(PCHAR)Adapter->TransUnCached[Adapter->WriteDesc],
FirstBuffer,
&BytesCopied );
Adapter->NoPackets++;
//KdPrint(("PACKET NO:%d",Adapter->NoPackets));
NdisReadRegisterUlong((PULONG)(Adapter->CSRAddress+TSD0+Adapter->WriteDesc * 4),&TSR_STATUS);
//KdPrint(("TSR BEFORE UPDATION : %X",TSR_STATUS));
TSR_STATUS &= 0xFFFFE000; //*** CLEARS THE PACKET DESC FIELD
TSR_STATUS |= TotalPacketLength;//*** SETS PACKET LENGTH DESC
TSR_STATUS |= 0x00200000; //***EARLY THRESHOLD
TSR_STATUS &= 0xFFFFDFFF; //***CLEARS OWN BIT
//*** UPDATING THE TRASMIT STATUS REGISTER
NdisWriteRegisterUlong((PULONG)(Adapter->CSRAddress+TSD0 +Adapter->WriteDesc* 4),TSR_STATUS);
Adapter->WriteDesc=(Adapter->WriteDesc+1)% NUM_OF_TRANS_DESC;
//KdPrint(("TxWRITE_DESC :%d",Adapter->WriteDesc));
NdisReadRegisterUlong((PULONG)(Adapter->CSRAddress+TSD0+ Adapter->WriteDesc*4),&TSR_STATUS);
//KdPrint(("TSR AFTER UPDATATION : %X",TSR_STATUS));
}
NDIS_SET_PACKET_STATUS(Packet,NDIS_STATUS_PENDING);
return NDIS_STATUS_PENDING;
}
//-----------------------------------------------------------------------------
// Procedure: D100CheckForHang
//
// Description: This routine should check to see if the adapter is "hung", and
// fix it if it is. Right now this routine does not check for a
// hang, because the adapter should never "timeout". In the
// future, this is where the code to check for a timeout would go,
// if there were bugs in the chipset that could cause transmit
// "timeouts".
//-----------------------------------------------------------------------------
BOOLEAN D100CheckForHang(NDIS_HANDLE MiniportAdapterContext)
{
PD100_ADAPTER Adapter;
UCHAR read;
//KdPrint(("********In CheckForHang************\n"));
Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
// this is the implementation of the NDIS 4 feature for detecting
// link status change. It effectively checks every two seconds
// for link.
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress +MSR),&read ) ;
if(read & 4)
{
Adapter->LinkIsActive = NdisMediaStateDisconnected;
NdisMIndicateStatus(Adapter->D100AdapterHandle,
NDIS_STATUS_MEDIA_DISCONNECT,
(PVOID)0,
0);
//KdPrint(("~~~NETWORK CABLE STATUS UNPLUGGED~~~"));
}
else
{
Adapter->LinkIsActive = NdisMediaStateConnected;
NdisMIndicateStatus(Adapter->D100AdapterHandle,
NDIS_STATUS_MEDIA_CONNECT,
(PVOID)0,
0);
//KdPrint(("^^^^^NETWORK CABLE STATUS CONNECTED^^^^^"));
}
// have to indicate status complete every time you indicate status
NdisMIndicateStatusComplete(Adapter->D100AdapterHandle);
// return false to indicate that the adapter is not hung, and that
// D100Reset does NOT need to be called by the wrapper
return(FALSE) ;
}
/// ==================================================================
/// -------------------RESET-----------------------------------------
///INSTRUCTS THE MINIPORT TO ISSUE A HARDWARE RESET TO THE
// NETWORK ADAPTER. THE DRIVER ALSO RESETS ITS SOFTWARE STATE.
// THIS FUNCTION ALSO RESETS THE TRANSMIT QUEUES.
//---------------------------------------------------------------
///==================================================================
NDIS_STATUS
D100Reset(PBOOLEAN AddressingReset,
NDIS_HANDLE MiniportAdapterContext)
{
PD100_ADAPTER Adapter;
/* UCHAR commandReg;
ULONG transConfReg;
ULONG recvConfReg;
*/
//KdPrint(("*** InReset ***"));
Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
///***NDIS LIBRARY SHOULD CALL MINIPORTSETINFORMATION
///***TO RESTORE ADDRESSING INFORMATION TO THE CURRENT VALUES.
*AddressingReset = TRUE;
D100DisableInterrupt(Adapter);////***DISABLES THE INTERRUPT
Adapter->IsrReg=0;
///**** WE WILL COMPLETE ALL SENDS THAT WE HAVE LEFT RIGHT NOW.
while(Adapter->NoPackets > 0)
{
NdisMSendComplete(Adapter->D100AdapterHandle,
Adapter->Packet[Adapter->ReadDesc],
NDIS_STATUS_SUCCESS);
Adapter->ReadDesc=(Adapter->ReadDesc+1) % NUM_OF_TRANS_DESC;
Adapter->NoPackets--;
}
ResetPhy(Adapter); //// RESETTING COMMAND REGISTER
AutoNegotiate(Adapter); //// RE INITIALIZE AUTONEGOTIATION
DeleteSharedMemoryAdapter(Adapter);
SetupRecvQ(Adapter); //// RE-INITIALIZE RECEIVE QUEUES
SetupTransQ(Adapter); //// RE-INITIALIZE TRANSMIT QUEUES
/* NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ),&commandReg ) ;
//KdPrint(("Command Reg Before Transmit Enable = %X\n",commandReg ));
commandReg |= TRANS_ENABLE ;
NdisWriteRegisterUchar( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), commandReg ) ;
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), &commandReg ) ;
//KdPrint(("Command Reg After Transmit Enable = %X\n\n",commandReg ));
// Set Transmit Configuration register
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + TRANS_CONFIG_REG ),&transConfReg ) ;
//KdPrint(("Transmit Configuration Reg Before Enable = %X\n",transConfReg ));
transConfReg &=0;
transConfReg |= TCR_ENABLE;
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + TRANS_CONFIG_REG ), transConfReg ) ;
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + TRANS_CONFIG_REG ), &transConfReg ) ;
//KdPrint(("Transmit Configuration Reg After Enable = %X\n\n",transConfReg ));
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ),&commandReg ) ;
//KdPrint(("Command Reg Before Receive Enable = %X\n",commandReg));
commandReg |= RECV_ENABLE ;
NdisWriteRegisterUchar( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), commandReg ) ;
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG ), &commandReg ) ;
// Read the status of the Command Register
NdisReadRegisterUchar ( (PUCHAR)(Adapter->CSRAddress + CMND_REG),&commandReg ) ;
//KdPrint(("Command Reg After Receive Enable = %X\n\n",commandReg));
// Set Receive Configuration register
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + RECV_CONFIG_REG ),&recvConfReg ) ;
//KdPrint(("Receive Configuration Reg Before Enable = %X\n",recvConfReg ));
recvConfReg |= RCR_ENABLE ;
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + RECV_CONFIG_REG ), recvConfReg ) ;
NdisReadRegisterUlong ( (PULONG)(Adapter->CSRAddress + RECV_CONFIG_REG ), &recvConfReg ) ;
//KdPrint(("Receive Configuration Reg After Enable = %X\n\n",recvConfReg ));
// Set Receive Buffer start register
NdisWriteRegisterUlong( (PULONG)(Adapter->CSRAddress + RBSTART ), Adapter->RecvUnCachedPhys.LowPart ) ;
Adapter->WriteDesc=0;
Adapter->ReadDesc=0;
Adapter->NoPackets=0;
*/
///****NOTIFIES NDIS THAT AN ETHERNET RECEIVE PACKET,
//***IDENTIFIED IN A PRECEDING CALL TO NdisMEthIndicateReceive,
//**HAS BEEN FULLY TRANSFERRED BY THE NIC SO THAT NDIS CAN NOTIFY
//**THE APPROPRIATE BOUND PROTOCOLS.
NdisMEthIndicateReceiveComplete(Adapter->D100AdapterHandle);
//***NdisMResetComplete RETURNS THE FINAL STATUS OF A RESET REQUEST
//**FOR WITH THE NIC DRIVER PREVIOUSLY RETURNED NDIS_STATUS_PENDING.
NdisMResetComplete(Adapter->D100AdapterHandle,
(NDIS_STATUS) NDIS_STATUS_SUCCESS,
FALSE);
return NDIS_STATUS_SUCCESS;
}
///=============================================================================
//-----------COPIES ONE PACKET TO THE TRANSMIT BUFFER-------------------
//======================================================================
VOID CopyPacketToTransmitBuffer( UINT BytesToCopy,
PCHAR DestBuffer,
PNDIS_BUFFER FirstBuffer,
PUINT BytesCopied )
{PNDIS_BUFFER CurrentBuffer;
PVOID VirtualAddress;
UINT CurrentLength;
UINT AmountToMove;
*BytesCopied = 0;
if (!BytesToCopy)
return;
CurrentBuffer = FirstBuffer;
NdisQueryBuffer(
CurrentBuffer,
&VirtualAddress,
&CurrentLength);
while (BytesToCopy)
{
while (!CurrentLength)
{
NdisGetNextBuffer(
CurrentBuffer,
&CurrentBuffer);
// If we've reached the end of the packet. We return with what
// we've done so far (which must be shorter than requested).
if (!CurrentBuffer)
return;
NdisQueryBuffer(
CurrentBuffer,
&VirtualAddress,
&CurrentLength);
}
// Compute how much data to move from this fragment
if (CurrentLength > BytesToCopy)
AmountToMove = BytesToCopy;
else
AmountToMove = CurrentLength;
// Copy the data.
NdisMoveMemory(
DestBuffer,
VirtualAddress,
AmountToMove);
// Update destination pointer
DestBuffer = (PCHAR) DestBuffer + AmountToMove;
// Update counters
*BytesCopied += AmountToMove;
BytesToCopy -= AmountToMove;
CurrentLength = 0;
}
}
//==========================================================================
//--------------Process Receive Interrupt-----------------------------------
//===========================================================================
VOID ProcessRXInterrupt(IN PD100_ADAPTER Adapter)
{
NDIS_STATUS Status;
//USHORT CAPR_REG;
//USHORT CBR_REG;
USHORT ReadPtr;
UCHAR COMMANDREG;
NdisReadRegisterUchar((PUCHAR)(Adapter->CSRAddress+CMND_REG),&COMMANDREG);
while(!(COMMANDREG & BUFE))
{
NdisReadRegisterUshort((PUSHORT)(Adapter->CSRAddress+CBR),&ReadPtr);
//KdPrint((" CBR(Write Pointer) := %x(HEX)\n",ReadPtr));
//***** THE FIRST TWO BYTES CONTAINING THE STATUS OF THE PACKET
ReadPtr = *((PUSHORT)(Adapter->RecvUnCached + Adapter->RHead));
//KdPrint(("PACKET STATUS :=%x\n",ReadPtr));
if(ReadPtr & (Rx_FAE|Rx_CRC|Rx_LONG|Rx_RUNT|Rx_ISE))
{
//KdPrint(("******* RECEIVE PACKET ERROR *****"));
return;
}
//***** IF GOOD PACKET IS RECEIVED
if (ReadPtr & Rx_ROK)
{
//KdPrint(("GOOD PACKET IS RECEIVED "));
Adapter->GoodReceives++;
NdisAllocatePacket( &Status,
&Adapter->RxPacketDesc,
Adapter->RxPacketPoolHandle );
if(Status != NDIS_STATUS_SUCCESS)
{
KdPrint(("**** PACKET ALLOCATION FAILED ****"));
return;
}
//****** THE NEXT TWO BYTES CONTAINING THE LENGTH OF THE PACKET
Adapter->PacketLength=*((PUSHORT)(Adapter->RecvUnCached+Adapter->RHead+2));
NdisAllocateBuffer(
&Status,
&Adapter->RxBufferDesc,
Adapter->RxBufferPoolHandle,
(PVOID)(Adapter->RecvUnCached+Adapter->RHead+4),//STARTING VIRTUAL ADDRESS
Adapter->PacketLength-4 ); // EXCLUDING CRC
if(Status != NDIS_STATUS_SUCCESS)
{
KdPrint(("**** BUFFER ALLOCATION FAILED ****"));
return;
}
Adapter->RHead=((Adapter->PacketLength+Adapter->RHead+4+3) &(~(0x03))) % (64*1024);
//4:FOR HEADER LENGTH(PKTLENGTH INCLUDE 4 BYTES CRC)
//3:FOR DWORD ALIGNMENT
NdisReadRegisterUshort((PUSHORT)(Adapter->CSRAddress+CAPR),
&ReadPtr);
//KdPrint(("CAPR BEFORE UPDATE :%X",ReadPtr));
ReadPtr=(Adapter->RHead-0x10);///** 4 AVOID OVERFLOW;
NdisWriteRegisterUshort((PUSHORT)(Adapter->CSRAddress+CAPR),
ReadPtr);
NdisReadRegisterUshort((PUSHORT)(Adapter->CSRAddress+CAPR),
&ReadPtr);
//KdPrint(("CAPR AFTER UPDATE :%X",ReadPtr));
NdisReadRegisterUshort((PUSHORT)(Adapter->CSRAddress+CBR),
&ReadPtr);
//KdPrint(("CBR :%X",ReadPtr));
///****SETS THE HEADER SIZE VALUE IN THE OOB DATA BLOCK ASSOCIATED WITH A
//***GIVEN PACKET DESCRIPTOR FOR A SUBSEQUENT RECEIVE INDICATION
NDIS_SET_PACKET_HEADER_SIZE(Adapter->RxPacketDesc,ENET_HEADER_SIZE);
//**** SETS THE PACKET STATUS IN THE OOB DATA BLOCK
NDIS_SET_PACKET_STATUS(Adapter->RxPacketDesc,NDIS_STATUS_SUCCESS);
//NDIS_SET_PACKET_STATUS(Adapter->RxPacketDesc,NDIS_STATUS_RESOURCES);
///**** LINKS THE GIVEN BUFFER DESCRIPTOR AT THE TAIL
//*** OF THE CHAIN FOR THE GIVEN PACKET.
NdisChainBufferAtFront(Adapter->RxPacketDesc,Adapter->RxBufferDesc);
///**** NOTIFIES NDIS THAT RECEIVED PACKET IS AVAILABLE
///**** TO BE FORWARDED TO THE APPROPRIATE BOUND PROTOCOL DRIVER(S).
NdisMIndicateReceivePacket(Adapter->D100AdapterHandle,
&Adapter->RxPacketDesc , 1 );
//NdisStallExecution(100);
NdisReadRegisterUchar((PUCHAR)(Adapter->CSRAddress+CMND_REG),&COMMANDREG);
}
}
return ;
}
//---------------------------------------------------------------------------
// D100ReturnPacket
// DESCRIPTION: This function attempts to return to the receive free list the
// packet passed to us by NDIS
//----------------------------------------------------------------------------
VOID D100ReturnPacket(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet
)
{
PD100_ADAPTER Adapter = (PD100_ADAPTER) MiniportAdapterContext;
//KdPrint(("\n\n*****************D100ReturnPacket****************\n"));
/*if(Adapter->Status==NDIS_STATUS_PENDING)
{
NDIS_SET_PACKET_STATUS(Adapter->RxPacketDesc,NDIS_STATUS_SUCCESS);
NdisMIndicateReceivePacket(Adapter->D100AdapterHandle,
&Adapter->RxPacketDesc , 1 );
NdisUnchainBufferAtFront(Adapter->RxPacketDesc,&Adapter->RxBufferDesc);
}*/
NdisFreeBuffer(Adapter->RxBufferDesc);
NdisFreePacket(Adapter->RxPacketDesc);
return;
}
//-----------------------------------------------------------------------------
// Procedure: D100Halt
//
// Description: Removes an adapter instance that was previously initialized.
// To "halt" or "remove" an adapter, we disable its interrupt,
// abort its receive unit (otherwise it would continue to DMA in
// data), and release all of the resources (memory, i/o space,
// etc.) that the adapter instance was using.
// This routine is only called when the adapter is "stopped"
// or unloaded with a "net stop e100b". To see what is called
// at machine shutdown see D100ShutdownHandler.
//-----------------------------------------------------------------------------
VOID D100Halt(NDIS_HANDLE MiniportAdapterContext)
{
PD100_ADAPTER Adapter;
//KdPrint(("****D100Halt***"));
Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
// Disable the device's interrupt line.
D100DisableInterrupt(Adapter);
while(Adapter->NoPackets > 0)
{
NdisMSendComplete(Adapter->D100AdapterHandle,
Adapter->Packet[Adapter->ReadDesc],
NDIS_STATUS_SUCCESS);
Adapter->ReadDesc=(Adapter->ReadDesc+1) % NUM_OF_TRANS_DESC;
Adapter->NoPackets--;
}
NdisMDeregisterInterrupt(&Adapter->Interrupt);
//KdPrint((" After DeRegistering the interrupt"));
ResetPhy(Adapter);
DeleteAllAllocatedMemory(Adapter);
}
//-----------------------------------------------------------------------------
// Procedure: D100ShutdownHandler
//
// Description: Removes an adapter instance that was previously initialized.
// To Shutdown simply Disable interrupts and Stop the receive unit.
// Since the system is shutting down there is no need to release
// resources (memory, i/o space, etc.) that the adapter instance
// was using.
//
// Arguments:
// MiniportAdapterContext - pointer to the adapter object data area.
//
// Returns: (none)
//-----------------------------------------------------------------------------
/*VOID
D100ShutdownHandler(NDIS_HANDLE MiniportAdapterContext)
{
PD100_ADAPTER Adapter;
//KdPrint(("D100ShutdownHandler"));
Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
// Disable the device's interrupt line.
D100DisableInterrupt(Adapter);
//D100StallExecution(30);
// Reset the PHY chip. We do this so that after a warm boot, the PHY will
// be in a known state, with auto-negotiation enabled.
ResetPhy(Adapter);
}*/
VOID D100StallExecution( IN UINT MsecDelay)
{
// Delay in 100 usec increments
MsecDelay *= 10;
while (MsecDelay)
{
NdisStallExecution(100);
MsecDelay--;
}
}
VOID InitializePower(IN PD100_ADAPTER Adapter)
{
UCHAR Read;
//UNLOCK....
#ifdef __PM__
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+CMREG93C56,&Read);
Read|=0xc0;
NdisWriteRegisterUchar((PUCHAR)Adapter->CSRAddress+CMREG93C56,Read);
//PME Config1
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG1,&Read);
//KdPrint(("%%%% CNFG1=%x\n",Read));
Read|=0x31;
NdisWriteRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG1,Read);
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG1,&Read);
//KdPrint(("%%%% CNFG1=%x\n",Read));
//Disable Magic Packet Config 3
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG3,&Read);
KdPrint(("%%%% CNFG3=%x\n",Read));
#ifdef __LINK_WAKE_UP__ //Not Proper
Read &=0xdf;//Linkup
Read |=0x10;
#endif
/*#ifdef __MAGIC_WAKE_UP__
Read &=0xef;
Read |=0x20;
#endif*/
NdisWriteRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG3,Read);
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG3,&Read);
KdPrint(("%%%% CNFG3=%x\n",Read));
//LANWAKE vs PMEB Packet Config 4
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG4,&Read);
//KdPrint(("%%%% CNFG4=%x\n",Read));
Read&=0x9F;
NdisWriteRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG4,Read);
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG4,&Read);
//KdPrint(("%%%% CNFG4=%x\n",Read));
//LANWAKE... Config5
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG5,&Read);
//KdPrint(("%%%% CNFG5=%x\n",Read));
Read|=0x42;
Read&=0xFB;
NdisWriteRegisterUchar((PUCHAR)Adapter->CSRAddress+CONFIG5,Read);
NdisReadRegisterUchar((PUCHAR)Adapter->CSRAddress+0xd8,&Read);
//KdPrint(("%%%% CNFG5=%x\n",Read));
#endif
}
NDIS_STATUS
D100ChangeMCAddresses(
IN PD100_ADAPTER Adapter,
IN UINT AddressCount
)
{
// Holds the change that should be returned to the filtering package.
PUCHAR McAddress;
UINT i, j;
NDIS_STATUS Status;
KdPrint(("CHANGE MC ADDRESS"));
// Setup the command block for the multicast command.
for (i = 0;(i < AddressCount) && (i < MAX_MULTICAST_ADDRESSES);i++)
{
McAddress = &Adapter->NonTxCmdBlock->Multicast.McAddress[i*ETHERNET_ADDRESS_LENGTH];
for (j = 0; j < ETH_LENGTH_OF_ADDRESS; j++)
*(McAddress++) = Adapter->PrivateMulticastBuffer[i][j];
}
Adapter -> NonTxCmdBlock ->Multicast.McCount =
(USHORT) (AddressCount * ETH_LENGTH_OF_ADDRESS);
Adapter->NonTxCmdBlockHdr->CbStatus = 0;
Adapter->NonTxCmdBlockHdr->CbCommand = 3;
Status = (NDIS_STATUS_SUCCESS);
KdPrint(("***END***"));
return(Status);
}
0 nhận xét:
Đăng nhận xét