📄 ax88172.c
字号:
MoveSource = (PVOID) (&Medium);
MoveBytes = sizeof(NDIS_MEDIUM);
break;
case OID_GEN_MEDIA_CONNECT_STATUS:
GenericData.lValue = Adapter->fgMediaLinkUp ?
NdisMediaStateConnected : NdisMediaStateDisconnected;
break;
case OID_GEN_MAXIMUM_LOOKAHEAD:
GenericData.lValue = AX88172_MAX_LOOKAHEAD;
break;
case OID_GEN_MAXIMUM_FRAME_SIZE:
GenericData.lValue = (ULONG)(1514 - ETH_HEADER_SIZE);
break;
case OID_GEN_MAXIMUM_TOTAL_SIZE:
GenericData.lValue = (ULONG)(1514);
break;
case OID_GEN_LINK_SPEED:
GenericData.lValue = 1000000;
if ( !Adapter->fgMediaLinkUp )
break;
if ( Adapter->PhoneNetworkMedia )
{
if ( Adapter->SecondaryPhyType == 5 )
GenericData.lValue = 100000;
else
GenericData.lValue = 10000;
UsbBuildVendorRequest(
&Urb,
URB_FUNCTION_VENDOR_DEVICE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_TRANSFER_DIRECTION_OUT,
0,
0x1b,
0,
0,
NULL,
NULL,
0,
NULL
);
BulkUsb_CallUSBD(Adapter, &Urb);
}
else
{
UINT ConnectionType;
UsbBuildVendorRequest(
&Urb,
URB_FUNCTION_VENDOR_DEVICE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_TRANSFER_DIRECTION_OUT,
0,6,0,0,
NULL,NULL,
0,
NULL
);
BulkUsb_CallUSBD(Adapter, &Urb);
NdisStallExecution(5);
UsbBuildVendorRequest(
&Urb,
URB_FUNCTION_VENDOR_DEVICE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
(USBD_TRANSFER_DIRECTION_IN |USBD_SHORT_TRANSFER_OK),
0,7,
Adapter->PrimaryPhy,
PhyNwayLinkPartnerAbility,
&Adapter->uPartnerAbility,
NULL,
2,
NULL
);
BulkUsb_CallUSBD(Adapter, &Urb);
if ( (Adapter->uPartnerAbility==0) && (Adapter->ulPrimaryPhyId==RTL8201_0) )
{
UsbBuildVendorRequest(
&Urb,
URB_FUNCTION_VENDOR_DEVICE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
(USBD_TRANSFER_DIRECTION_IN |USBD_SHORT_TRANSFER_OK),
0,7,
Adapter->PrimaryPhy,
25, //Realtek
&Adapter->uPartnerAbility,
NULL,
2,
NULL
);
BulkUsb_CallUSBD(Adapter, &Urb);
if ( Adapter->uPartnerAbility&1 )
Adapter->uPartnerAbility = MiiPhyNway100BaseTx;
else
Adapter->uPartnerAbility = MiiPhyNway10BaseT;
}
UsbBuildVendorRequest(
&Urb,
URB_FUNCTION_VENDOR_DEVICE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_TRANSFER_DIRECTION_OUT,
0,10,0,0,
NULL,NULL,
0,
NULL
);
BulkUsb_CallUSBD(Adapter, &Urb);
ConnectionType = Adapter->uConnectionType&Adapter->uPartnerAbility;
UsbBuildVendorRequest(
&Urb,
URB_FUNCTION_VENDOR_DEVICE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_TRANSFER_DIRECTION_OUT,
0,0x1b,
((Adapter->FlowControl &&
(Adapter->uPartnerAbility&MiiPhyNwayPauseEnable))?
0x10:0)|
((ConnectionType&MiiPhyStat100BaseTxFD)? 6:
((ConnectionType&MiiPhyStat100BaseTx)? 4:
((ConnectionType&MiiPhyStat10BaseTxFD)? 2:0))),
0,
NULL,NULL,
0,
NULL
);
BulkUsb_CallUSBD(Adapter, &Urb);
//1,000,000 for 100Mbps
if ( ConnectionType & MiiPhyNway100BaseTxFD )
GenericData.lValue = 2000000;
else if ( ConnectionType & MiiPhyNway100BaseTx )
GenericData.lValue = 1000000;
else if ( ConnectionType & MiiPhyNway10BaseTFD )
GenericData.lValue = 200000;
else
GenericData.lValue = 100000;
}
NdisMSetTimer( &Adapter->InterruptTimer,160 );
break;
case OID_GEN_TRANSMIT_BUFFER_SPACE:
GenericData.lValue = (ULONG)(numTransmitQ *(AX88172_MAX_LOOKAHEAD+ETH_HEADER_SIZE));
break;
case OID_GEN_RECEIVE_BUFFER_SPACE:
GenericData.lValue = (ULONG)(numReceiveQ *(AX88172_MAX_LOOKAHEAD+ETH_HEADER_SIZE));
break;
case OID_GEN_TRANSMIT_BLOCK_SIZE:
GenericData.lValue = (ULONG)(AX88172_MAX_LOOKAHEAD+ETH_HEADER_SIZE);
break;
case OID_GEN_RECEIVE_BLOCK_SIZE:
GenericData.lValue = (ULONG)(AX88172_MAX_LOOKAHEAD+ETH_HEADER_SIZE);
break;
case OID_GEN_TRANSMIT_QUEUE_LENGTH:
GenericData.lValue = Adapter->NumQueuePackets;
break;
case OID_GEN_MAXIMUM_SEND_PACKETS:
GenericData.lValue = 1;
break;
case OID_GEN_VENDOR_ID:
GenericData.lValue = 0;
NdisMoveMemory(
(PVOID)&GenericData.lValue,
Adapter->PermanentAddress,
3
);
MoveSource = (PVOID)(&GenericData.lValue);
break;
case OID_GEN_VENDOR_DESCRIPTION:
MoveSource = (PVOID)"ASIX AX88172 Based USB2-LAN Adapter";
MoveBytes = 35;
break;
case OID_GEN_VENDOR_DRIVER_VERSION:
GenericData.lValue = 0x20020916;
break;
case OID_GEN_DRIVER_VERSION:
GenericData.sValue = ((USHORT)AX88172_NDIS_MAJOR_VERSION << 8) |
AX88172_NDIS_MINOR_VERSION;
MoveSource = (PVOID)(&GenericData.sValue);
MoveBytes = sizeof(GenericData.sValue);
break;
case OID_GEN_CURRENT_LOOKAHEAD:
GenericData.lValue = Adapter->MaxLookAhead;
break;
case OID_802_3_PERMANENT_ADDRESS:
NdisMoveMemory(
(PCHAR)GenericData.cArray,
Adapter->PermanentAddress,
AX88172_LENGTH_OF_ADDRESS
);
MoveSource = (PVOID)(GenericData.cArray);
MoveBytes = sizeof(Adapter->PermanentAddress);
break;
case OID_802_3_CURRENT_ADDRESS:
NdisMoveMemory(
(PCHAR)GenericData.cArray,
Adapter->StationAddress,
AX88172_LENGTH_OF_ADDRESS
);
MoveSource = (PVOID)(GenericData.cArray);
MoveBytes = sizeof(Adapter->StationAddress);
break;
case OID_802_3_MAXIMUM_LIST_SIZE:
GenericData.lValue = (ULONG) 1024;
break;
default:
switch (Oid)
{
case OID_GEN_XMIT_OK:
GenericData.lValue = Adapter->FramesXmitGood;
break;
case OID_GEN_RCV_OK:
GenericData.lValue = Adapter->FramesRcvGood;
break;
case OID_GEN_XMIT_ERROR:
GenericData.lValue = Adapter->FramesXmitBad;
break;
case OID_GEN_RCV_NO_BUFFER:
GenericData.lValue = Adapter->MissedPackets;
break;
case OID_802_3_XMIT_ONE_COLLISION:
case OID_802_3_XMIT_MORE_COLLISIONS:
case OID_GEN_RCV_ERROR:
case OID_802_3_RCV_ERROR_ALIGNMENT:
GenericData.lValue = 0;
break;
case OID_BACKDOOR_GPBITS:
// Bit 5,3,1 (GPI2,GPI1,GPI0) are the bit data that we want
UsbBuildVendorRequest(
&Urb,
URB_FUNCTION_VENDOR_DEVICE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_TRANSFER_DIRECTION_IN |USBD_SHORT_TRANSFER_OK,
0,
0x1e,
0,
0,
&GenericData.sValue,
NULL,
1,
NULL
);
BulkUsb_CallUSBD(Adapter, &Urb);
break;
default:
StatusToReturn = NDIS_STATUS_INVALID_OID;
break;
}
break;
}
if (StatusToReturn == NDIS_STATUS_SUCCESS)
{
*BytesNeeded = MoveBytes;
if (MoveBytes > InformationBufferLength)
{
//
// Not enough room in InformationBuffer. Punt
StatusToReturn = NDIS_STATUS_BUFFER_TOO_SHORT;
*BytesWritten = 0;
}
else
{
//
// Store result.
NdisMoveMemory(
(PUCHAR)(InformationBuffer),
MoveSource,
MoveBytes
);
*BytesWritten = MoveBytes;
}
}
return StatusToReturn;
}
NDIS_STATUS
AX88172Reset(
OUT PBOOLEAN AddressingReset,
IN NDIS_HANDLE MiniportAdapterContext
)
//++
//
//Routine Description:
// The AX88172Reset request instructs the Miniport to issue a hardware reset
// to the network adapter. The driver also resets its software state. See
// the description of NdisMReset for a detailed description of this request.
//
//Arguments:
// AddressingReset - Does the adapter need the addressing information reloaded.
// MiniportAdapterContext - Pointer to the adapter structure.
//
//Return Value:
// The function value is the status of the operation.
//
//--
{
//
// Pointer to the adapter structure.
PAX_ADAPTER Adapter = (PAX_ADAPTER)MiniportAdapterContext;
if (AddressingReset !=NULL)
*AddressingReset = FALSE;
//
// Restart the chip
CardStart(Adapter);
return NDIS_STATUS_SUCCESS;
}
//extern
NDIS_STATUS
AX88172SetInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesRead,
OUT PULONG BytesNeeded
)
/*++
Routine Description:
AX88172SetInformation handles a set operation for a
single OID.
Arguments:
MiniportAdapterContext - Context registered with the wrapper, really
a pointer to the adapter.
Oid - The OID of the set.
InformationBuffer - Holds the data to be set.
InformationBufferLength - The length of InformationBuffer.
BytesRead - If the call is successful, returns the number
of bytes read from InformationBuffer.
BytesNeeded - If there is not enough data in InformationBuffer
to satisfy the OID, returns the amount of storage needed.
General Algorithm:
Verify length
Switch(Request)
Process Request
Return Value:
NDIS_STATUS_SUCCESS
NDIS_STATUS_PENDING
NDIS_STATUS_INVALID_LENGTH
NDIS_STATUS_INVALID_OID
--*/
{
//
// Pointer to the adapter structure.
PAX_ADAPTER Adapter = (PAX_ADAPTER)MiniportAdapterContext;
PUCHAR InfoBuffer = (PUCHAR)(InformationBuffer);
UINT OidLength = InformationBufferLength;
URB Urb;
UCHAR mcFilter[8];
//
// Status of the operation.
NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
//
// Variables for holding the new values to be used.
union {
PULONG LookAhead;
PULONG Filter;
PUSHORT GPBits;
PUCHAR mcAddress;
} lptr;
*BytesRead =
*BytesNeeded = 0;
switch (Oid)
{
case OID_802_3_MULTICAST_LIST:
NdisZeroMemory (mcFilter, 8);
lptr.mcAddress = (PUCHAR)InformationBuffer;
for ( OidLength/=AX88172_LENGTH_OF_ADDRESS; OidLength; OidLength-- )
{
UINT BitNumber;
BitNumber = (compute_crc32( AX88172_LENGTH_OF_ADDRESS,lptr.mcAddress )>>26)&0x3f;
mcFilter[BitNumber/8] |= 1 << (BitNumber % 8);
lptr.mcAddress += AX88172_LENGTH_OF_ADDRESS;
}
if ( !NdisEqualMemory ( mcFilter, Adapter->mcFilter, 8 ) )
{
NdisMoveMemory( Adapter->mcFilter, mcFilter, 8 );
UsbBuildVendorRequest(
&Urb,
URB_FUNCTION_VENDOR_DEVICE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_TRANSFER_DIRECTION_OUT,
0,
0x16,
0,
0,
Adapter->mcFilter,
NULL,
8,
NULL
);
BulkUsb_CallUSBD(Adapter, &Urb);
}
break;
case OID_GEN_CURRENT_PACKET_FILTER:
//
// Verify length
if (OidLength != 4 )
{
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
break;
}
lptr.Filter = (PULONG)InformationBuffer;
//
// Verify bits
if ( *lptr.Filter & (NDIS_PACKET_TYPE_SOURCE_ROUTING |
NDIS_PACKET_TYPE_SMT |
NDIS_PACKET_TYPE_MAC_FRAME |
NDIS_PACKET_TYPE_FUNCTIONAL |
NDIS_PACKET_TYPE_ALL_FUNCTIONAL |
NDIS_PACKET_TYPE_GROUP
))
{
StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
*BytesRead = 4;
break;
}
//
// See what has to be put on the card.
if ( *lptr.Filter != Adapter->PacketFilterSave )
{
Adapter->PacketFilterSave = *lptr.Filter;
Adapter->PacketFilter &= 0x80; //Alternate Setting!
if ( *lptr.Filter & NDIS_PACKET_TYPE_BROADCAST )
Adapter->PacketFilter |= PACKET_TYPE_BROADCAST;
if ( *lptr.Filter & NDIS_PACKET_TYPE_ALL_MULTICAST )
Adapter->PacketFilter |= PACKET_TYPE_ALL_MULTICAST;
if ( *lptr.Filter & NDIS_PACKET_TYPE_PROMISCUOUS )
Adapter->PacketFilter |= PACKET_TYPE_PROMISCUOUS;
if ( *lptr.Filter & NDIS_PACKET_TYPE_MULTICAST )
Adapter->PacketFilter |= PACKET_TYPE_MULTICAST;
if (*lptr.Filter & NDIS_PACKET_TYPE_DIRECTED)
Adapter->PacketFilter |= PACKET_TYPE_DIRECTED;
//
// Set Packet Filter (Receive Configuration)
UsbBuildVendorRequest(
&Urb,
URB_FUNCTION_VENDOR_DEVICE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_TRANSFER_DIRECTION_OUT,
0,
0x10,
Adapter->PacketFilter,
0,
NULL,
NULL,
0,
NULL
);
BulkUsb_CallUSBD(Adapter, &Urb);
}
break;
case OID_GEN_CURRENT_LOOKAHEAD:
//
// Verify length
if (OidLength == 4)
{
//
// Store the new value.
lptr.LookAhead = (PULONG)InformationBuffer;
if (*lptr.LookAhead > AX88172_MAX_LOOKAHEAD)
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
else
Adapter->MaxLookAhead = *lptr.LookAhead;
}
else
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
break;
case OID_BACKDOOR_GPBITS:
lptr.GPBits = (PUSHORT)InformationBuffer;
Adapter->GPIO = *lptr.GPBits & 0x3f;
// Bit 0..5 (GPIO0EN,GPIO0,GPIO1EN,GPIO1,GPIO2EN,GPIO2) are the bit data that we want
UsbBuildVendorRequest(
&Urb,
URB_FUNCTION_VENDOR_DEVICE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_TRANSFER_DIRECTION_OUT,
0,
0x1f,
Adapter->GPIO,
0,
NULL,
NULL,
0,
NULL
);
BulkUsb_CallUSBD(Adapter, &Urb);
break;
default:
StatusToReturn = NDIS_STATUS_INVALID_OID;
break;
}
if (StatusToReturn == NDIS_STATUS_SUCCESS)
{
*BytesRead = InformationBufferLength;
}
return StatusToReturn;
}
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
#pragma NDIS_INIT_FUNCTION(DriverEntry)
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
//++
//
//Routine Description:
// This is the primary initialization routine for the AX88172 driver.
// It is simply responsible for the intializing the wrapper and registering
// the Miniport driver. It then calls a system and architecture specific
// routine that will initialize and register each adapter.
//
//Arguments:
// DriverObject - Pointer to driver object created by the system.
// RegistryPath - Path to the parameters for this driver in the registry.
//
//Return Value:
// The status of the operation.
//
//--
{
//
// Characteristics table for this driver.
NDIS_MINIPORT_CHARACTERISTICS AXChar;
//
// Save the global information about this driver.
AX88172MiniportBlock.AdapterQueue = (NDIS_HANDLE)NULL;
//
// Initialize the wrapper.
NdisMInitializeWrapper(
&AX88172MiniportBlock.NdisWrapperHandle,
DriverObject,
RegistryPath,
NULL
);
//
// Initialize the Miniport characteristics
// for the call to NdisMRegisterMiniport.
NdisZeroMemory (&AXChar, sizeof(AXChar));
AXChar.MajorNdisVersion = AX88172_NDIS_MAJOR_VERSION;
AXChar.MinorNdisVersion = AX88172_NDIS_MINOR_VERSION;
AXChar.InitializeHandler = AX88172Initialize;
AXChar.QueryInformationHandler = AX88172QueryInformation;
AXChar.SetInformationHandler = AX88172SetInformation;
AXChar.ResetHandler = AX88172Reset;
AXChar.CheckForHangHandler = AXCheckForHang;
AXChar.HaltHandler = AX88172Halt;
AXChar.SendHandler = AX88172Send;
AXChar.TransferDataHandler = AX88172TransferData;
if ( NdisMRegisterMiniport(
AX88172MiniportBlock.NdisWrapperHandle,
&AXChar,
sizeof(AXChar)
) != NDIS_STATUS_SUCCESS )
{
NdisTerminateWrapper(
AX88172MiniportBlock.NdisWrapperHandle,
NULL
);
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -