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

📄 3c90x.c

📁 3c90x网卡的驱动(Linux环境下的)
💻 C
📖 第 1 页 / 共 5 页
字号:
	)
{
	PNIC_INFORMATION pAdapter = Adapter;
	MediaStatus_g = 0;

	NIC_COMMAND(pAdapter,COMMAND_SELECT_REGISTER_WINDOW | REGISTER_WINDOW_4);

	MediaStatus_g = NIC_READ_PORT_USHORT(pAdapter,MEDIA_STATUS_REGISTER);

	NIC_DELAY(10);

	if(MediaStatus_g & MEDIA_STATUS_TX_IN_PROGRESS)
	{	pAdapter->WaitCases = CHECK_TRANSMIT_IN_PROGRESS;
		TimeOutCount = jiffies + HZ;  //max = 1s
		if(!InWaitTimer)
		{	WaitTimer.expires = RUN_AT(HZ/100);
			add_timer(&WaitTimer);
			InWaitTimer = TRUE;
		}
		while(TimeOutCount > jiffies) ;
		if(!(MediaStatus_g & MEDIA_STATUS_TX_IN_PROGRESS))
		{	pAdapter->Hardware.Status = HARDWARE_STATUS_FAILURE;
			DBGPRINT_ERROR(("CheckTransmitInProgress: Transmit still in progress\n"));
			return FALSE;
		}
	}
	return TRUE;
}

	
/*++

Routine Name:

	TestPacket

Routine Description:

    This function is called by TryLoopback to determine if a packet can 
	successfully be loopbacked for 10Base-2 and AUI.

Arguments:

	IN PNIC_INFORMATION Adapter
    
Return Value:
	
	BOOLEAN

--*/

BOOLEAN
TestPacket(    
	IN PNIC_INFORMATION Adapter
	) 
{
	PNIC_INFORMATION pAdapter = Adapter;
    	BOOLEAN ReturnValue = FALSE;
	USHORT MacControl = 0;
	ULONG PacketStatus = 0;

	NIC_COMMAND(
		pAdapter, 
		COMMAND_SELECT_REGISTER_WINDOW | REGISTER_WINDOW_3);

	MacControl = NIC_READ_PORT_USHORT(
					pAdapter, 
					MAC_CONTROL_REGISTER);
	//
    	// Enable full duplex
    	//
	NIC_WRITE_PORT_USHORT(
		pAdapter,
		MAC_CONTROL_REGISTER, 
		(USHORT)(MacControl | MAC_CONTROL_FULL_DUPLEX_ENABLE));
	//
    	// Write UpListPointer to UpListPointer register and unstall
    	//
	NIC_COMMAND_WAIT(pAdapter, COMMAND_UP_STALL);
    
	NIC_WRITE_PORT_ULONG(
		pAdapter, 
		UP_LIST_POINTER_REGISTER, 
		pAdapter->HeadUPDVirtual->UPDPhysicalAddress);

	NIC_COMMAND(pAdapter, COMMAND_UP_UNSTALL);

	//
    	// Enable receive and transmit and setup our packet filter
    	//
    	NIC_COMMAND_WAIT(pAdapter, COMMAND_TX_ENABLE);
    	NIC_COMMAND_WAIT(pAdapter, COMMAND_RX_ENABLE);
    	NIC_COMMAND_WAIT(pAdapter, COMMAND_SET_RX_FILTER + 
			 RX_FILTER_INDIVIDUAL);

	//
	// Create single DPD and download 
	//
	if (!DownloadSelfDirected(pAdapter)) {

		return FALSE;
	}
	//
	// Check if transmit is still in progress 
	//
	if (!CheckTransmitInProgress(pAdapter))
		return FALSE;
   	//
    	// Reset the transmitter to get rid of any TxStatus we haven't seen yet
   	//
	NIC_COMMAND_WAIT(pAdapter, COMMAND_TX_RESET | TX_RESET_MASK_NETWORK_RESET);
	//
   	// Check UpListPtr to see if it has changed to see if upload complete
	//
	UpListPointer_g = NIC_READ_PORT_ULONG(pAdapter,UP_LIST_POINTER_REGISTER);

	NIC_DELAY(100);

	if(UpListPointer_g == pAdapter->HeadUPDVirtual->UPDPhysicalAddress)
	{	pAdapter->WaitCases = AUTONEG_TEST_PACKET;
		TimeOutCount = jiffies + HZ; //max =1s		
		while(TimeOutCount > jiffies) ;
		if(UpListPointer_g != pAdapter->HeadUPDVirtual->UPDPhysicalAddress)
		{	DBGPRINT_ERROR(("TestPacket: UPD not finished\n"));
			return FALSE;
		}
	}
    //
    // Check RxStatus. If we've got a packet without any errors, this
    // connector is okay.
    //
    	PacketStatus = pAdapter->HeadUPDVirtual->UpPacketStatus;
   
	if (!(PacketStatus & UP_PACKET_STATUS_ERROR) && 
    		(PacketStatus & UP_PACKET_STATUS_COMPLETE)) {
		
		ReturnValue = TRUE;		// Received a good packet
	}
    	//
    	// The following cleans up after the test we just ran
    	//
    	NIC_WRITE_PORT_ULONG(pAdapter, UP_LIST_POINTER_REGISTER, 0);
    	NIC_WRITE_PORT_ULONG(pAdapter, DOWN_LIST_POINTER_REGISTER, 0);
    	pAdapter->HeadUPDVirtual->UpPacketStatus = 0;
    	//
    	// Reset the receiver to wipe anything we haven't seen yet
    	//
    	NIC_COMMAND_WAIT(pAdapter, COMMAND_RX_RESET | RX_RESET_MASK_NETWORK_RESET);
    	NIC_COMMAND(
		pAdapter, 
		COMMAND_ACKNOWLEDGE_INTERRUPT +	
		INTSTATUS_ACKNOWLEDGE_ALL);

	//
    // Get out of loopback mode
    //
	NIC_COMMAND(
		pAdapter, 
		COMMAND_SELECT_REGISTER_WINDOW | REGISTER_WINDOW_3);

	MacControl = NIC_READ_PORT_USHORT(pAdapter, MAC_CONTROL_REGISTER);
	
	NIC_WRITE_PORT_USHORT(
		pAdapter,
		MAC_CONTROL_REGISTER, 
		(USHORT)(MacControl & ~MAC_CONTROL_FULL_DUPLEX_ENABLE));

    	return ReturnValue;
}


/*++

Routine Name: 

	GetLinkSpeed

Routine Description:

	Determine from the MII AutoNegotiationAdvertisement and
	AutoNegotiationPartnerAbility registers whether the 
	current linkspeed is 10Mbits or 100Mbits.

Arguments:

	IN PNIC_INFORMATION Adapter,
	OUT PBOOLEAN handles100Mbitptr 

Return Value:

	BOOLEAN

--*/

BOOLEAN
GetLinkSpeed(  
	IN PNIC_INFORMATION Adapter,
	OUT PBOOLEAN handles100Mbitptr 
	) 
{
	PNIC_INFORMATION pAdapter = Adapter;
  	BOOLEAN PhyResponding;
	USHORT PhyAnlpar;
    	USHORT PhyAner;
    	USHORT PhyAnar;
	USHORT PhyStatus;
      
    PhyResponding = ReadMIIPhy(pAdapter, MII_PHY_ANER, &PhyAner);
    if (!PhyResponding)
		return FALSE;
  
    PhyResponding = ReadMIIPhy(pAdapter, MII_PHY_ANLPAR, &PhyAnlpar);
    if (!PhyResponding)
		return FALSE;

    PhyResponding = ReadMIIPhy(pAdapter, MII_PHY_ANAR, &PhyAnar);
    if (!PhyResponding)
		return FALSE;

	PhyResponding = ReadMIIPhy(pAdapter, MII_PHY_STATUS, &PhyStatus);
	if (!PhyResponding)
		return FALSE;
	//
	// Check to see if we've completed auto-negotiation.
	//
	if (!(PhyStatus & MII_STATUS_AUTO_DONE))
		return FALSE;

	if ((PhyAnar & MII_ANAR_100TXFD) && 
		(PhyAnlpar & MII_ANLPAR_100TXFD)) {
		pAdapter->Hardware.MIIPhyUsed = MII_100TXFD;
		*handles100Mbitptr = TRUE;
		pAdapter->Hardware.FullDuplexEnable = TRUE;

	} 
    else if ((PhyAnar & MII_ANAR_100TX) && (PhyAnlpar & MII_ANLPAR_100TX)) {
		pAdapter->Hardware.MIIPhyUsed = MII_100TX ;
		*handles100Mbitptr = TRUE;
		pAdapter->Hardware.FullDuplexEnable = FALSE;
    } 
    else if ((PhyAnar & MII_ANAR_10TFD) && (PhyAnlpar & MII_ANLPAR_10TFD)) {
		pAdapter->Hardware.MIIPhyUsed = MII_10TFD ;
		pAdapter->Hardware.FullDuplexEnable = TRUE;
    	*handles100Mbitptr = FALSE;
	} 
   	else if ((PhyAnar & MII_ANAR_10T) && (PhyAnlpar & MII_ANLPAR_10T)) {
		pAdapter->Hardware.MIIPhyUsed = MII_10T ;
		pAdapter->Hardware.FullDuplexEnable = FALSE;
		*handles100Mbitptr = FALSE;	
    }
	else if (!(PhyAner & MII_ANER_LPANABLE)) {
	//
	// Link partner is not capable of auto-negotiation. Fall back to 10HD.
	//
	pAdapter->Hardware.MIIPhyUsed = MII_10T ;
	pAdapter->Hardware.FullDuplexEnable = FALSE;
	*handles100Mbitptr = FALSE;	
	}
	else 
		return FALSE;

    return TRUE;
}






