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

📄 rtl81x9.c

📁 VxWorks下8139网卡驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
		if (stat & RTL_IPT_TX_ERR)
			{
			DRV_LOG (DRV_DEBUG_INT, "RTL_IPT_TX_ERR\n", 0, 0, 0, 0, 0, 0);
        	rtl81x9HandleTxInt (pDrvCtrl);
			}

		if (stat & RTL_IPT_RX_ERR)
			{
			DRV_LOG (DRV_DEBUG_INT, "RTL_IPT_RX_ERR\n", 0, 0, 0, 0, 0, 0);

	
        	if (netJobAdd ((FUNCPTR)rtl81x9HandleRecvInt, (int) pDrvCtrl,
                       0, 0, 0, 0) != OK)
				DRV_LOG (DRV_DEBUG_INT, "xl: netJobAdd (rtl81x9HandleRecvInt) failed\n", 0, 0, 0, 0, 0, 0);
			}

    	/* Check for transmit Interrupt */
		if (stat & RTL_IPT_TX_OK)
			{
        	rtl81x9HandleTxInt (pDrvCtrl);
			}


		if (stat & RTL_IPT_RX_OK)
			{
        	if (netJobAdd ((FUNCPTR)rtl81x9HandleRecvInt, (int) pDrvCtrl,
                       0, 0, 0, 0) != OK)
				DRV_LOG (DRV_DEBUG_INT, "xl: netJobAdd (rtl81x9HandleRecvInt) failed\n", 0, 0, 0, 0, 0, 0);
			}
			
			
		}
    rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, RTL_VALID_INTERRUPTS, NONE);

	}



/*******************************************************************************
*
* rtl81x9HandleTxInt - task level interrupt service for tx packets
*
* This routine is called by the interrupt service routine to do any 
* message transmission processing.
*
* RETURNS: N/A.
*/

LOCAL void rtl81x9HandleTxInt
    (
    RTL81X9END_DEVICE *pDrvCtrl
    )

	{
	int 		   txDesc;


	for (txDesc=0; txDesc < RTL_NUM_TX_DESC; txDesc++) 
		{
		u_long txstatus;
    	
    	txstatus = rtl81x9CsrReadLong (pDrvCtrl, 
    				RTL_REGS_TX_STATUS0 + (txDesc*4), NONE);

		if (txstatus & RTL_TX_STATUS_OK)
			{
			/* Has the packet been sent previously */
			if ((txstatus & RTL_TX_HOST_OWNS) && (pDrvCtrl->pDescMem[txDesc] != NULL))
				{
				/* Clear the buffer that was registered to the Descriptor */
				/*vicadd netClFree (pDrvCtrl->end.pNetPool, pDrvCtrl->pDescMem[txDesc]);*/
				pDrvCtrl->pDescMem[txDesc] = NULL;
				pDrvCtrl->freeDesc++;
				if (pDrvCtrl->freeDesc > RTL_NUM_TX_DESC)
						pDrvCtrl->freeDesc = RTL_NUM_TX_DESC;
				}
			}
		else if (txstatus & (RTL_TX_UNDERRUN | 
							RTL_TX_OUT_OF_WINDOW | 
							RTL_TX_ABORTED ))
			{
			/* Clear the buffer that was registered to the Descriptor */

			/*vicaddnetClFree (pDrvCtrl->end.pNetPool, pDrvCtrl->pDescMem[txDesc]);*/
			pDrvCtrl->pDescMem[txDesc] = NULL;
				
    		rtl81x9CsrWriteLong (pDrvCtrl, 
					RTL_REGS_TX_STATUS0 + (txDesc*4), RTL_TX_HOST_OWNS, NONE);
			}
		}
	}

/*******************************************************************************
*
* rtl81x9HandleRecvInt - task level interrupt service for input packets
*
* This routine is called by the interrupt service routine to do any 
* message received processing.
*
* RETURNS: N/A.
*/

