📄 ax88172.c
字号:
&NextDeviceObject,
&AllocatedResources,
&AllocatedResourcesTranslated
);
USBD_GetUSBDIVersion( &UsbVersionInfo );
if ( (UsbVersionInfo.USBDI_Version < AcceptedUSBDIVersion) ||
(UsbVersionInfo.Supported_USB_Version < AcceptedUSBVersion) )
return NDIS_STATUS_NOT_SUPPORTED;
siz = sizeof(USB_CONFIGURATION_DESCRIPTOR) +128;
while (TRUE)
{
Adapter->UsbConfigurationDescriptor =
ExAllocatePool(
NonPagedPool,
siz
);
UsbBuildGetDescriptorRequest(
&Urb,
(USHORT) sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_CONFIGURATION_DESCRIPTOR_TYPE,
0,
0,
Adapter->UsbConfigurationDescriptor,
NULL,
siz,
NULL
);
if ( !NT_SUCCESS(BulkUsb_CallUSBD(Adapter, &Urb)) )
return NDIS_STATUS_HARD_ERRORS;
if (Urb.UrbControlDescriptorRequest.TransferBufferLength > 0 &&
Adapter->UsbConfigurationDescriptor->wTotalLength > siz)
{
siz = Adapter->UsbConfigurationDescriptor->wTotalLength;
ExFreePool(Adapter->UsbConfigurationDescriptor);
Adapter->UsbConfigurationDescriptor = NULL;
}
else
break; // we got it!
}
i = Adapter->UsbConfigurationDescriptor->bNumInterfaces;
tmp = interfaceList = ExAllocatePool(
NonPagedPool,
sizeof(USBD_INTERFACE_LIST_ENTRY)*(i+1)
);
for ( i=0; i<Adapter->UsbConfigurationDescriptor->bNumInterfaces; i++ )
{
// Get the next matching descriptor. Here we implicitly use
// the fact that the interface descriptors are laid out in order in memory.
UsbInterfaceDescriptor =
USBD_ParseConfigurationDescriptorEx(
Adapter->UsbConfigurationDescriptor,
Adapter->UsbConfigurationDescriptor,
i, // interface number
-1, // alternate setting
-1,
-1,
-1
);
interfaceList->InterfaceDescriptor = UsbInterfaceDescriptor;
interfaceList++;
}
interfaceList->InterfaceDescriptor = NULL;
pUrb = USBD_CreateConfigurationRequestEx(
Adapter->UsbConfigurationDescriptor,
tmp
);
ExFreePool(tmp);
if (!pUrb)
return NDIS_STATUS_ADAPTER_NOT_FOUND;
Adapter->UsbConfigurationHandle = pUrb->UrbSelectConfiguration.ConfigurationHandle;
UsbInterface = &pUrb->UrbSelectConfiguration.Interface;
if ( !NT_SUCCESS(BulkUsb_CallUSBD(Adapter, pUrb)) )
{
ExFreePool(pUrb);
return NDIS_STATUS_HARD_ERRORS;
}
for (i=0; i< UsbInterface->NumberOfPipes; i++)
{
PUSBD_PIPE_INFORMATION PipeInfo = &UsbInterface->Pipes[i];
switch (PipeInfo->PipeType)
{
case UsbdPipeTypeBulk:
Adapter->MaximumPacketSize = PipeInfo->MaximumPacketSize;
if (PipeInfo->EndpointAddress & 0x80)
Adapter->ReceivePipe = PipeInfo->PipeHandle;
else
Adapter->TransmitPipe = PipeInfo->PipeHandle;
break;
case UsbdPipeTypeInterrupt:
Adapter->InterruptPipe = PipeInfo->PipeHandle;
break;
default:
break;
}
}
ExFreePool(pUrb);
UsbBuildVendorRequest(
&Urb,
URB_FUNCTION_VENDOR_DEVICE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_TRANSFER_DIRECTION_IN |USBD_SHORT_TRANSFER_OK,
0,
0x1c,
0,
0,
MiiData,
NULL,
1,
NULL
);
BulkUsb_CallUSBD(Adapter, &Urb);
Adapter->ChipVersion = MiiData[0];
//Read SROM - MiiPhy Address (ID)
UsbBuildVendorRequest(
&Urb,
URB_FUNCTION_VENDOR_DEVICE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_TRANSFER_DIRECTION_IN |USBD_SHORT_TRANSFER_OK,
0,
25,
0,
0,
MiiData,
NULL,
2,
NULL
);
BulkUsb_CallUSBD(Adapter, &Urb);
Adapter->SecondaryPhy = MiiData[0]&0x1f;
Adapter->SecondaryPhyType = (MiiData[0]>>5)&7;
Adapter->PrimaryPhy = MiiData[1]&0x1f;
Adapter->PrimaryPhyType = (MiiData[1]>>5)&7;
//Read Multicast Filtering Array
UsbBuildVendorRequest(
&Urb,
URB_FUNCTION_VENDOR_DEVICE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_TRANSFER_DIRECTION_IN |USBD_SHORT_TRANSFER_OK,
0,
0x15,
0,
0,
Adapter->mcFilter,
NULL,
8,
NULL
);
BulkUsb_CallUSBD(Adapter, &Urb);
///
// PHY Connection Type Setup!
///
PhyInitial( Adapter );
//
// Initialize the receive variables.
Adapter->PendingInterrupt.Adapter = Adapter;
Adapter->PendingTransmit.Adapter = Adapter;
Adapter->PendingReceive.Adapter = Adapter;
///
// USB Initialize!
///
///
// Reads in the Ethernet address from the ASIX AX88172.
// The address is stored in Adapter->PermanentAddress,
// and StationAddress if it is currently zero.
///
UsbBuildVendorRequest(
&Urb,
URB_FUNCTION_VENDOR_DEVICE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_TRANSFER_DIRECTION_IN |USBD_SHORT_TRANSFER_OK,
0,
0x17,
0,
0,
&Adapter->PermanentAddress[0],
NULL,
6,
NULL
);
BulkUsb_CallUSBD(Adapter, &Urb);
//
// Use the burned in address as the station address, unless the
// registry specified an override value.
if ( (Adapter->StationAddress[0] |Adapter->StationAddress[1]
|Adapter->StationAddress[2] |Adapter->StationAddress[3]
|Adapter->StationAddress[4] |Adapter->StationAddress[5]) == 0 )
{
NdisMoveMemory(
Adapter->StationAddress,
Adapter->PermanentAddress,
AX88172_LENGTH_OF_ADDRESS
);
}
return NDIS_STATUS_SUCCESS;
}
#pragma NDIS_PAGEABLE_FUNCTION(AX88172Initialize)
//extern
NDIS_STATUS
AX88172Initialize(
OUT PNDIS_STATUS OpenErrorStatus,
OUT PUINT SelectedMediumIndex,
IN PNDIS_MEDIUM MediumArray,
IN UINT MediumArraySize,
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_HANDLE ConfigurationHandle
)
/*++
Routine Description:
AX88172Initialize starts an adapter and registers resources with the
wrapper.
Arguments:
OpenErrorStatus - Extra status bytes for opening token ring adapters.
SelectedMediumIndex - Index of the media type chosen by the driver.
MediumArray - Array of media types for the driver to chose from.
MediumArraySize - Number of entries in the array.
MiniportAdapterHandle - Handle for passing to the wrapper when
referring to this adapter.
ConfigurationHandle - A handle to pass to NdisOpenConfiguration.
Return Value:
NDIS_STATUS_SUCCESS
NDIS_STATUS_PENDING
--*/
{
//
// Temporary looping variable.
UINT i;
//
// Status of Ndis calls.
NDIS_STATUS Status;
//
// Pointer to our newly allocated adapter.
PAX_ADAPTER Adapter;
//
// The handle for reading from the registry.
NDIS_HANDLE ConfigHandle;
//
// The value read from the registry.
PNDIS_CONFIGURATION_PARAMETER ReturnedValue;
//
// String names of all the parameters that will be read.
NDIS_STRING ConnectionTypeStr = NDIS_STRING_CONST("ConnectionType");
NDIS_STRING RemoteWakeupStr = NDIS_STRING_CONST("RemoteWakeup");
NDIS_STRING FlowControlStr = NDIS_STRING_CONST("FlowControl");
NDIS_STRING PhoneLineStr = NDIS_STRING_CONST("PhoneLine");
//
// Search for the medium type (802.3) in the given array.
for (i = 0; i < MediumArraySize; i++)
if (MediumArray[i] == NdisMedium802_3)
break;
if (i == MediumArraySize)
return NDIS_STATUS_UNSUPPORTED_MEDIA;
*SelectedMediumIndex = i;
//
// Allocate memory for the adapter block now.
Status =
NdisAllocateMemoryWithTag(
(PVOID *)&Adapter,
sizeof(struct _AX_ADAPTER),
'ASIX'
);
if (Status != NDIS_STATUS_SUCCESS)
return Status;
//
// Clear out the adapter block,
// which sets all default values to FALSE or NULL.
NdisZeroMemory (Adapter, sizeof(struct _AX_ADAPTER));
//
// Open the configuration space.
NdisOpenConfiguration(
&Status,
&ConfigHandle,
ConfigurationHandle
);
if (Status == NDIS_STATUS_SUCCESS)
{
//
// connection type.
NdisReadConfiguration(
&Status,
&ReturnedValue,
ConfigHandle,
&ConnectionTypeStr,
NdisParameterInteger
);
if (Status == NDIS_STATUS_SUCCESS)
Adapter->uConnectionType = (UINT)ReturnedValue->ParameterData.IntegerData;
//
// remote wakeup.
NdisReadConfiguration(
&Status,
&ReturnedValue,
ConfigHandle,
&RemoteWakeupStr,
NdisParameterInteger
);
if (Status == NDIS_STATUS_SUCCESS)
Adapter->uRemoteWakeup = (USHORT)ReturnedValue->ParameterData.IntegerData & 0x000e;
//
// flow control.
NdisReadConfiguration(
&Status,
&ReturnedValue,
ConfigHandle,
&FlowControlStr,
NdisParameterHexInteger
);
if (Status == NDIS_STATUS_SUCCESS)
Adapter->FlowControl = ReturnedValue->ParameterData.IntegerData? TRUE:FALSE;
//
// phone line configure.
NdisReadConfiguration(
&Status,
&ReturnedValue,
ConfigHandle,
&PhoneLineStr,
NdisParameterHexInteger
);
if (Status == NDIS_STATUS_SUCCESS)
Adapter->uPhoneLine = ((USHORT)ReturnedValue->ParameterData.IntegerData &6) |0x0040;
else
Adapter->uPhoneLine = 0x0044;
//
// Close the configuration space.
NdisCloseConfiguration(ConfigHandle);
}
//
// Now to use this information and register with the wrapper
// and initialize the adapter.
//
//
// Inform the wrapper of the physical attributes of this adapter.
NdisMSetAttributesEx(
MiniportAdapterHandle,
(NDIS_HANDLE)Adapter,
2,
NDIS_ATTRIBUTE_DESERIALIZE,
NdisInterfacePci
);
Adapter->MiniportAdapterHandle = MiniportAdapterHandle;
//
// Set up the parameters.
Adapter->MaxLookAhead = AX88172_MAX_LOOKAHEAD;
Adapter->FixedPhy = TRUE;
switch (Adapter->uConnectionType)
{
case 2:
Adapter->uConnectionType = MiiPhyNway10BaseT
|MiiPhyExtendedCapabilities;
break;
case 3:
Adapter->uConnectionType = MiiPhyNway10BaseT
|MiiPhyNway10BaseTFD
|MiiPhyNwayPauseEnable
|MiiPhyExtendedCapabilities;
break;
case 8:
Adapter->uConnectionType = MiiPhyNway10BaseT
|MiiPhyNway10BaseTFD
|MiiPhyNway100BaseTx
|MiiPhyExtendedCapabilities;
break;
default:
switch (Adapter->uConnectionType)
{
case 102:
case 108:
Adapter->PhoneNetworkMedia = TRUE;
Adapter->uConnectionType -= 100;
break;
default:
Adapter->uConnectionType = 0;
break;
}
if ( Adapter->uConnectionType )
break;
case 0:
Adapter->FixedPhy = FALSE;
case 9:
Adapter->uConnectionType = MiiPhyNway10BaseT
|MiiPhyNway10BaseTFD
|MiiPhyNway100BaseTx
|MiiPhyNway100BaseTxFD
|MiiPhyNwayPauseEnable
|MiiPhyExtendedCapabilities;
break;
}
Status = AX88172RegisterAdapter( Adapter );
if ( Adapter->UsbConfigurationDescriptor )
{
if ( ~Adapter->UsbConfigurationDescriptor->bmAttributes&0x20 )
Adapter->uRemoteWakeup = 0;
ExFreePool(Adapter->UsbConfigurationDescriptor);
}
if (Status != NDIS_STATUS_SUCCESS)
{
NdisFreeMemory(
Adapter,
sizeof(struct _AX_ADAPTER),
0
);
return Status;
}
Adapter->NextAdapter = AX88172MiniportBlock.AdapterQueue;
AX88172MiniportBlock.AdapterQueue = Adapter;
NdisMInitializeTimer(
&Adapter->ReceiveTimer,
MiniportAdapterHandle,
(PNDIS_TIMER_FUNCTION)&AXWaitReceive,
(PVOID)Adapter
);
NdisMInitializeTimer(
&Adapter->ReceiveHandleTimer,
MiniportAdapterHandle,
(PNDIS_TIMER_FUNCTION)&AXReceiveHandler,
(PVOID)Adapter
);
NdisMInitializeTimer(
&Adapter->TransmitTimer,
MiniportAdapterHandle,
(PNDIS_TIMER_FUNCTION)&AXWaitTransmit,
(PVOID)Adapter
);
NdisMInitializeTimer(
&Adapter->TransmitHandleTimer,
MiniportAdapterHandle,
(PNDIS_TIMER_FUNCTION)&AXTransmitHandler,
(PVOID)Adapter
);
NdisMInitializeTimer(
&Adapter->InterruptTimer,
MiniportAdapterHandle,
(PNDIS_TIMER_FUNCTION)&AXWaitInterrupt,
(PVOID)Adapter
);
NdisAllocateSpinLock( &Adapter->TransmitSpinLock );
NdisAllocateSpinLock( &Adapter->ReceiveIoCountSpinLock );
NdisAllocateSpinLock( &Adapter->TransmitIoCountSpinLock );
//
// Start up the adapter.
CardStart(Adapter);
return NDIS_STATUS_SUCCESS;
}
VOID
AX88172Halt(
IN NDIS_HANDLE MiniportAdapterContext
)
//++
//
//Routine Description:
// AX88172Halt removes an adapter that was previously initialized.
//
//Arguments:
// MiniportAdapterContext - The context value that the Miniport returned
// from AX88172Initialize; actually as pointer to an AX_ADAPTER.
//
//Return Value:
// None.
//
//--
{
PAX_ADAPTER Adapter = PAX_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
CardStop( Adapter );
NdisFreeSpinLock( &Adapter->TransmitIoCountSpinLock );
NdisFreeSpinLock( &Adapter->ReceiveIoCountSpinLock );
NdisFreeSpinLock( &Adapter->TransmitSpinLock );
//
// Remove the adapter from the global queue of adapters.
if (AX88172MiniportBlock.AdapterQueue == Adapter)
AX88172MiniportBlock.AdapterQueue = Adapter->NextAdapter;
else
{
PAX_ADAPTER TmpAdapter = AX88172MiniportBlock.AdapterQueue;
while ( TmpAdapter )
{
if (TmpAdapter->NextAdapter == Adapter)
{
TmpAdapter->NextAdapter = Adapter->NextAdapter;
break;
}
TmpAdapter = TmpAdapter->NextAdapter;
}
}
NdisFreeMemory(
Adapter,
sizeof(struct _AX_ADAPTER),
0
);
if (AX88172MiniportBlock.AdapterQueue == NULL)
NdisTerminateWrapper(
AX88172MiniportBlock.NdisWrapperHandle,
NULL
);
}
BOOLEAN
AXCheckForHang(
IN NDIS_HANDLE MiniportAdapterContext
)
{
PAX_ADAPTER Adapter = (PAX_ADAPTER)(MiniportAdapterContext);
if ( Adapter->HaltEvents )
CardStop( Adapter );
if ( !Adapter->fgReady )
return FALSE;
if ( Adapter->fgBusy )
return Adapter->fgBusy = FALSE;
return FALSE;
}
NDIS_STATUS
AX88172QueryInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesWritten,
OUT PULONG BytesNeeded
)
//++
//Routine Description:
// The AX88172QueryInformation process a Query request for
// NDIS_OIDs that are specific about the Driver.
//
//Arguments:
// MiniportAdapterContext - a pointer to the adapter.
// Oid - the NDIS_OID to process.
// InformationBuffer - a pointer into the NdisRequest->InformationBuffer
// into which store the result of the query.
// InformationBufferLength - a pointer to the number of bytes left in the
// InformationBuffer.
// BytesWritten - a pointer to the number of bytes written into the
// InformationBuffer.
// BytesNeeded - If there is not enough room in the information buffer then
// this will contain the number of bytes needed to complete the request.
//
//Return Value:
// The function value is the status of the operation.
//
//--
{
//
// Pointer to the adapter structure.
PAX_ADAPTER Adapter = (PAX_ADAPTER)MiniportAdapterContext;
NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
NDIS_MEDIUM Medium;
NDIS_HARDWARE_STATUS HardwareStatus;
//
// This variable holds result of query
union {
ULONG lValue;
USHORT sValue;
UCHAR cArray[6];
} GenericData;
UINT MoveBytes = sizeof(ULONG);
PVOID MoveSource = (PVOID)(&GenericData.lValue);
URB Urb;
//
// Make sure that int is 4 bytes,
// else GenericData.lValue must change to something of size 4.
ASSERT(sizeof(ULONG) == 4);
switch (Oid)
{
case OID_GEN_MAC_OPTIONS:
GenericData.lValue = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
NDIS_MAC_OPTION_FULL_DUPLEX |
NDIS_MAC_OPTION_NO_LOOPBACK);
break;
case OID_GEN_SUPPORTED_LIST:
MoveSource = (PVOID)(AX88172SupportedOids);
MoveBytes = sizeof(AX88172SupportedOids);
break;
case OID_GEN_HARDWARE_STATUS:
HardwareStatus = NdisHardwareStatusReady;
MoveSource = (PVOID)(&HardwareStatus);
MoveBytes = sizeof(NDIS_HARDWARE_STATUS);
break;
case OID_GEN_MEDIA_SUPPORTED:
case OID_GEN_MEDIA_IN_USE:
Medium = NdisMedium802_3;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -