⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ax88172.c

📁 Axis ax88172 USB 界面网卡驱动源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*++

Copyright (c) 1998-2001  ASIX Electronics Corporation

Module Name:
	ax88172.c

Abstract:
	This is the main file for the ASIX AX88172 USB-Ethernet Controller.
	This driver conforms to the NDIS3/NDIS5 miniport interface.

Author:
	William Lee, June 2001, July 2002,

Environment:
	Windows 98/98SE/2000/ME/XP

Revision History:

--*/


#include	"ax88170.h"

//
// The global Miniport driver block.
//
static	DRIVER_BLOCK	AX88172MiniportBlock;


//
// List of supported OID for this driver.
//
static const NDIS_OID	AX88172SupportedOids[] =
{
	OID_GEN_SUPPORTED_LIST,
	OID_GEN_HARDWARE_STATUS,
	OID_GEN_MEDIA_SUPPORTED,
	OID_GEN_MEDIA_IN_USE,
	OID_GEN_MEDIA_CONNECT_STATUS,
	OID_GEN_MAXIMUM_LOOKAHEAD,
	OID_GEN_MAXIMUM_FRAME_SIZE,
	OID_GEN_MAXIMUM_TOTAL_SIZE,
	OID_GEN_MAXIMUM_SEND_PACKETS,
	OID_GEN_MAC_OPTIONS,
	OID_GEN_PROTOCOL_OPTIONS,
	OID_GEN_LINK_SPEED,
	OID_GEN_TRANSMIT_BUFFER_SPACE,
	OID_GEN_TRANSMIT_BLOCK_SIZE,
	OID_GEN_TRANSMIT_QUEUE_LENGTH,
	OID_GEN_RECEIVE_BUFFER_SPACE,
	OID_GEN_RECEIVE_BLOCK_SIZE,
	OID_GEN_VENDOR_ID,
	OID_GEN_VENDOR_DESCRIPTION,
	OID_GEN_VENDOR_DRIVER_VERSION,
	OID_GEN_CURRENT_PACKET_FILTER,
	OID_GEN_CURRENT_LOOKAHEAD,
	OID_GEN_DRIVER_VERSION,
	OID_GEN_XMIT_OK,
	OID_GEN_XMIT_ERROR,
	OID_GEN_RCV_OK,
	OID_GEN_RCV_ERROR,
	OID_GEN_RCV_NO_BUFFER,
	OID_802_3_PERMANENT_ADDRESS,
	OID_802_3_CURRENT_ADDRESS,
	OID_802_3_MULTICAST_LIST,
	OID_802_3_MAXIMUM_LIST_SIZE,
	OID_802_3_RCV_ERROR_ALIGNMENT,
	OID_802_3_XMIT_ONE_COLLISION,
	OID_802_3_XMIT_MORE_COLLISIONS,
	OID_BACKDOOR_GPBITS
};

USHORT	HIFG[3] = { 0x17,0x0c,0x14 };	//HomePNA
USHORT	EIFG[3] = { 0x15,0x0c,0x12 };	//Ethernet


#include	"card.c"
#include	"interrup.c"

VOID
AXTransmitHandler(
	IN PVOID	SystemSpecific1,
	IN PAX_ADAPTER	Adapter,
	IN PVOID	SystemSpecific2,
	IN PVOID	SystemSpecific3
	)
{
	Adapter->fgBusy = TRUE;
	while ( Adapter->FirstPacket )
	{
		if ( Adapter->TransmitIoCount<numTransmitQ )
			AX88172DoNextSend(Adapter);
		else
		{
			NdisMSetTimer( &Adapter->TransmitHandleTimer,1 );
			return;
		}
	}
	Adapter->StartTransmit = FALSE;
}


ULONG
compute_crc32(
	IN UINT		length,
	IN PUCHAR	buffer
	)
{
	ULONG	crc32 = 0xffffffff;

	for ( ; length; length-- )
	{
		UCHAR	current_byte = *buffer++;
		UINT	j;

		for ( j=0; j<8; j++ )
		{
			UCHAR	carry = current_byte & 1;

			if ( crc32 & 0x80000000 )
				carry ^= 1;
			crc32 <<= 1;
			current_byte >>= 1;
			if ( carry )
				crc32 ^= 0x04c11db7;	/*big endian polynomial*/
		}
	}
	return crc32;
}