LOCAL void rtl81x9HandleRecvInt
    (
    RTL81X9END_DEVICE *pDrvCtrl
    )
    {
    int         len, wrapSize; 
    M_BLK_ID 	pMblk;
    char*       pNewCluster;
    CL_BLK_ID	pClBlk;
	RTL_RX_DATA *rxData;

	USHORT		cur_rx;
	/*USHORT		limit,max_bytes = 0;*/
	USHORT		 rx_bytes = 0;
        

	char 		*readPtr;
	

  
	
	/* Disable interrupts by clearing the interrupt mask. */
	
	

				
	cur_rx = ((rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_RX_BUF_PTR, NONE) 
					+ 16) % RTL_RXBUFLEN);


/*	limit  = (rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_RX_BUF_ADDR, NONE) % RTL_RXBUFLEN);

	if (limit < cur_rx)
		max_bytes = (RTL_RXBUFLEN - cur_rx) + limit;
	else

		max_bytes = limit - cur_rx;

*/
    while ((rtl81x9CsrReadByte (pDrvCtrl, RTL_REGS_CHIP_CMD, NONE) & 
    					   RTL_CMD_RX_BUF_EMPTY) == 0)
        {

		
		/*rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_INTR_STATUS, NONE) ;*//*test*/

		readPtr = (pDrvCtrl->ptrRxBufSpace + cur_rx);
     	rxData = (RTL_RX_DATA *) readPtr;



		if ((rxData->rxPktLen >> 16) == RTL_RX_UNFINISHED)
		{
		 	DRV_LOG (DRV_DEBUG_ALL, "RxHandError 0fff0: ", 1, 2, 3, 4, 5, 6);
                    break;
		}
		

		if (!(rxData->rxStatusFlags & RTL_RX_STATUS_OK)) 
			{
			if (rxData->rxStatusFlags & (RTL_RX_BAD_SYMBOL|
										 RTL_RX_RUNT|
										 RTL_RX_TOO_LONG|
										 RTL_RX_CRC_ERROR|
										 RTL_RX_BAD_ALIGN)) 
				{
				/*rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB, RTL_WIN_0);
				rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB|
							RTL_CMD_RX_ENB, RTL_WIN_0);*/
				rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB, RTL_WIN_0);
				rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB|
							RTL_CMD_RX_ENB, RTL_WIN_0);

				rtl81x9CsrWriteLong(pDrvCtrl, RTL_REGS_RX_BUF, (ULONG) pDrvCtrl->ptrRxBufSpace, RTL_WIN_0);
				/*rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_RX_BUF_PTR, cur_rx - 16, RTL_WIN_0);*/
				cur_rx = 0;
				/*DRV_LOG (DRV_DEBUG_ALL, "RxHandError:rxData->rxStatusFlags=%x ", rxData->rxStatusFlags, 2, 3, 4, 5, 6);
				i = rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_INTR_STATUS, NONE);
                           	DRV_LOG (DRV_DEBUG_INT, "ISR %x ", i,0,0,0,0,0);*/
					 
				rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_RX_CONFIG, pDrvCtrl->reg_rcr, RTL_WIN_0); 
				
				
				}
			break;
			}


		/* No errors; receive the packet. */	
    	len = rxData->rxPktLen;		/* get packet length */

	/*DRV_LOG (DRV_DEBUG_RX, "Rmask %x", rtl81x9CsrReadWord(pDrvCtrl, 		RTL_REGS_INTR_MASK, NONE), 0, 0, 0, 0, 0); *//*test*/
	

		rx_bytes += len + 4;
		
		len -= RTL_CRC_SIZE;

		/*
		 * Avoid trying to read more bytes than we know
		 * the chip has prepared for us.
		 */
		/*if (rx_bytes > max_bytes)
		{
			DRV_LOG (DRV_DEBUG_ALL, "MAX bytes error rx_bytes=%x max_bytes=%x\n", rx_bytes, max_bytes, 0, 0, 0, 0);			
			break; unknow what do
		}*/





			if(len>1518) {

				/*rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB, RTL_WIN_0);
				rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB|
							RTL_CMD_RX_ENB, RTL_WIN_0);*/
				rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB, RTL_WIN_0);
				rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_TX_ENB|
							RTL_CMD_RX_ENB, RTL_WIN_0);

				rtl81x9CsrWriteLong(pDrvCtrl, RTL_REGS_RX_BUF, (ULONG) pDrvCtrl->ptrRxBufSpace, RTL_WIN_0);
				/*rtl81x9CsrWriteWord(pDrvCtrl, RTL_REGS_RX_BUF_PTR, cur_rx - 16, RTL_WIN_0);*/
				cur_rx = 0;
				DRV_LOG (DRV_DEBUG_ALL, "RxHandError:rxData->rxStatusFlags=%x ", rxData->rxStatusFlags, 2, 3, 4, 5, 6);
				/*i = rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_INTR_STATUS, NONE);*/
               	                /*DRV_LOG (DRV_DEBUG_INT, "ISR %x ", i,0,0,0,0,0);*/
					 
				rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_RX_CONFIG, pDrvCtrl->reg_rcr, RTL_WIN_0); 
				




			       DRV_LOG (DRV_DEBUG_ALL, "MAX bytes error rx_bytes>1518=%x \n", len, 0, 0, 0, 0, 0);			
                               break;
				}	


