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

📄 rtl81x9.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
    pDrvCtrl->txBlocked = FALSE;
		
	if(pDrvCtrl->unit == 0)
	{
		rtlNetTaskSemId0 = semBCreate(SEM_Q_FIFO,SEM_EMPTY);

		/*启动数据接收任务*/
		(void)taskSpawn("tRtlRxTask0",45,0,4000,(FUNCPTR)rtlRecvTask0,pDrvCtrl,0,0,0,0,0,0,0,0,0);
	}
	else if(pDrvCtrl->unit == 1)
	{
		rtlNetTaskSemId1 = semBCreate(SEM_Q_FIFO,SEM_EMPTY);

		/*启动数据接收任务*/
		(void)taskSpawn("tRtlRxTask1",45,0,4000,(FUNCPTR)rtlRecvTask1,pDrvCtrl,0,0,0,0,0,0,0,0,0);

	}

    SYS_INT_CONNECT (pDrvCtrl, rtl81x9Int, (int)pDrvCtrl, &result);

	if (result == ERROR)
	{
		return ERROR;
	}

    SYS_INT_ENABLE (pDrvCtrl);

	/* Init the RX buffer pointer register. */

    rtl81x9CsrWriteLong(pDrvCtrl, RTL_REGS_RX_BUF, (ULONG) pDrvCtrl->ptrRxBufSpace, RTL_WIN_0);
     /*DRV_LOG (DRV_DEBUG_ALL, "rxbuffer start- %x: \n",(ULONG) pDrvCtrl->ptrRxBufSpace , 2, 3, 4, 5, 6);*/		
	
	/* Enable Tx and RX */
    rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_RX_ENB + RTL_CMD_TX_ENB, RTL_WIN_0);

	/*
	 * Set the initial TX and RX configuration.
	 * Set the buffer size and set the wrap register
	 */

    rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_TX_CONFIG, RTL_TXCFG_CONFIG, RTL_WIN_0); 

    /* DRV_LOG (DRV_DEBUG_ALL, "rtl81x9-TXCFG - %x: \n",RTL_TXCFG_CONFIG , 2, 3, 4, 5, 6);*/

    rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_RX_CONFIG, RTL_RXCFG_CONFIG, RTL_WIN_0); 

	rxcfg = rtl81x9CsrReadLong(pDrvCtrl, RTL_REGS_RX_CONFIG, RTL_WIN_0);

	/* Set the Early Threshold bits depending on flags read */  /*vicadd*/
	/* from initialisation string							*/
	rxcfg |= ((pDrvCtrl->flags >> 16) << 24);

	/* Set the individual bit to receive frames for this host only. */
	rxcfg |= RTL_RXCG_APM;

	/* If we want promiscuous mode, set the allframes bit. */
	if (pDrvCtrl->ib->rtlIBMode == 0x8000)
		{ 
		rxcfg |= RTL_RXCG_AAP;
    	rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_RX_CONFIG, rxcfg, RTL_WIN_0); 
		} 
	else
		{ 
		rxcfg &= ~RTL_RXCG_AAP;
    	rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_RX_CONFIG, rxcfg, RTL_WIN_0); 
		}
	/*
	 * Set capture broadcast bit to capture broadcast frames.
	 */
	rxcfg |= RTL_RXCG_AB;


   /*  DRV_LOG (DRV_DEBUG_ALL, "rtl81x9-RCR - %x: \n", rxcfg, 2, 3, 4, 5, 6);*/
 			
	 pDrvCtrl-> reg_rcr =rxcfg;/* save it */
    rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_RX_CONFIG, rxcfg, RTL_WIN_0); 

	/* We now need to update the Multicast Registers */
	/* These values need to be finalised and written */

    rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_MAR0, 0xffff, RTL_WIN_0); 
    rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_MAR0 + 4, 0xffff, RTL_WIN_0); 

	/* Enable Controller Interrupts */
	

/*vicadd*/
	if(pDrvCtrl->flags & RTL_FLG_POLLING) 
	{
		rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, 0, NONE);
	}
    else
    	{
		rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, RTL_VALID_INTERRUPTS, NONE);
    	}
	
   /* DRV_LOG (DRV_DEBUG_ALL, "rtl81x9-IMR - %x: \n",RTL_VALID_INTERRUPTS , 2, 3, 4, 5, 6);*/
	
		
	/* Start RX/TX process. */
    rtl81x9CsrWriteLong (pDrvCtrl, RTL_REGS_RX_MISSED, 0, RTL_WIN_0); 

	/* Enable Tx and RX */
    rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CHIP_CMD, RTL_CMD_RX_ENB + RTL_CMD_TX_ENB, RTL_WIN_0);