/*++

Routine Name:

    tc90x_FreeAdapterResources.

Routine Description:

    This routine frees up the adapter resources.

Arguments:

	Device - Pointer to the device structure.

Return Value:

    None

--*/

VOID
tc90x_FreeAdapterResources(
	IN PNIC_INFORMATION Adapter
	)
{
	PNIC_INFORMATION pAdapter = Adapter;
	PDEVICE device = pAdapter->Device;
	PUPD_LIST_ENTRY currentUPDVirtual = pAdapter->HeadUPDVirtual;
	
	
	DBGPRINT_FUNCTION(("FreeAdapterResources: IN\n"));

	if (pAdapter->ResourcesReserved & NIC_INTERRUPT_REGISTERED) {

		DBGPRINT_INITIALIZE(("Releasing interrupt\n"));
		free_irq(device->irq, device);
		pAdapter->ResourcesReserved &= ~NIC_INTERRUPT_REGISTERED;

	}

	if (pAdapter->ResourcesReserved & WAIT_TIMER_REGISTERED) {

		DBGPRINT_INITIALIZE((KERN_CRIT "Releasing WaitTimer\n"));
		if (del_timer(&WaitTimer))	
			/* Timer has already been queued. */
			DBGPRINT_ERROR(("WaitTimer already queued\n"));
		pAdapter->ResourcesReserved &= ~WAIT_TIMER_REGISTERED;
	}

	if (pAdapter->ResourcesReserved & NIC_TIMER_REGISTERED) {

		DBGPRINT_INITIALIZE((KERN_CRIT "Releasing Timers\n"));
		if (del_timer(&pAdapter->Resources.Timer)) {		
			//
			// Timer has already been queued.
			//
			DBGPRINT_ERROR(("Timer already queued\n"));
		}
		pAdapter->ResourcesReserved &= ~NIC_TIMER_REGISTERED;
		if (del_timer(&WaitTimer))					
			DBGPRINT_ERROR(("WaitTimer already queued\n"));
	}

	if (pAdapter->ResourcesReserved & NIC_SHARED_MEMORY_ALLOCATED) {

		DBGPRINT_INITIALIZE((KERN_CRIT "Releasing memory\n"));

		currentUPDVirtual = pAdapter->HeadUPDVirtual;
		//
		// Release the SKBs allocated
		//
		while (1) {

			if (currentUPDVirtual->SocketBuffer) 
#if LINUX_VERSION_CODE >= 0x20200
				dev_kfree_skb(
					currentUPDVirtual->SocketBuffer
					);
#else
				dev_kfree_skb(
					currentUPDVirtual->SocketBuffer,
					GFP_ATOMIC
					);

#endif
			currentUPDVirtual = currentUPDVirtual->Next;
			if (currentUPDVirtual == pAdapter->HeadUPDVirtual)
					break;	
		}

		kfree(pAdapter->Resources.SharedMemoryVirtual);
		pAdapter->ResourcesReserved &= ~NIC_SHARED_MEMORY_ALLOCATED;
	}


	if (pAdapter->ResourcesReserved & NIC_IO_PORT_REGISTERED) {

		DBGPRINT_INITIALIZE((KERN_CRIT "Releasing IO port region\n"));
		release_region(device->base_addr, 0x80);
		pAdapter->ResourcesReserved &= ~NIC_IO_PORT_REGISTERED;
	}	
	DBGPRINT_FUNCTION(("FreeAdapterResources: OUT\n"));
}