VOID
AXReceiveHandler(
	IN PVOID	SystemSpecific1,
	IN PAX_ADAPTER	Adapter,
	IN PVOID	SystemSpecific2,
	IN PVOID	SystemSpecific3
	)
{
	ULONG	IoCount;

	NdisAcquireSpinLock( &Adapter->ReceiveIoCountSpinLock );
	IoCount = Adapter->ReceiveIoCount;
	while ( IoCount )
	{
		PUCHAR	BufferOffset;
		UINT	totalLength;

		NdisReleaseSpinLock( &Adapter->ReceiveIoCountSpinLock );

		BufferOffset = &Adapter->ReceiveBuffer[Adapter->LastReceive][0];
		totalLength = Adapter->ReceiveLength[Adapter->LastReceive] -ETH_HEADER_SIZE;

		NdisMEthIndicateReceive(
			Adapter->MiniportAdapterHandle,
			(NDIS_HANDLE)Adapter,
			BufferOffset,
			ETH_HEADER_SIZE,
			(PUCHAR)BufferOffset +ETH_HEADER_SIZE,
			totalLength,
			totalLength
			);
		NdisMEthIndicateReceiveComplete( Adapter->MiniportAdapterHandle );
		if ( Adapter->StopReceive )
		{
			Adapter->StopReceive = FALSE;
			BulkUsb_PacketReceive( Adapter );
		}
		Adapter->FramesRcvGood++;
		if ( Adapter->LastReceive<(numReceiveQ-1) )
			Adapter->LastReceive++;
		else
			Adapter->LastReceive = 0;
		NdisAcquireSpinLock( &Adapter->ReceiveIoCountSpinLock );
		IoCount = NdisInterlockedDecrement(&Adapter->ReceiveIoCount);
	}
	NdisReleaseSpinLock( &Adapter->ReceiveIoCountSpinLock );
	Adapter->StartReceive = FALSE;
}



VOID
AXWaitTransmit(
	IN PVOID	SystemSpecific1,
	IN PAX_ADAPTER	Adapter,
	IN PVOID	SystemSpecific2,
	IN PVOID	SystemSpecific3
	)
{
	BulkUsb_PacketTransmit( Adapter );
}



VOID
AXWaitReceive(
	IN PVOID	SystemSpecific1,
	IN PAX_ADAPTER	Adapter,
	IN PVOID	SystemSpecific2,
	IN PVOID	SystemSpecific3
	)
{
	BulkUsb_PacketReceive( Adapter );
}



VOID
AXWaitInterrupt(
	IN PVOID	SystemSpecific1,
	IN PAX_ADAPTER	Adapter,
	IN PVOID	SystemSpecific2,
	IN PVOID	SystemSpecific3
	)
{
	if ( !Adapter->HaltEvents && Adapter->fgReady )
	{
		if ( Adapter->StartReceive||Adapter->StartTransmit )
			NdisMSetTimer( &Adapter->InterruptTimer,160 );
		else
			BulkUsb_InterruptEvent( Adapter );
	}
}



VOID
MiiReadRegister(
	IN PAX_ADAPTER	Adapter,
	IN PURB		pUrb,
	IN USHORT	uPhyAddr,
	IN USHORT	uRegNum,
	IN PUSHORT	puRegData
	)
{
	UsbBuildVendorRequest(
		pUrb,
		URB_FUNCTION_VENDOR_DEVICE,
		sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
		(USBD_TRANSFER_DIRECTION_IN |USBD_SHORT_TRANSFER_OK),
		0,
		7,
		uPhyAddr,
		uRegNum,
		puRegData,
		NULL,
		2,
		NULL
		);
	BulkUsb_CallUSBD(Adapter, pUrb);
}

USHORT
_MiiReadRegister(
	IN NDIS_HANDLE	MiniportAdapterContext,
	IN USHORT	uRegNum
	)
{
	PAX_ADAPTER	Adapter = (PAX_ADAPTER)(MiniportAdapterContext);
	URB	Urb;
	USHORT	uRegData;

	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->SecondaryPhy,
		uRegNum,
		&uRegData,
		NULL,
		2,
		NULL
		);
	BulkUsb_CallUSBD(Adapter, &Urb);
	return	uRegData;
}



VOID
MiiWriteRegister(
	IN PAX_ADAPTER	Adapter,
	IN PURB		pUrb,
	IN USHORT	uPhyAddr,
	IN USHORT	uRegNum,
	IN USHORT	uRegData
	)
{
	UsbBuildVendorRequest(
		pUrb,
		URB_FUNCTION_VENDOR_DEVICE,
		sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
		USBD_TRANSFER_DIRECTION_OUT,
		0,
		8,
		uPhyAddr,
		uRegNum,
		&uRegData,
		NULL,
		2,
		NULL
		);
	BulkUsb_CallUSBD(Adapter, pUrb);
}

