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

📄 lan91c111_miniport.c

📁 wince LAN91C11 网卡驱动 wince 4.2 5.0 6.0都可用,没有原来驱动引起PPPOE拨号引起网络崩溃问题
💻 C
📖 第 1 页 / 共 2 页
字号:
		return (NDIS_STATUS_FAILURE);
	}
	
	if (Adapter->AllocIntPending)
	{
		PrintDebugMsg(1, (TEXT("LAN91C111: Allocation in process\r\n")));
		PrintDebugMsg(1, (TEXT("LAN91C111: <== Miniport Send\r\n")));        
		Packet			= (MINIPORT_PACKET *) pNDISPacket->MiniportReserved;
		Packet->Next	= (MINIPORT_PACKET *) 0;
		QuePacket(Adapter->AllocPending, Packet);
		Adapter->AllocIntPending = TRUE;
		NdisMSynchronizeWithInterrupt((PNDIS_MINIPORT_INTERRUPT)&Adapter->InterruptInfo, (PVOID)AllocIntEnabler, (PVOID)Adapter);
		return (NDIS_STATUS_PENDING);
	}
	
	RetVal = LAN91C111_AdapterAllocBuffer(Adapter, &PacketNumber);
	if (RetVal == NDIS_STATUS_SUCCESS)
		LAN91C111_AdapterWriteData(Adapter, pNDISPacket, PacketNumber);
	else
	{
		Packet			= (MINIPORT_PACKET *) pNDISPacket->MiniportReserved;
		Packet->Next	= (MINIPORT_PACKET *) 0;
		QuePacket(Adapter->AllocPending, Packet);
		Adapter->AllocIntPending = TRUE;
		NdisMSynchronizeWithInterrupt((PNDIS_MINIPORT_INTERRUPT)&Adapter->InterruptInfo, (PVOID)AllocIntEnabler, (PVOID)Adapter);
		PrintDebugMsg(ZONE_TX, (TEXT("LAN91C111: Allocation FAILED - Packet Queued\r\n")));
		PrintDebugMsg(ZONE_TX, (TEXT("LAN91C111: <== Miniport Send\r\n")));        
		return (NDIS_STATUS_PENDING);
	}		
	PrintDebugMsg(ZONE_TX, (TEXT("LAN91C111 <== Miniport Send\r\n")));
#ifdef SMSC_AUTO_RELEASE
	return (NDIS_STATUS_SUCCESS);
#else
	return (NDIS_STATUS_PENDING);
#endif
}

/*
Function Name : LAN91C111_MiniportReset
Description   : This function is a required function that issues a hardware reset 
to the network adapter and/or resets the driver抯 software state.
Parameters    : 
PBOOLEAN    AddressingReset -Points to a variable that MiniportReset
sets to TRUE if the NDIS library should call 
MiniportSetInformation to restore addressing information 
to the current values. 
NDIS_HANDLE AdapterContext - Handle to the adapter structure

  Return Value  :
  NDIS_STATUS Status
*/
NDIS_STATUS	LAN91C111_MiniportReset		(
										 PBOOLEAN    AddressingReset,
										 NDIS_HANDLE AdapterContext
										 )
{
	NDIS_STATUS          Status=NDIS_STATUS_SUCCESS;
	MINIPORT_ADAPTER	*Adapter = (MINIPORT_ADAPTER *) AdapterContext;
	USHORT				TempWord;
	ULONG				IOBase;
	INT					Counter;
	
	RETAILMSG(1, (TEXT("LAN91C111 ==> Miniport Reset\r\n")));

	IOBase = Adapter->IOBase;

	//Clear the card's interrupt mask register
    NdisRawWritePortUshort( IOBase + BANK_SELECT, 2 );
    NdisRawWritePortUshort( IOBase + BANK2_INT_STS, (USHORT)0 );

	//Just Reset the MMU and clear the Statistics...
	NdisRawWritePortUshort( IOBase + BANK2_MMU_CMD, CMD_RIS);
	NdisRawReadPortUshort(IOBase + BANK2_MMU_CMD, (PUSHORT) &TempWord);
	while (TempWord & MMUCMD_BUSY)
		NdisRawReadPortUshort(IOBase + BANK2_MMU_CMD, (PUSHORT) TempWord);

	
	Adapter->State = RESET_STATE;
	
	//Restore Multicast Hash Table.
    NdisRawWritePortUshort(IOBase + BANK_SELECT, (USHORT) 3 );
	for(Counter = 0;Counter < 8;Counter += 2)
		NdisRawWritePortUshort(IOBase + BANK3_MT01 + Counter, *(&Adapter->HashTable[Counter]));
	
	//Setup Receive control Register
	Adapter->RCVAllMulticast = TRUE;
	Adapter->RCVBroadcast = TRUE;
	Adapter->PromiscuousMode = FALSE;
	Adapter->RCR = RCR_RX_EN;
	Adapter->RCR |= RCR_STRP_CRC;
	NdisRawWritePortUshort( IOBase + BANK_SELECT, (USHORT) 0);
	NdisRawWritePortUshort(IOBase + BANK0_RCR, Adapter->RCR);
	
	
	//Clear all the statistic counter
	Adapter->Stat_RxError		=
		Adapter->Stat_RxOK		=
		Adapter->Stat_RxOvrn	=
		Adapter->Stat_TxError	=
		Adapter->Stat_TxOK		= 
		Adapter->Stat_AlignError =
		Adapter->Stat_MultiColl = 
		Adapter->Stat_SingleColl = 0;
	
    //Initialize Queues.
    ClearPacketQue(Adapter->AckPending);
	ClearPacketQue(Adapter->AllocPending);
	Adapter->AllocIntPending = FALSE;
	
	
	//Setup Transmit Control Register
	Adapter->TCR = (USHORT)(TCR_TX_ENA | TCR_PAD_EN | TCR_MON_CSN);
	if (Adapter->Duplex == FULL_DUPLEX)
		Adapter->TCR |= TCR_SWFDUP;
	else
		Adapter->TCR &= (~TCR_SWFDUP);
	NdisRawWritePortUshort(IOBase+BANK_SELECT, (USHORT) 0);
	NdisRawWritePortUshort( IOBase + BANK0_TCR, Adapter->TCR);
	
	//Enable the interrupts !!
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT,(USHORT) 2);
	NdisRawWritePortUshort( Adapter->IOBase + BANK2_INT_STS,(USHORT)(ENABLED_INTS << 8));
	
	Adapter->State = NORMAL_STATE;
	
	PrintDebugMsg(ZONE_INIT, (TEXT("LAN91C111 <== Miniport Reset\r\n")));
	return Status;
}

