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

📄 rtl81x9.c

📁 在Tornado环境下实现的8139网卡芯片的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	}    if (ix == RTL_TIMEOUT)        DRV_LOG (DRV_DEBUG_ALL, "rtl81x9Wait - rtlPci%d: command never completed!\n",                 pDrvCtrl->unit, 2, 3, 4, 5, 6);    return;    }/********************************************************************************* rtl81x9Reset - Reset the chip** This routine does a soft reset on the chip.** RETURNS: OK, Always. */LOCAL STATUS rtl81x9Reset    (    RTL81X9END_DEVICE *	pDrvCtrl	/* pointer to device control structure */    )    {    /* issue the reset command */	/*DRV_LOG (DRV_DEBUG_LOAD, " rtl81x9Reset\n",0,0,0,0,0,0);*/        /*rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_RESET, RTL_WIN_0);*/    rtl81x9CsrWriteByte (pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_RESET, RTL_WIN_0);	    rtl81x9Wait(pDrvCtrl);	/* wait for the command to complete */    /* wait for a while */    SYS_DELAY(10);/*vicadd*/    return OK;    }   /********************************************************************************* rtl81x9LowPowerMode - Enter low power mode*** RETURNS: N/A** NOMANUAL*/void rtl81x9LowPowerMode (RTL81X9END_DEVICE* pDrvCtrl)    {/*    rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CFG_9346, 0xC0, RTL_WIN_0);    rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CONFIG_1, 0x03, RTL_WIN_0);*/    }/********************************************************************************* rtl81x9NormalPowerMode - Come out of Low power mode*** RETURNS: N/A** NOMANUAL*//*void rtl81x9NormalPowerMode (RTL81X9END_DEVICE* pDrvCtrl)    {    rtl81x9CsrWrite(pDrvCtrl, RTL_REGS_CONFIG_1,  0x00,  RTL_WIN_0);    }*//********************************************************************************* rtl81x9Stop - stop the device** This routine marks the interface as down and resets the device.  This* includes disabling interrupts, stopping the transmitter and receiver.** The complement of this routine is rtl81x9Start.  Once a unit is* stop in this routine, it may be re-initialized to a running state by* rtl81x9Start.** RETURNS: OK or ERROR*/LOCAL STATUS rtl81x9Stop    (    RTL81X9END_DEVICE *	pDrvCtrl    )    {    STATUS result = OK;    DRV_LOG (DRV_DEBUG_LOAD, "rtl81x9Stop\n",0,0,0,0,0,0);	/* Disable interrupts by clearing the interrupt mask. */    rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, 0x00, NONE);	/* Stop the chip's Tx and Rx DMA processes. */    rtl81x9CsrWriteByte (pDrvCtrl, RTL_REGS_CHIP_CMD, 0x00, NONE);	/* Green! Put the chip in low-power mode. */	rtl81x9LowPowerMode (pDrvCtrl);    SYS_INT_DISCONNECT (pDrvCtrl, rtl81x9Int, (int)pDrvCtrl, &result);    if (result == ERROR)    	DRV_LOG (DRV_DEBUG_LOAD, "rtl81x9Stop - Could not disconnect interrupt!\n"    							,0,0,0,0,0,0);	return result;    }/******************************************************************************** rtl81x9AddrFilterSet - set the address filter for multicast addresses** This routine goes through all of the multicast addresses on the list* of addresses (added with the rtl81x9AddrAdd() routine) and sets the* device's filter correctly.** NOMANUAL*/LOCAL void rtl81x9AddrFilterSet    (    RTL81X9END_DEVICE *pDrvCtrl    )    {    ETHER_MULTI* 	pCurr;    rtl_ib*			pIb;    u_char*			pCp;    u_char 			c;    u_long 			crc;    u_long 			carry;	int				i, j;    pIb = pDrvCtrl->ib;    RTL_ADDRF_CLEAR (pIb);    pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->end);    while (pCurr != NULL)		{		pCp = (unsigned char *)&pCurr->addr;		crc = 0xFFFFFFFF; /* initial value */		for (i = 0; i < 6; i++) 			{			c = *(pCp + i);			for (j = 0; j < 8; j++) 				{				carry = ((crc & 0x80000000) ? 1 : 0) ^ (c & 0x01);				crc <<= 1;				c >>= 1;				if (carry)					crc = (crc ^ 0x04c11db6) | carry;				}			}		/* Just want the 6 most significant bits. */		crc = crc >> 26;		/* Turn on the corresponding bit in the filter. */		RTL_ADDRF_SET (pIb, crc);		pCurr = END_MULTI_LST_NEXT(pCurr);		}    }/********************************************************************************* rtl81x9PollReceive - routine to receive a packet in polled mode.** This routine is called by a user to try and get a packet from the* device.*/LOCAL STATUS rtl81x9PollReceive    (    RTL81X9END_DEVICE *pDrvCtrl,    M_BLK_ID pMblk    )    {    int         len, wrapSize;    char*       pNewCluster;    CL_BLK_ID	pClBlk;	RTL_RX_DATA *rxData;	USHORT		cur_rx;	USHORT		limit;	USHORT		max_bytes = 0, rx_bytes = 0;	char 		*readPtr;			/*return OK; */ /* test only */   /* DRV_LOG (DRV_DEBUG_ALL, "rtl81x9PollReceive\n",0,0,0,0,0,0);*/	/* Disable interrupts by clearing the interrupt mask. *//*     rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, 0x00, NONE);vicadd*/	cur_rx = ((rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_RX_BUF_PTR, NONE) 					+ 16) % RTL_RXBUFLEN);	/* Enable interrupts by setting the interrupt mask. *//*    rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, RTL_VALID_INTERRUPTS, NONE);vicadd*/	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)        {						readPtr = (pDrvCtrl->ptrRxBufSpace + cur_rx);     	rxData = (RTL_RX_DATA *) readPtr;		if ((rxData->rxPktLen >> 16) == RTL_RX_UNFINISHED)			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;				}			break;			}		/* No errors; receive the packet. */	    	len = rxData->rxPktLen;		/* get packet length */		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)			break;    	/* If we cannot get a buffer to loan then bail out. */    	pNewCluster = netClusterGet(pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId);    	if (pNewCluster == NULL)        	{        	DRV_LOG (DRV_DEBUG_POLL_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_POLL_RX, "Out of Cluster 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  */    		memcpy (pNewCluster, pDrvCtrl->ptrRxBufSpace, wrapSize);			cur_rx = (wrapSize + RTL_CRC_SIZE + 4 + 3) & ~3;			}		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);		      	/*RV_LOG (DRV_DEBUG_ALL,"Capr=%X\n",(cur_rx - 16) , 0, 0, 0, 0, 0);*/				/* Enable interrupts by setting the interrupt mask. *//*    	rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, RTL_VALID_INTERRUPTS, NONE);vicadd*/    	    	/* 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);		return OK;		}cleanRXD:	return ERROR;    }/********************************************************************************* rtl81x9PollSend - routine to send a packet in polled mode.** This routine is called by a user to try and send a packet on the* device.*/LOCAL STATUS rtl81x9PollSend    (    RTL81X9END_DEVICE* pDrvCtrl,    M_BLK_ID pMblk    )    {	/*int 		   txDesc;*/	int level;	    int         len = 0;        char*       pBuf;	ULONG		tx_val;	u_short        stat;/*    DRV_LOG (DRV_DEBUG_ALL, "rtl81x9PollSend\n",0,0,0,0,0,0);*/	 if (!(pDrvCtrl->flags & RTL_FLG_POLLING))        level = intLock ();   /* now templateInt won't get confused   vic test */	rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_STATUS, 0xffff, NONE);    /* find Tx Descriptor */	if (pDrvCtrl->freeDesc != 0)		{		if (pDrvCtrl->pDescMem[pDrvCtrl->nextDesc] == NULL) 			{    		pBuf = (pDrvCtrl->txmemspace + (pDrvCtrl->nextDesc * RTL81x9_BUFSIZE));    		pBuf += pDrvCtrl->offset;	/* take care of the alignment */    		len = netMblkToBufCopy (pMblk, pBuf, NULL);   			netMblkClChainFree(pMblk);    		len = max (len, ETHERSMALL);				tx_val = len + (3 << 16);    		rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_TX_ADDR0 + (pDrvCtrl->nextDesc * 4), (int) pBuf, RTL_WIN_0);     		rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_TX_STATUS0 + (pDrvCtrl->nextDesc * 4), tx_val, RTL_WIN_0);		/*DRV_LOG (DRV_DEBUG_ALL, "No=%x txstatus=%x\n", pDrvCtrl->nextDesc, tx_val, 0, 0, 0, 0);	*/		stat = rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_INTR_STATUS, NONE);		while(!(stat & 0x04))		{		 stat = rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_INTR_STATUS, NONE);		}				/*pDrvCtrl->pDescMem[pDrvCtrl->nextDesc] = pBuf;*/						/*netClFree (pDrvCtrl->end.pNetPool, pDrvCtrl->pDescMem[pDrvCtrl->nextDesc]);*/			pDrvCtrl->nextDesc++;			if (pDrvCtrl->nextDesc == 4)				pDrvCtrl->nextDesc = 0;			/*if (pDrvCtrl->freeDesc != 0)				pDrvCtrl->freeDesc--;*/			}		else			{    		DRV_LOG (DRV_DEBUG_TX, "Next Desc %d is not free yet\n", pDrvCtrl->nextDesc, 0, 0, 0, 0, 0);        	netMblkClChainFre

⌨️ 快捷键说明

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