/*++

RoutineName:

    tc90x_RegisterAdapter.

Routine Description:

    This routine registers the adapter resources with Linux.

Arguments:

	Device - Pointer to the device structure.

Return Value:

    NIC_STATUS_SUCCESS if the adapter resources could be registered.
    NIC_STATUS_FAILURE if the adapter resources could not be registered.

--*/

NIC_STATUS
tc90x_RegisterAdapter(
	IN PNIC_INFORMATION Adapter
	)
{
	PNIC_INFORMATION pAdapter = Adapter;
	PDEVICE device = pAdapter->Device;

	DBGPRINT_FUNCTION(("RegisterAdapter: IN\n"));
	//
	// Use the now-standard shared IRQ implementation.
	//
	DBGPRINT_INITIALIZE(("SA_SHIRQ  registering IRQ %x\n", device->irq));
	if (request_irq(
		device->irq, 
		&NICInterrupt, 
		SA_SHIRQ, 
		device->name, 
		device)) {
		
		DBGPRINT_ERROR(("RegisterAdapter: IRQ registration failed\n"));
		return NIC_STATUS_FAILURE;

	}

	pAdapter->ResourcesReserved|= NIC_INTERRUPT_REGISTERED; 

	DBGPRINT_FUNCTION(("RegisterAdapter: OUT\n"));
	return NIC_STATUS_SUCCESS;
}

/*++

Routine Name:

    tc90x_GetAdapterProperties.

Routine Description:

    This routine sets up the adapter.

Arguments:

	Device - Pointer to the device structure.

Return Value:

    NIC_STATUS_SUCCESS if the adapter could be set up successfully.
    NIC_STATUS_FAILURE if the adpater could not be set up successfully.

--*/

NIC_STATUS
tc90x_GetAdapterProperties(
	IN PNIC_INFORMATION Adapter
    	)

{
	PNIC_INFORMATION pAdapter = Adapter;
	PDEVICE device = pAdapter->Device;

	NIC_STATUS nicStatus;
	USHORT eepromValue;
	USHORT intStatus;
	COMPATABILITY_WORD compatability;
	SOFTWARE_INFORMATION_1 information1;
	SOFTWARE_INFORMATION_2 information2;
	CAPABILITIES_WORD capabilities;
	UCHAR value, index;

	DBGPRINT_FUNCTION(("GetAdapterProperties: IN \n"));
    //
    // Check the ASIC type. Udp checksum should not be used in
    // pre-Tornado cards-  JRR
    //

    if ((pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_9055) ||
        (pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_9004) ||
        (pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_9005) ||
        (pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_9006) ||
        (pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_9058) ||
        (pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_900A) ||
        (pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_905A) || 
        (pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_4500) || 
        (pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_7646) || 
	(pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_9800)) { 

        pAdapter->Hardware.BitsInHashFilter = 0x40;
    }
    else {

        pAdapter->Hardware.BitsInHashFilter = 0x100;
        pAdapter->Hardware.UDPChecksumErrDone = TRUE;
    }

	pAdapter->Hardware.Status = HARDWARE_STATUS_WORKING;
	pAdapter->Hardware.LinkSpeed = LINK_SPEED_100;

	//
	// Make sure we can see the adapter.  Set up for window 7, and make
	// sure the window number gets reflected in status. 
	//
	NIC_COMMAND(
		pAdapter, 
		COMMAND_SELECT_REGISTER_WINDOW | REGISTER_WINDOW_7);

	intStatus = NIC_READ_PORT_USHORT(
			pAdapter, 
			INTSTATUS_COMMAND_REGISTER);

	DBGPRINT_INITIALIZE(("intStatus =%x\n", intStatus));
	DBGPRINT_INITIALIZE(("ioBase =%x\n", (INT)pAdapter->IoBaseAddress));

	if ((intStatus & REGISTER_WINDOW_MASK) != 
	    (REGISTER_WINDOW_7 << 13)) {

		DBGPRINT_ERROR(("SetupAdapter: Window selection failure\n"));
		DBGPRINT_INITIALIZE(("SetupAdapter: Out with error\n"));
	    	return NIC_STATUS_FAILURE;
    	}
	//
	// ----------------- Read the compatability level ----------
	//

	nicStatus = tc90x_ReadEEPROM(
                        pAdapter,
                        EEPROM_COMPATABILITY_WORD,

⌨️ 快捷键说明

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