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

📄 rtl81x9.c

📁 在Tornado环境下实现的8139网卡芯片的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    )	{	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);            break;        case EIOCGFLAGS:	    *(int *)data = END_FLAGS_GET(&pDrvCtrl->end);            break;	case EIOCPOLLSTART:	    error = rtl81x9PollStart (pDrvCtrl);	    break;	case EIOCPOLLSTOP:	    error = rtl81x9PollStop (pDrvCtrl);	    break;        case EIOCGMIB2:            if (data == NULL)                return (EINVAL);            bcopy((char *)&pDrvCtrl->end.mib2Tbl, (char *)data,                  sizeof(pDrvCtrl->end.mib2Tbl));            break;        case EIOCGFBUF:            if (data == NULL)                return (EINVAL);            *(int *)data = RTL_MIN_FBUF;            break;        case EIOCGMWIDTH:            if (data == NULL)                return (EINVAL);            *(int *)data = pDrvCtrl->memWidth;            break;        case EIOCGHDRLEN:            if (data == NULL)                return (EINVAL);            *(int *)data = 14;            break;        default:            error = EINVAL;        }    return (error);    }/********************************************************************************* rtl81x9Wait - wait for the command completion** This function waits for the command completion* It is possible the chip can wedge and the 'command in progress' bit may* never clear. Hence, we wait only a finite amount of time to avoid getting* caught in an infinite loop. Normally this delay routine would be a macro,* but it isn't called during normal operation so we can afford to make it a* function.** RETURNS: N/A*/LOCAL void rtl81x9Wait    (    RTL81X9END_DEVICE * 	pDrvCtrl	/* device control structure */    )    {    register int	ix;    for (ix = 0; ix < RTL_TIMEOUT; ix++)        {        /*if ((rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_CHIP_CMD, NONE) & 0x10) == 0)*/	if ((rtl81x9CsrReadByte (pDrvCtrl, RTL_REGS_CHIP_CMD, NONE) & 0x10) == 0)	            break;					/*vicadd*/

⌨️ 快捷键说明

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