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

📄 lan91c111end.c

📁 atmel9200 vxworks bsp
💻 C
📖 第 1 页 / 共 5 页
字号:
				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.*/
            /*sysOutByte(Adapter->IOBase + BANK2_INT_STS, INT_RX_OVRN);*/
                SYS_IN_SHORT(Adapter->IOBase + BANK2_INT_STS,&tempb);
                tempb &= 0xff00;
                tempb |= INT_RX_OVRN;
                SYS_OUT_SHORT(Adapter->IOBase + BANK2_INT_STS,tempb);           
           
               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);

    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);
    }


/*******************************************************************************
* 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;
    }


#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;
	DRV_LOG (DRV_DEBUG_TX, "lan91c111Send: called \n",1, 2, 3, 4, 5, 6);

/* This Block is to put the packet sent by the upper layers in a ring Buffer.Here
 we are using ReadIndex and WriteIndex instead of allocpending and writepending Queues*/

/* He is not checking for null since he is sending null  in the TX Int case...
    I think we have to check for null ..ask kumar about this.. */

	if(pMblk ==(M_BLK_ID) 1)
	{

			currentKey = intLock();
			pDrvCtrl->AllocPending =FALSE;
			curMblk = pDrvCtrl->pTxReadIndex->pMblk;

            END_TX_SEM_TAKE (&pDrvCtrl->endObj,WAIT_FOREVER);
	        pDrvCtrl->sendDatalen = netMblkToBufCopy(curMblk,pDrvCtrl->sendBuf,NULL);
			pDrvCtrl->sendDatalen = (ETHER_ZLEN < pDrvCtrl->sendDatalen) ? pDrvCtrl->sendDatalen : ETHER_ZLEN;
			pDrvCtrl->pTxReadIndex->pMblk = NULL;
			netMblkClChainFree(curMblk);
	        if ( pDrvCtrl->pTxReadIndex < pDrvCtrl->pTxBase + TX_PACKETS - 2)
				pDrvCtrl->pTxReadIndex++;
   			else
     			pDrvCtrl->pTxReadIndex = pDrvCtrl->pTxBase;
		    lan91c111WriteToChip(pDrvCtrl);
			intUnlock(currentKey);
            END_TX_SEM_GIVE (&pDrvCtrl->endObj);
		    return OK;
	}
    else if(pMblk)   /* put in ring buffer */
    {
		if(pDrvCtrl->pTxWriteIndex->pMblk)
		{
			/* TX fifo full, drop packet */
			netMblkClChainFree(pMblk);
		}
		else
		{
			/* TX fifo not full, queue packet */
	 	   	pDrvCtrl->pTxWriteIndex->pMblk = pMblk;
/*
			DRV_LOG(DRV_DEBUG_TX,"TxWriteIndex : %d\n",pDrvCtrl->pTxWriteIndex,2,3,4,5,6);
*/
	 	   	if(pDrvCtrl->pTxWriteIndex < (pDrvCtrl->pTxBase + TX_PACKETS - 2))
		        pDrvCtrl->pTxWriteIndex++;
	  	  	else
	      		pDrvCtrl->pTxWriteIndex = pDrvCtrl->pTxBase;
        }
    }

/* This Block calls two Functions one allocates the memory
 from the MMU and other copies the stuff from clusters to the chip*/
			curMblk = pDrvCtrl->pTxReadIndex->pMblk;
	 	  	if(!curMblk)
			{
            DRV_LOG (DRV_DEBUG_ERR, "lan91c111Send: Current MBlk is NULL \n",1, 2, 3, 4, 5, 6);
			return OK;
			}
	        status = DoAllocate(pDrvCtrl);
            if(status)
            {
					DRV_LOG(DRV_DEBUG_TX, "lan91c111Send : Got Access to MMU\n",1,2,3,4,5,6);
  			        END_TX_SEM_TAKE (&pDrvCtrl->endObj,WAIT_FOREVER);
					currentKey = intLock();
	    		    pDrvCtrl->sendDatalen = netMblkToBufCopy(curMblk,pDrvCtrl->sendBuf,NULL);
					pDrvCtrl->sendDatalen = (ETHER_ZLEN < pDrvCtrl->sendDatalen) ? pDrvCtrl->sendDatalen : ETHER_ZLEN;
					pDrvCtrl->pTxReadIndex->pMblk = NULL;
	 				netMblkClChainFree(curMblk);
   			        if ( pDrvCtrl->pTxReadIndex < pDrvCtrl->pTxBase + TX_PACKETS - 2)
   						pDrvCtrl->pTxReadIndex++;
		   			else
  		     			pDrvCtrl->pTxReadIndex = pDrvCtrl->pTxBase;
					lan91c111WriteToChip(pDrvCtrl);
					intUnlock(currentKey);
            }
            else
            {
                    USHORT OldMask;
					int key;
					key = intLock();
                    pDrvCtrl->AllocPending = TRUE;
                    SYS_IN_SHORT(pDrvCtrl->IOBase + BANK2_INT_STS, (PUSHORT)&OldMask);
                    SYS_OUT_SHORT(pDrvCtrl->IOBase + BANK2_INT_STS, 0);
                    OldMask |= ( INT_ALLOC << 8 );
                    OldMask &= 0xFF00;  /* Do not ACK interrupts */
                    SYS_OUT_SHORT(pDrvCtrl->IOBase + BANK2_INT_STS, OldMask);
					intUnlock(key);
					DRV_LOG(DRV_DEBUG_TX, "lan91c111Send : Set Alloc Int bit\n",1,2,3,4,5,6);
            }
			END_TX_SEM_GIVE (&pDrvCtrl->endObj);

            return OK;
}