/*
	if(pDrvCtrl->unit == 0)
	{
	(void)taskSpawn("tRtlTxClearTask0",40,0,4000,(FUNCPTR)rtl8139IntTimer,pDrvCtrl,0,0,0,0,0,0,0,0,0);
	}
	else
	{
	(void)taskSpawn("tRtlTxClearTask1",40,0,4000,(FUNCPTR)rtl8139IntTimer,pDrvCtrl,0,0,0,0,0,0,0,0,0);
	}*/
    return (OK);
    }


/*******************************************************************************
*
* rtl81x9Int - handle controller interrupt
*
* This routine is called at interrupt level in response to an interrupt from
* the controller.
*
* RETURNS: N/A.
*/

LOCAL void rtl81x9Int
    (
    RTL81X9END_DEVICE  *pDrvCtrl
    )
    {
    u_short        stat;
	int rxcfg;

	/* Disable controller interrupts. */
    rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_MASK, 0x00, NONE);

	for (;;)
		{
   		/* Read the interrupt status register */
    	stat = rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_INTR_STATUS, NONE);
	DRV_LOG (DRV_DEBUG_INT, "ISR %x ", stat,0,0,0,0,0);
    	/* clear interrupts, */
		if (stat)
    		rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_STATUS, stat, NONE);

    	/* Check if a valid Interrupt has been set */
		if ((stat & RTL_VALID_INTERRUPTS) == 0)
			break;

		if (stat & RTL_IPT_PCI_ERR)
			{
			DRV_LOG (DRV_DEBUG_INT, "RTL_IPT_PCI_ERR - Reset and Re initialise\n", 0,0,0,0,0,0);
			rtl81x9Reset (pDrvCtrl);
			rtl81x9Restart (pDrvCtrl);
			}

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

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

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

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

/*vicadd*/   		rtl81x9CsrWriteWord (pDrvCtrl, RTL_REGS_INTR_STATUS,  RTL_IPT_RX_OK|RTL_IPT_RX_OVERFLOW|RTL_IPT_RX_FIFO_OVER, NONE);

		    rxcfg=rtl81x9CsrReadLong (pDrvCtrl, RTL_REGS_RX_CONFIG,  RTL_WIN_0); 				
		     DRV_LOG (DRV_DEBUG_ALL, "rtl81x9-RCR - %x: \n", rxcfg, 2, 3, 4, 5, 6);
				

			}

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

		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_RX, "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);
				
			/*释放信号量,开始接收数据*/
			/*semGive(rtlNetTaskSemId);*/
			}

    	/* Check for transmit Interrupt */
		if (stat & RTL_IPT_TX_OK)
			{
				DRV_LOG (DRV_DEBUG_TX, "RTL_IPT_TX_OK\n", 0, 0, 0, 0, 0, 0);

        	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);
			DRV_LOG (DRV_DEBUG_RX, "RTL_IPT_RX_OK\n", 0, 0, 0, 0, 0, 0);*/

			if(pDrvCtrl->unit == 0)
			{
				/*释放信号量,开始接收数据*/
				semGive(rtlNetTaskSemId0);
			}
			else if(pDrvCtrl->unit == 1)
			{
				/*释放信号量,开始接收数据*/
				semGive(rtlNetTaskSemId1);
			}

			}
			
			
		}
    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;
        int n=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;
			
		DRV_LOG (DRV_DEBUG_RX, "rxData->ptrRxBufSpace=%x, cur_rx = %x\n", pDrvCtrl->ptrRxBufSpace, cur_rx, 3, 4, 5, 6);

		DRV_LOG (DRV_DEBUG_RX, "rxData->rxStatusFlags=%x \n", PCI_WORD_SWAP(rxData->rxStatusFlags), 2, 3, 4, 5, 6);
		DRV_LOG (DRV_DEBUG_RX, "rxData->rxPktLen=%x \n", PCI_WORD_SWAP(rxData->rxPktLen), 2, 3, 4, 5, 6);
		DRV_LOG (DRV_DEBUG_RX, "rxData->pktData 0=%d, 1 =%d\n", rxData->pktData[0], rxData->pktData[1], 3, 4, 5, 6);


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

		if (!(PCI_WORD_SWAP(rxData->rxStatusFlags) & RTL_RX_STATUS_OK)) 
			{
			if (PCI_WORD_SWAP(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 = PCI_WORD_SWAP(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);

⌨️ 快捷键说明

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