/*
Function Name : LAN91C111_AdapterAllocBuffer
Description   : Allocates a buffer for TX pacet. The PacketNumber holds the packet allocated.
Return Value  : NDIS_STAUS_SUCCESS if allocation is success
				NDIS_STATUS_FAILURE if allocation failed, in this case PacketNumber is invalid
*/
NDIS_STATUS LAN91C111_AdapterAllocBuffer(MINIPORT_ADAPTER *Adapter, USHORT *PacketNumber)
{
	ULONG				IOBase;
	UINT				AllocateOk;     
	USHORT				AllocSts;
		
	*PacketNumber = -1;
	IOBase = Adapter->IOBase;

	//Allocate memory
	NdisRawWritePortUshort(IOBase + BANK_SELECT,2);
	NdisRawWritePortUshort(IOBase + BANK2_MMU_CMD,(USHORT)(CMD_ALLOC));
	AllocateOk = MMU_WAIT;
	while(AllocateOk)
	{
		NdisRawReadPortUshort(IOBase + BANK2_INT_STS, (PUSHORT) &AllocSts);
		if(AllocSts & INT_ALLOC) break;
		AllocateOk--;
	}
	
	if (!(AllocSts & INT_ALLOC))
		return (NDIS_STATUS_FAILURE);
	else
	{
		NdisRawReadPortUshort(IOBase + BANK2_PNR, PacketNumber);
		*PacketNumber = *PacketNumber >> 8; //allocated packet number in higher byte
		PrintDebugMsg(ZONE_TX, (TEXT("\tLAN91C111: Packet #%d Allocated\r\n"), *PacketNumber));
		return (NDIS_STATUS_SUCCESS);
	}	
}