/*	DRV_LOG (DRV_DEBUG_LOAD, "Rx_Bytes=%x len=%x max_byte=%x\n", rx_bytes, len, max_bytes, 4, 5, 6);*/

    	/* If we cannot get a buffer to loan then bail out. */
    	pNewCluster = netClusterGet(pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId);

	/*DRV_LOG (DRV_DEBUG_RX, "Cannot loan cluster!\n", 0, 0, 0, 0, 0, 0);
			END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);*/


    	if (pNewCluster == NULL)
        	{
    		DRV_LOG (DRV_DEBUG_RX, "Cannot loan cluster!\n", 0, 0, 0, 0, 0, 0);
			END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
			goto cleanRXD;
        	}

    	if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL)
      		{
        	netClFree (pDrvCtrl->end.pNetPool, pNewCluster);
    		DRV_LOG (DRV_DEBUG_RX, "Out of Cluster Blocks!\n", 0, 0, 0, 0, 0, 0);
			END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
			goto cleanRXD;
        	}
    
    	/*
     	 * OK we've got a spare, let's get an M_BLK_ID and marry it to the
     	 * one in the ring.
     	 */

    	if ((pMblk = mBlkGet(pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA))
        	== NULL)
        	{
        	netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk);
        	netClFree (pDrvCtrl->end.pNetPool, pNewCluster);
        	DRV_LOG (DRV_DEBUG_RX, "Out of M Blocks!\n", 0, 0, 0, 0, 0, 0);
        	END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
        	goto cleanRXD;
        	}

		/* Copy the data found into the new cluster, we have (+4) to get us past the */
		/* data that the rtl chip places at the start of the message and we remove   */
		/* the CRC from the end of the message	*/

		if ((readPtr + len) >= (pDrvCtrl->ptrRxBufSpace + RTL_RXBUFLEN))
			{
			wrapSize = (int) ((readPtr + len) - (pDrvCtrl->ptrRxBufSpace + RTL_RXBUFLEN));

			/* Copy in first section of message as stored */
			/* at the end of the ring buffer			  */


		  


    		memcpy (pNewCluster, readPtr + 4, len - wrapSize);

			/* Copy in end of message as stored */
			/* at the start of the ring buffer  */

		/*vicadd*/
#ifdef	CPU_PENTIUM
    		memcpy (pNewCluster +len - wrapSize -4, pDrvCtrl->ptrRxBufSpace, wrapSize+0x04);
								/* there have some error compiler's bug in this line*/
								/* If I just copy the correct bytes the last two bytes will*/
								/* have some trouble, so I copy extra bytes to fix the CPU or*/
								/* OS's bug	vic						*/						
#else
	memcpy (pNewCluster /*+len - wrapSize -4*/, pDrvCtrl->ptrRxBufSpace, wrapSize/*+0x04*/);
#endif
				
			cur_rx = (wrapSize + RTL_CRC_SIZE + 4 + 3) & ~3;


	





		/*DRV_LOG (DRV_DEBUG_ALL, "wrapsize=%x readptr=%x len=%x pNew=%x newwrapsize %x\n",wrapSize,readPtr,len,pNewCluster,pNewCluster-wrapSize ,6);		
		DRV_LOG (DRV_DEBUG_ALL, "header=%02x %02x %02x %02x %02x %02x \n",readPtr[4],readPtr[5],readPtr[6],readPtr[7],readPtr[8],readPtr[9]);		
		DRV_LOG (DRV_DEBUG_ALL, "newheader=%02x %02x %02x %02x %02x %02x \n",pNewCluster[0],pNewCluster[1],pNewCluster[2],pNewCluster[3],pNewCluster[4],pNewCluster[5]);*/
		/*DRV_LOG (DRV_DEBUG_ALL, "len=%02x \n",len,2, 3, 4, 5, 6);*/

			}
		else

			{
    		memcpy (pNewCluster, readPtr + 4, len);
			cur_rx = (cur_rx + len + RTL_CRC_SIZE + 4 + 3) & ~3;

	

		
    			}



		/* Disable interrupts by clearing the interrupt mask. */
