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

📄 lan91c111end.c

📁 LAN91C111驱动源码,使用C语言写成
💻 C
📖 第 1 页 / 共 5 页
字号:

				pDrvCtrl->pRxWriteIndex->len = len;
				pDrvCtrl->pRxWriteIndex->pData = pData;

			/* update indices */

	       		if(pDrvCtrl->pRxWriteIndex < pDrvCtrl->pRxBase + RX_PACKETS - 1)
	         		pDrvCtrl->pRxWriteIndex++;
	       		else
	           		pDrvCtrl->pRxWriteIndex = pDrvCtrl->pRxBase;

	       		if (pDrvCtrl->rxHandling == FALSE)
	        	{
	           		pDrvCtrl->rxHandling = TRUE;
					netJobAdd ((FUNCPTR)lan91c111HandleRcvInt, (int)pDrvCtrl,0,0,0,0);
				}
				else
				{
					DRV_LOG (DRV_DEBUG_ERR, "airoNetInt: Could not add to tNetTask\n", 1, 2, 3, 4, 5, 6);
				}
#endif

            	SYS_OUT_SHORT(MmuPort, (USHORT) CMD_REM_REL_TOP);
	        	do
	        	{
               		SYS_IN_SHORT(MmuPort, (PUSHORT) &tempWord);
            	} while (tempWord & MMUCMD_BUSY);

	        	{
					DRV_LOG(DRV_DEBUG_RX," RX_DIR len = %d\n",len,2,3,4,5,6);

	       		}
    			SYS_IN_SHORT(IOBase + BANK2_FIFOS, &FifoPort);

			} /* End While */
		} /* done : RX_INT */
		else if(IntrSts & INT_TX_CMP) /* start : TX_INT */
		{
        	DRV_LOG (DRV_DEBUG_INT, " TX \n",1, 2, 3, 4, 5, 6);
        	SYS_IN_SHORT( IOBase + BANK2_FIFOS, &tempWord );
        	PacketNumber = (CHAR)LOBYTE(tempWord);
        	SYS_OUT_SHORT(IOBase + BANK2_PNR, (USHORT) PacketNumber);
	    /*
	     *  Retrieve packet status and range.
	     *
	     */
        	SYS_OUT_SHORT(IOBase + BANK2_PTR, (USHORT) (PTR_AUTO | PTR_READ));
        	Count = PTR_WAIT;
	    	while(Count--)
            	SYS_IN_SHORT((IOBase + BANK2_PTR), (PUSHORT) &Pointer);
        	SYS_IN_SHORT(IOBase + BANK2_DATA1, (PUSHORT) &PacketStatus);
			SYS_OUT_SHORT(IOBase + BANK2_MMU_CMD, (USHORT) CMD_REL_SPEC);
			sysOutByte(IOBase + BANK2_INT_STS, INT_TX_CMP);lan91c111Delay();

			if(pDrvCtrl->pTxReadIndex->pMblk != NULL)
				netJobAdd ((FUNCPTR)lan91c111Send,(int)pDrvCtrl,0,0,0,0);
	    /*
	     *  Update statistics.
	     *
	     */
	    	if(PacketStatus & TFS_ERROR)
	    	{
	        /*
	         * Lost carrier status be set when doing HCT test, that cause few
	         * items testing failed.
	         */
	        	;
		    	if (!pDrvCtrl->errorHandling)
					if (netJobAdd ((FUNCPTR) lan91c111HandleError, (int) pDrvCtrl,PacketStatus, 3, 4, 5) == OK)
			    		pDrvCtrl->errorHandling = TRUE;
    		}
    	else
    	{
        	if(PacketStatus & TFS_BCAST)
        	{
        	}
        	else if(PacketStatus & TFS_MCAST)
        	{
        	}
        	else
        	{
        	}
        	if(PacketStatus & TFS_DEFER)
				;
        	if(PacketStatus & TFS_MULTICOL)
				;
        	if(PacketStatus & TFS_1COL)
            	;
    	}
	} /* done : TX_INT */
	else if(IntrSts & INT_ALLOC) /* start : ALLOC_INT */
	{
  		if(Adapter->AllocPending == TRUE)
		{
			DRV_LOG (DRV_DEBUG_INT, " ALLOC_INT ",1, 2, 3, 4, 5, 6);
        	Adapter->AllocPending = FALSE;
			netJobAdd ((FUNCPTR) lan91c111Send, (int) pDrvCtrl,1,0,0,0);
		}

        /*-----------------3/15/01 3:51PM-------------------
         * Acknowledge of ALLOC Interrupt is not possible
         * --------------------------------------------------*/

        /* SYS_OUT_SHORT(Adapter->IOBase + BANK2_INT_STS, INT_ALLOC);*/
        SYS_OUT_SHORT(Adapter->IOBase + BANK_SELECT, 2);
		SYS_IN_SHORT(Adapter->IOBase + BANK2_INT_STS, &tempWord);

		/* 0xff00 would keep the higher byte as it is and the lower
			byte will be made zero. This is what we need as we will
			be touching the Int Ack Register which will not be modified
			if written with a zero */
		/* We are disabling Alloc Int now */

		tempWord = tempWord & ((~((USHORT)(INT_ALLOC)))<<8);
		SYS_OUT_SHORT(Adapter->IOBase + BANK2_INT_STS, tempWord);
	} /* done : ALLOC_INT */
    else if (IntrSts & INT_EPH_INT) /* start : EPHINT */
	{

		/* LE Enable and TXENA code that follows is taken from
				AdapterEnableTransmitter() */
		SYS_OUT_SHORT(Adapter->IOBase + BANK_SELECT, 1 );
        SYS_IN_SHORT(Adapter->IOBase + BANK1_CTL, &tempWord );
		tempWord &= ~CTL_LE_EN;
        SYS_OUT_SHORT(Adapter->IOBase + BANK1_CTL, tempWord);
		tempWord |= CTL_LE_EN;
        SYS_OUT_SHORT(Adapter->IOBase + BANK1_CTL, tempWord);
        SYS_OUT_SHORT(Adapter->IOBase + BANK_SELECT, 0 );

		/* Enable Transmitter as it would have been shut off because of Tx Errors */
        SYS_IN_SHORT(Adapter->IOBase + BANK0_TCR, (PUSHORT) &tempWord);
	    tempWord |= TCR_TX_ENA;
        SYS_OUT_SHORT(Adapter->IOBase + BANK0_TCR, tempWord);

        SYS_IN_SHORT(Adapter->IOBase + BANK0_STS, (PUSHORT) &EphStatus);
		Adapter->EphStatus = EphStatus;
	    /*
	     *  Count for statistics.
	     *
	     */
        DRV_LOG (DRV_DEBUG_INT, "EPH INT :EPH Status = %x\n",EphStatus, 2, 3, 4, 5, 6);

	    if( Adapter->EphStatus & TFS_UNDERRUN )
		{
            SYS_OUT_SHORT(Adapter->IOBase + BANK_SELECT, (USHORT) 2 );
	        if( Adapter->TxUnderRunFixed )
	            Adapter->TxUnderRunFixed = FALSE;
	        else
			{
                SYS_OUT_SHORT(Adapter->IOBase + BANK2_MMU_CMD, (USHORT) CMD_ENQ_TX);
	            Adapter->TxUnderRunFixed = TRUE;
	        }
	        Adapter->ETxThrshInc += ThresholdIncreament;
	        Adapter->EarlyTxThreshold = Adapter->ETxThrshInc + Adapter->ETxThrshBase;
	    }

	/* <- This will be done at TX_INT */
		if(Adapter->LinkStatusChange != (Adapter->EphStatus & TFS_LINKERROR))
		{
			if(Adapter->EphStatus & TFS_LINKERROR)
			{
				Adapter->LinkChange = MEDIA_CONNECT;
                DRV_LOG (DRV_DEBUG_INT, "\nEPH Int : Link OK Transition : MEDIA_CONNECT %x\n",1, 2, 3, 4, 5, 6);
			}
			else
			{
				Adapter->LinkChange = MEDIA_DISCONNECT;
                DRV_LOG (DRV_DEBUG_INT, "\nEPH Int : Link OK Transition : MEDIA_DISCONNECT %x\n",1, 2, 3, 4, 5, 6);
			}
			Adapter->LinkStatusChange = Adapter->EphStatus & TFS_LINKERROR;
		}
	}	/* done : EPHINT */
    else if(IntrSts & INT_MDINT)    /* start : MDINT */
	{
		USHORT ledValue = 0;
	    SYS_OUT_SHORT(Adapter->IOBase + BANK_SELECT, 2);

		sysOutByte(Adapter->IOBase + BANK2_INT_STS, INT_MDINT);lan91c111Delay();
		DefaultVal = ReadPhyRegister( (USHORT)Adapter->IOBase, 
								(UCHAR)Adapter->TempPhyAddr, PHY_STATUS_OUTPUT );
		DRV_LOG (DRV_DEBUG_INT, "MD Int : Link Detect : Phy Status Register %x\n",DefaultVal , 2, 3, 4, 5, 6);


		if(DefaultVal & 0x8000)
		{
			if(Adapter->LinkChange == MEDIA_DISCONNECT)
			{
				Adapter->LinkChange = MEDIA_CONNECT;
				if(DefaultVal & 0x80)
				{
						Adapter->Speed100 = SPEED100;
						ledValue =0x0000;
				}
				else
				{
						Adapter->Speed100 = SPEED10;
						ledValue=0x0020;
				}
				if(DefaultVal & 0x40)
				{
						Adapter->Duplex = FULL_DUPLEX;
						ledValue |= 0x0000;
				}
				else
				{
						Adapter->Duplex = HALF_DUPLEX;
						ledValue |= 0x0004;
				}

				SYS_OUT_SHORT(Adapter->IOBase + BANK_SELECT, 0);
				SYS_IN_SHORT(Adapter->IOBase + BANK0_RPCR,&DefaultVal);
				SYS_OUT_SHORT(Adapter->IOBase + BANK0_RPCR,((DefaultVal & 0xff00) | ledValue) );

				netJobAdd ((FUNCPTR) AdapterReset, (int) pDrvCtrl,0,0,0,0);				
								
                DRV_LOG (DRV_DEBUG_INT, "\nMD Int : Link Detect : MEDIA_CONNECT\n",
					1, 2, 3, 4, 5, 6);
			}
			else
			{
				Adapter->LinkChange = MEDIA_DISCONNECT;
                DRV_LOG (DRV_DEBUG_INT, "\nMD Int : Link Detect : MEDIA_DISCONNECT \n",
					1, 2, 3, 4, 5, 6);
			}
		}
		else
		{
			if(Adapter->LinkChange == MEDIA_DISCONNECT)
				Adapter->LinkChange = MEDIA_DISCONNECT;
			else
				Adapter->LinkChange = MEDIA_CONNECT;
		}
		Adapter->LinkStatusChange = Adapter->EphStatus & TFS_LINKERROR;
	}	/* done : MDINT */
	else if(IntrSts & INT_RX_OVRN)	/* start : RX_OVRINT */
	{
	    /* Overflow sets receive abort.  Clear it now.*/

		   SYS_OUT_SHORT(Adapter->IOBase + BANK_SELECT, (USHORT) 0);
  		   SYS_OUT_SHORT(Adapter->IOBase + BANK0_RCR, Adapter->Rcr);
	       SYS_OUT_SHORT(Adapter->IOBase + BANK_SELECT, (USHORT) 2);
           SYS_OUT_SHORT(Adapter->IOBase ,CMD_RIS);
           sysOutByte(Adapter->IOBase + BANK2_INT_STS, INT_RX_OVRN);lan91c111Delay();
           DRV_LOG (DRV_DEBUG_INT, " Rx_OverRun ",1, 2, 3, 4, 5, 6);

    }   /* done : RX_OVRINT */
  }

  netJobAdd ((FUNCPTR)lan91c111Send,(int)pDrvCtrl,0,0,0,0);	/* kumar */