/*
Function Name : LAN91C111_AdapterWriteData
Description   : Write the packet data to the packet specified int he PacketNumber parameter.
Return Value  : NDIS_STAUS_SUCCESS 
*/
NDIS_STATUS LAN91C111_AdapterWriteData(
							 MINIPORT_ADAPTER *Adapter,
							 PNDIS_PACKET pNDISPacket,
							 UINT         PacketNumber
							 )
{
	PNDIS_BUFFER            pCurrentBuffer;
	ULONG                   IOBase;
	UINT                    PacketLength,
		CurrentBufferLength;
	PUCHAR              pCurrentBufferAddr,
		ptemp;
	UCHAR               OddByte=0;
	MINIPORT_PACKET     *Packet;
	USHORT              ControlWord;
			
	PrintDebugMsg(ZONE_TX, (TEXT("LAN91C111 ==> AdapterWriteData\r\n")));
	
	IOBase = Adapter->IOBase;
	
	//Make sure that the packet size is in legal limits.
	NdisQueryPacket(pNDISPacket,NULL,NULL,&pCurrentBuffer,(PUINT) &PacketLength);
	
	NdisRawWritePortUshort(IOBase + BANK_SELECT,2);
	//Write the allocated packet no. to PNR
	NdisRawWritePortUshort(IOBase + BANK2_PNR, PacketNumber);
	NdisStallExecution(1);
	
	//Set the pointer register to TX + AUTO_INCR + WRITE
	NdisRawWritePortUshort(IOBase + BANK2_PTR, PTR_AUTO);
	NdisStallExecution(1); //Wait for 1us (as per the Data sheet atleast 370ns)
	
	//Write the status word (placeholder)
	NdisRawWritePortUshort(IOBase + BANK2_DATA1, (USHORT) 0);
	
	//Write the byte count + packet overhead
	NdisRawWritePortUshort(IOBase + BANK2_DATA1, (USHORT)(PacketLength+FRAME_OVERHEAD));
	
	//Query for the first non-zero buffer
	NdisQueryPacket(pNDISPacket,NULL,NULL,&pCurrentBuffer,(PUINT) &PacketLength);
	NdisQueryBuffer(pCurrentBuffer, (PVOID*)&pCurrentBufferAddr, &CurrentBufferLength);
	while ((pCurrentBuffer) && (CurrentBufferLength == 0))
	{
		NdisGetNextBuffer(pCurrentBuffer, (PNDIS_BUFFER *)&pCurrentBuffer);
		NdisQueryBuffer(pCurrentBuffer, (PVOID*)&pCurrentBufferAddr, &CurrentBufferLength);
	}
	
	//Copy the data to the TxBuffer   
	ptemp = Adapter->TxBuffer;
	do
	{
		NdisMoveMemory(ptemp, pCurrentBufferAddr, (ULONG)CurrentBufferLength);
		(ULONG)ptemp += CurrentBufferLength;
		NdisGetNextBuffer (pCurrentBuffer, (PNDIS_BUFFER *)&pCurrentBuffer);  //Get the next buffer
		NdisQueryBuffer (pCurrentBuffer, (PVOID*)&pCurrentBufferAddr, &CurrentBufferLength);        
	}
	while(pCurrentBuffer);

#ifdef SMSC_32BIT_RW
	{
		NdisRawWritePortBufferUlong(IOBase + BANK2_DATA1, Adapter->TxBuffer, PacketLength>>2);
		if ((PacketLength & 0xFFFE) % 4)
		{
			USHORT LastWord;
			if (PacketLength & 1)
				LastWord = *((PUSHORT)(Adapter->TxBuffer+PacketLength-3));
			else
				LastWord = *((PUSHORT)(Adapter->TxBuffer+PacketLength-2));
			NdisRawWritePortUshort(IOBase + BANK2_DATA1, LastWord);
		}
	}
#else
	//Write the data to the chip
	NdisRawWritePortBufferUshort(IOBase + BANK2_DATA1, Adapter->TxBuffer, PacketLength>>1);
#endif
	
	//If odd length packet
	if (PacketLength & 1)
	{
		ptemp = Adapter->TxBuffer;
		OddByte = ptemp[PacketLength-1];
		ControlWord = ((CTL_BYTE_ODD | CTL_BYTE_CRC) << 8)| OddByte;
	}
	else
		ControlWord = (CTL_BYTE_CRC<< 8);
	//Write the control word to the chip
	NdisRawWritePortUshort(IOBase+BANK2_DATA1, (USHORT)ControlWord);
    
	//Now enque the packet for transmission..
	NdisRawWritePortUshort( IOBase + BANK_SELECT, (USHORT) 2);
	NdisRawWritePortUshort (IOBase+BANK2_MMU_CMD, CMD_ENQ_TX);   

	PrintDebugMsg(ZONE_TX, (TEXT("LAN91C111 <== AdapterWriteData\r\n")));
#ifdef SMSC_AUTO_RELEASE
	return (NDIS_STATUS_SUCCESS); 
#else
	Packet			= (MINIPORT_PACKET *) pNDISPacket->MiniportReserved;
	Packet->Next	= (MINIPORT_PACKET *) 0;
	QuePacket(Adapter->AckPending, Packet);
	return (NDIS_STATUS_PENDING);
#endif
}


/*
Function Name : LAN91C111_MiniportCheckforHang
Description   : This function checks for the internal state of the chip. If one or more onchip buffers
				are unaccounted, it returns TRUE indicatin to the NDIS layer to call the AdapterReset
				function. Generally this funciton is called every 2 seconds, by the NDIS layer.

				This is an optional miniport functions. If not used, the NDIS layer judges the drivers
				unresponsivenss to call the AdapterReset function.

				Basically this functions checks if there are any TX or RX packets are pending. If pending 
				it returns FALSE, else it checks for the empty buffer space. If the buffer space is less than
				4, then it returns TRUE.
Return Value  : TRUE - If the chip needs to be reset, else FALSE
*/							 
BOOLEAN LAN91C111_MiniportCheckforHang(
									   NDIS_HANDLE AdapterContext
									   )
{
	MINIPORT_ADAPTER        *Adapter = (MINIPORT_ADAPTER *) AdapterContext;
	ULONG IOBase;
	USHORT FIFO, MIR;
	BOOLEAN RetVal = FALSE;
	IOBase = Adapter->IOBase;
	
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT,2);
	NdisRawReadPortUshort(Adapter->IOBase + BANK2_FIFOS, &FIFO);
	NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT,(USHORT) 0);
	NdisRawReadPortUshort(Adapter->IOBase + BANK0_MIR, &MIR);
	
	if ((!(Adapter->AckPending.First)) && (Adapter->AllocIntPending == FALSE))
	{
		//Nothing in TX and RX
		//And atleast one slot is full, then reset.
		if (((MIR & 0xFF00) != 0x0400) && (FIFO & 0x8000))
			RetVal = TRUE;
	}
	return RetVal;
}

⌨️ 快捷键说明

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