/*vicadd    	rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, 0x00, NONE);*/

		/* We then write the CAPR as the next ptr we will read minus 0x10 which 	*/
		/* give us a little leeway to ensure that there is no overflow 				*/
		rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_RX_BUF_PTR, (cur_rx - 16), RTL_WIN_0);
    		/*DRV_LOG (DRV_DEBUG_ALL, "CAPR=%x len=%d\n",(cur_rx - 16), len, 0, 0, 0, 0);*/
			
		/* Enable interrupts by setting the interrupt mask. */
/*vicadd    	rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, RTL_VALID_INTERRUPTS, NONE);*/
    	
    	/* Join the cluster to the MBlock */

    	netClBlkJoin (pClBlk, pNewCluster, len, NULL, 0, 0, 0);
    			netMblkClJoin (pMblk, pClBlk);

    	/* make the packet data coherent */

    	RTL_CACHE_INVALIDATE (pMblk->mBlkHdr.mData, len);

    	pMblk->mBlkHdr.mLen   = len;
    	pMblk->mBlkHdr.mFlags |= M_PKTHDR;
    	pMblk->mBlkPktHdr.len = len;

    	/* Call the upper layer's receive routine. */

    	END_RCV_RTN_CALL (&pDrvCtrl->end, pMblk);

		}

cleanRXD:
	

    }

	  
/*******************************************************************************
*
* rtl81x9Ioctl - interface ioctl procedure
*
* Process an interface ioctl request.
*
* This routine implements the network interface control functions.
* It handles EIOCSADDR, EIOCGADDR, EIOCSFLAGS, EIOCGFLAGS, EIOCMULTIADD,
* EIOCMULTIDRTL, EIOCMULTIGET, EIOCPOLLSTART, EIOCPOLLSTOP, EIOCGMIB2 commands.
*
* RETURNS: OK if successful, otherwise EINVAL.
*/

LOCAL int rtl81x9Ioctl
    (
    RTL81X9END_DEVICE *	pDrvCtrl,
    int		cmd,
    caddr_t	data
    )
    {
    int error = 0;
    long value;

    switch (cmd)
        {
        case EIOCSADDR:
	    if (data == NULL)
		return (EINVAL);
            bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->end),
		   END_HADDR_LEN(&pDrvCtrl->end));
            break;

        case EIOCGADDR:
	    if (data == NULL)
		return (EINVAL);
            bcopy ((char *)END_HADDR(&pDrvCtrl->end), (char *)data,
		    END_HADDR_LEN(&pDrvCtrl->end));
            break;

        case EIOCSFLAGS:
	    value = (long)data;
	    if (value < 0)
		{
		value = -value;
		value--;		/* HRTLP: WHY ??? */
		END_FLAGS_CLR (&pDrvCtrl->end, value);
		}
	    else
		{
		END_FLAGS_SET (&pDrvCtrl->end, value);
		}
	    rtl81x9Config (pDrvCtrl);

⌨️ 快捷键说明

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