/*****************************************************************************
* DoAllocate - allocates the memory for write operation
*
* This routine makes a request MMU for 2k bytes of memory for packet
* transmition.
*
* RETIRNS: status of the request
*/

BOOLEAN DoAllocate(LAN91C111END_DEVICE  *pDrvCtrl)
 {

	UINT            AllocateOk;         /*  Delay loop control */
 	UINT            IOBase;

	USHORT		AllocSts;

        IOBase = pDrvCtrl->IOBase;

		SYS_OUT_SHORT(IOBase + BANK_SELECT, 2);

        SYS_OUT_SHORT(IOBase + BANK2_MMU_CMD,(USHORT)((((pDrvCtrl->sendDatalen + FRAME_OVERHEAD) & 0xfffe) >> 8)|CMD_ALLOC));

		AllocateOk = MMU_WAIT;

        while(AllocateOk)
        {
               SYS_IN_SHORT(IOBase + BANK2_INT_STS,(PUSHORT) &AllocSts);
     		   if(AllocSts & INT_ALLOC)
     		       break;
     		   AllocateOk--;
   		}

		/* Check whether the allocation result is a pass or fail */
        return((BOOLEAN) (AllocSts & INT_ALLOC));

}

/***********************************************************************
* writeToChip - write data to the chip
*
* This routine will writes the data to the chip and the transmission for
* transmition.
*
* RETURNS: N/A
*/
void lan91c111WriteToChip(LAN91C111END_DEVICE  *pDrvCtrl)
{
        UINT        IOBase;
        UINT        DataPort;
        USHORT TempWord;
        BYTE TempByte;

        USHORT length = pDrvCtrl->sendDatalen ;
        char *p = pDrvCtrl->sendBuf ;
		int key;
        short tempb;

#if PING_DEBUG
	if(length <= 100)
		memcpy((void *)TxBuff, (void *)p, length);
#endif
        /*-----------------3/13/01 2:38PM-------------------
         * For faster data access
         * --------------------------------------------------*/

		if(pDrvCtrl->EarlyTransmit == TRUE) 
		{
				EarlyTransmit(pDrvCtrl);
		}
		else
		{
        IOBase   = pDrvCtrl->IOBase;
        DataPort = IOBase + BANK2_DATA1;

		key = intLock();
		SYS_OUT_SHORT(IOBase + BANK_SELECT, 2);
        /*-----------------3/13/01 2:35PM-------------------
         * The next 3 lines of code reads the Alloc Result register
         * and writes into the packet Number Register
         * --------------------------------------------------*/

        SYS_IN_SHORT( IOBase + BANK2_PNR,(PUSHORT) &TempWord );

        TempByte = HIBYTE(TempWord);

        SYS_OUT_SHORT(IOBase + BANK2_PNR,TempByte);
        /*-----------------3/13/01 2:38PM-------------------
         * From here we are writing the packet into the Chip
         * --------------------------------------------------*/
        SYS_OUT_SHORT(IOBase + BANK2_PTR,(USHORT) PTR_AUTO);

        SYS_OUT_SHORT(DataPort,(USHORT) 0);

                       /* force byte count even 3/25/96 NW */
        SYS_OUT_SHORT((DataPort), (USHORT) (0xfffe & (length + FRAME_OVERHEAD )) );


		while(length > 3)
		{
			SYS_OUT_LONG((DataPort),(*((PULONG) p)));
			length -= sizeof(ULONG);
			p += sizeof(ULONG);
		}
		if(length > 1)
		{
			SYS_OUT_SHORT((DataPort),(*((PUSHORT) p)));
			length -= sizeof(USHORT);
			p += sizeof(USHORT);
		}


        if(length)
        {
		    /*sysOutByte((DataPort),(*p));*/
                SYS_IN_SHORT(DataPort,&tempb);

⌨️ 快捷键说明

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