VOID
_MiiWriteRegister(
	IN NDIS_HANDLE	MiniportAdapterContext,
	IN USHORT	uRegNum,
	IN USHORT	uRegData
	)
{
	PAX_ADAPTER	Adapter = (PAX_ADAPTER)(MiniportAdapterContext);
	URB	Urb;

	UsbBuildVendorRequest(
		&Urb,
		URB_FUNCTION_VENDOR_DEVICE,
		sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
		USBD_TRANSFER_DIRECTION_OUT,
		0,
		8,
		Adapter->SecondaryPhy,
		uRegNum,
		&uRegData,
		NULL,
		2,
		NULL
		);
	BulkUsb_CallUSBD(Adapter, &Urb);
}


VOID
PhyInitial( IN PAX_ADAPTER Adapter );
#pragma NDIS_PAGEABLE_FUNCTION(PhyInitial)

VOID
PhyInitial(
	IN PAX_ADAPTER	Adapter
	)
{
	URB	Urb;
	USHORT	uPhyId_1, uPhyId_2;
	USHORT	i,uPhyRegister;


	//Disable MII operation of AX88172 Hardware
	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);

	#if 0
	UsbBuildVendorRequest(
		&Urb,
		URB_FUNCTION_VENDOR_DEVICE,
		sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
		USBD_TRANSFER_DIRECTION_OUT,
		0,
		0x1f,
		0x13,
		0,
		NULL,NULL,
		0,
		NULL
		);
	BulkUsb_CallUSBD(Adapter, &Urb);
	UsbBuildVendorRequest(
		&Urb,
		URB_FUNCTION_VENDOR_DEVICE,
		sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
		USBD_TRANSFER_DIRECTION_OUT,
		0,
		0x1f,
		1,
		0,
		NULL,NULL,
		0,
		NULL
		);
	BulkUsb_CallUSBD(Adapter, &Urb);
	NdisStallExecution(50);
	UsbBuildVendorRequest(
		&Urb,
		URB_FUNCTION_VENDOR_DEVICE,
		sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
		USBD_TRANSFER_DIRECTION_OUT,
		0,
		0x1f,
		3,
		0,
		NULL,NULL,
		0,
		NULL
		);
	BulkUsb_CallUSBD(Adapter, &Urb);
	#endif

	uPhyRegister = 0;
	while ( ~uPhyRegister&1 )
	{
		NdisStallExecution(50);
		UsbBuildVendorRequest(
			&Urb,
			URB_FUNCTION_VENDOR_DEVICE,
			sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
			USBD_TRANSFER_DIRECTION_IN |USBD_SHORT_TRANSFER_OK,
			0,9,0,0,
			&uPhyRegister,
			NULL,
			1,
			NULL
			);
		BulkUsb_CallUSBD(Adapter, &Urb);
	}
	if ( Adapter->PrimaryPhy || (Adapter->PrimaryPhyType!=7) )
	{
		MiiReadRegister(
			Adapter,
			&Urb,
			Adapter->PrimaryPhy,
			PhyStatusReg,
			&uPhyId_1
			);
		MiiReadRegister(
			Adapter,
			&Urb,
			Adapter->PrimaryPhy,
			PhyControlReg,
			&uPhyId_2
			);
		if ( (uPhyId_1&uPhyId_2) != 0xffff )
		{
			MiiWriteRegister(
				Adapter,
				&Urb,
				Adapter->PrimaryPhy,
				PhyControlReg,
				MiiPhyCtrlIsolate|MiiPhyCtrlPowerDown
				);
			MiiReadRegister(
				Adapter,
				&Urb,
				Adapter->PrimaryPhy,
				PhyId_1,
				&uPhyId_1
				);
			MiiReadRegister(
				Adapter,
				&Urb,
				Adapter->PrimaryPhy,
				PhyId_2,
				&uPhyId_2
				);
			Adapter->ulPrimaryPhyId = (uPhyId_1<<16) + (uPhyId_2&0xFFF0);
			Adapter->PrimaryPhyExist = TRUE;
		}
	}
	if ( Adapter->SecondaryPhy || (Adapter->SecondaryPhyType!=7) )
	{
		MiiWriteRegister(
			Adapter,
			&Urb,
			0,
			PhyAddress,
			Adapter->SecondaryPhy
			);
		if ( (_MiiReadRegister( Adapter,PhyStatusReg ) &
			_MiiReadRegister( Adapter,PhyControlReg ) ) != 0xffff )
		{
			_MiiWriteRegister(
				Adapter,
				PhyControlReg,
				MiiPhyCtrlIsolate|MiiPhyCtrlPowerDown
				);
			uPhyId_1 = _MiiReadRegister( Adapter,PhyId_1 );
			uPhyId_2 = _MiiReadRegister( Adapter,PhyId_2 );
			Adapter->ulSecondaryPhyId = (uPhyId_1<<16) + (uPhyId_2&0xFFF0);
			Adapter->SecondaryPhyExist = TRUE;
			if ( !Adapter->PrimaryPhyExist )
				Adapter->PhoneNetworkMedia = TRUE;
		}
	}
	if ( Adapter->PrimaryPhyExist && Adapter->SecondaryPhyExist )
	{
		MiiWriteRegister(
			Adapter,
			&Urb,
			0,
			PhyControlReg,
			MiiPhyCtrlIsolate|MiiPhyCtrlPowerDown
			);
	}
	else
		Adapter->FixedPhy = TRUE;

	if ( Adapter->PhoneNetworkMedia )
	{
		_MiiWriteRegister(
			Adapter,
			PhyControlReg,
			0
			);
		_MiiWriteRegister(
			Adapter,
			PhyControlReg,
			MiiPhyCtrlReset
			);
		if ( Adapter->PrimaryPhyExist )
			MiiWriteRegister(
				Adapter,
				&Urb,
				0,
				PhyAddress,
				Adapter->SecondaryPhy
				);
		for ( i=0; _MiiReadRegister( Adapter,PhyControlReg )&MiiPhyCtrlReset; i++)
		{
			if ( i > 1000 )
				break;
			NdisStallExecution(5000);
		}
		_MiiWriteRegister(
			Adapter,
			0x10,	//1M8 PHY Control Register
			Adapter->uPhoneLine
			);
	}
	else
	{
		MiiWriteRegister(
			Adapter,
			&Urb,
			Adapter->PrimaryPhy,
			PhyControlReg,
			0
			);
		MiiWriteRegister(
			Adapter,
			&Urb,
			Adapter->PrimaryPhy,
			PhyControlReg,
			MiiPhyCtrlReset
			);
		uPhyRegister = MiiPhyCtrlReset;
		for ( i=0; uPhyRegister & MiiPhyCtrlReset; i++)
		{
			if ( i > 1000 )
				break;
			NdisStallExecution(5000);
			MiiReadRegister(
				Adapter,
				&Urb,
				Adapter->PrimaryPhy,
				PhyControlReg,
				&uPhyRegister
				);
		}
		MiiWriteRegister(
			Adapter,
			&Urb,
			Adapter->PrimaryPhy,
			PhyNwayAdvertisement,
			(USHORT)Adapter->uConnectionType
			);
		MiiWriteRegister(
			Adapter,
			&Urb,
			Adapter->PrimaryPhy,
			PhyControlReg,
			MiiPhyCtrlEnableNway|MiiPhyCtrlRestartNway
			);
	}
	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);
	for ( i=0; i<3; i++ )
	{
		UsbBuildVendorRequest(
			&Urb,
			URB_FUNCTION_VENDOR_DEVICE,
			sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
			USBD_TRANSFER_DIRECTION_OUT,
			0,
			18+i,
			(Adapter->PhoneNetworkMedia)? HIFG[i]:EIFG[i],
			0,
			NULL,
			NULL,
			0,
			NULL
			);
		BulkUsb_CallUSBD(Adapter, &Urb);
	}

}