lan91c111IntExit:

    SYS_OUT_SHORT(IOBase + BANK2_PTR, SavedPtr);   /* restore pointer reg. */
    SYS_OUT_SHORT(IOBase + BANK2_PNR, SavedPnr);   /* restore packet number reg. */
    SYS_OUT_SHORT(IOBase + BANK_SELECT, SavedBank);/* restore Bank select reg. */
	CACHE_PIPE_FLUSH ();
	DRV_LOG(DRV_DEBUG_INT,"-----------DONE INT--------------------\n",1,2,3,4,5,6);


#endif
    return ;
}

/*******************************************************************************
* lan91c111Recv - process the next incoming packet
*
* Handle one incoming packet.  The packet is checked for errors.
*
* RETURNS: N/A.
*/
 STATUS lan91c111Recv
    (
    LAN91C111END_DEVICE *pDrvCtrl/*,
	char *pData,
	UINT len*/
    )
    {
    M_BLK_ID 	pMblk;
    CL_BLK_ID	pClBlk;
	int len;

    /* Grab a cluster block to marry to the cluster we received. */

    if ((pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) == NULL)
        {
        netClFree (pDrvCtrl->endObj.pNetPool, pDrvCtrl->pRxReadIndex->pData);
		DRV_LOG (DRV_DEBUG_ERR, "lan91c111Recv: Out of Cluster Blocks!\n",
				1, 2, 3, 4, 5, 6);
		END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);
		goto cleanRXD;
        }

    /*
     * OK, let's get an M_BLK_ID and marry it to the
     * one in the ring.
     */

    if ((pMblk = mBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA)) == NULL)
        {
        netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk);
        netClFree (pDrvCtrl->endObj.pNetPool, pDrvCtrl->pRxReadIndex->pData);
		DRV_LOG (DRV_DEBUG_ERR, "lan91c111Recv: Out of M Blocks!\n",
				1, 2, 3, 4, 5, 6);
		END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);
		goto cleanRXD;
        }

    /* Join the cluster to the MBlock */

    netClBlkJoin (pClBlk,(char*) pDrvCtrl->pRxReadIndex->pData, lan91c111ClDescTbl[0].clSize, NULL, 0, 0, 0);
    netMblkClJoin (pMblk, pClBlk);

	len = pDrvCtrl->pRxReadIndex->len;

    pMblk->mBlkHdr.mData = (char *)(pDrvCtrl->pRxReadIndex->pData + pDrvCtrl->offset);
    pMblk->mBlkHdr.mLen = len ;
    pMblk->mBlkHdr.mFlags |= M_PKTHDR;
    pMblk->mBlkPktHdr.len = len;

#if PING_DEBUG
	if(len > 70 && len <= 100)
		memcpy((void *)RxBuff, (void *)pMblk->mBlkHdr.mData, len);
#endif

    DRV_LOG (DRV_DEBUG_RX, "RX : Pkt : Len %d\n",
			len, 2, 3, 4, 5, 6);

	pDrvCtrl->pRxReadIndex->pData = NULL;	/* free the slot */

    if(pDrvCtrl->pRxReadIndex < pDrvCtrl->pRxBase + RX_PACKETS - 1)
		pDrvCtrl->pRxReadIndex++;
	else
		pDrvCtrl->pRxReadIndex = pDrvCtrl->pRxBase;


    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);

	END_RCV_RTN_CALL(&pDrvCtrl->endObj, pMblk);

cleanRXD:
	return (OK);
    }

#if 1
/*******************************************************************************
* lan91c111HandleRcvInt - task level interrupt service for input packets
*
* This routine is called at task level indirectly by the interrupt
* service routine to do any message received processing.
*
* The double loop is to protect against a race condition where the interrupt
* code see rxHandling as TRUE, but it is then turned off by task code.
* This race is not fatal, but does cause occassional delays until a second
* packet is received and then triggers the netTask to call this routine again.
*
* RETURNS: N/A.
*/

 void lan91c111HandleRcvInt
    (
    LAN91C111END_DEVICE *pDrvCtrl	/* interrupting device */
    )
    {
    UINT receiveReady;
	int loopCount=0;

    pDrvCtrl->rxHandling = TRUE;


    do {

        lan91c111Recv (pDrvCtrl);
        receiveReady = pDrvCtrl->pRxReadIndex->pData ? 1 : 0;
	    loopCount++;

       }  while ((receiveReady != 0) && (loopCount <= 30));
	   
       pDrvCtrl->rxHandling = FALSE;

		return;
    }
#endif

#define CLCHAIN_DBG 1

#if CLCHAIN_DBG
M_BLK_ID myMblk;
#endif
/******************************************************************************
* lan91c111Send - end send routine
*
* This routine will be called by the network stack whenever the upper layer want
* to send the datagram. It takes a pointer to mbuf. It extacts the data from the
* mbuf and writes in chip.
*
* RETURNS: status of the write operation
*/
STATUS lan91c111Send(END_OBJ *pEnd,M_BLK_ID pMblk)
{
    LAN91C111END_DEVICE  	*pDrvCtrl = (LAN91C111END_DEVICE *)pEnd;
    BOOLEAN status;

	M_BLK_ID curMblk;
	int currentKey;

⌨️ 快捷键说明

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