#pragma NDIS_PAGEABLE_FUNCTION(AX88172RegisterAdapter)
NDIS_STATUS
AX88172RegisterAdapter(
	IN PAX_ADAPTER	Adapter
	)

/*++

Routine Description:
    Called when a new adapter should be registered. It allocates space for
    the adapter, initializes the adapter's block, registers resources
    with the wrapper and initializes the physical adapter.

Arguments:
    Adapter - The adapter structure.
    ConfigurationHandle - Handle passed to AX88172Initialize.

Return Value:
    Indicates the success or failure of the registration.

--*/

{
	//
	// Temporary looping variable.
	UINT	i;
	UCHAR	MiiData[2];

	PDEVICE_OBJECT	FunctionalDeviceObject;
	PDEVICE_OBJECT	NextDeviceObject;
	PCM_RESOURCE_LIST  AllocatedResources,AllocatedResourcesTranslated;

	URB	Urb;
	PURB	pUrb;
	USHORT	siz;
	USBD_VERSION_INFORMATION	UsbVersionInfo;
	PUSB_INTERFACE_DESCRIPTOR	UsbInterfaceDescriptor;
	PUSBD_INTERFACE_INFORMATION	UsbInterface;
	PUSBD_INTERFACE_LIST_ENTRY	interfaceList, tmp;


	///
	// USB Initialize!
	///

	NdisMGetDeviceProperty(
		Adapter->MiniportAdapterHandle,
		&Adapter->PhysicalDeviceObject,
		&FunctionalDeviceObject,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -