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

📄 rtl81x9.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
    }      
#endif /* SYS_IN_SHORT*/

#ifndef SYS_OUT_BYTE
#define SYS_OUT_BYTE(pDrvCtrl,addr,value) \
    { \
    *((UCHAR *)(addr)) = (value); \
    }
#endif /* SYS_OUT_BYTE */

#ifndef SYS_IN_BYTE
#define SYS_IN_BYTE(pDrvCtrl,addr,data) \
    { \
    ((data) = *((UCHAR *)(addr))); \
    }
#endif /* SYS_IN_BYTE */

#ifndef SYS_OUT_SHORT_CSR
#define SYS_OUT_SHORT_CSR(pDrvCtrl,addr,value) \
    { \
    *(USHORT *)addr = value; \
    }
#endif /*SYS_OUT_SHORT_CSR*/

#ifndef SYS_IN_SHORT_CSR
#define SYS_IN_SHORT_CSR(pDrvCtrl,addr,pData) \
    (*(USHORT *)pData = *(USHORT *)addr)
#endif /*SYS_IN_SHORT_CSR*/


#define SYS_DELAY(count)	{                                               \
			volatile int cx = 0;                            \
			for (cx = 0; cx < (count); cx++);               \
			}

#ifndef SYS_ENET_ADDR_GET
#define SYS_ENET_ADDR_GET(pDrvCtrl, pAddress) \
    { \
    IMPORT STATUS sysRtl81x9EnetAddrGet (RTL81X9END_DEVICE *pDrvCtrl, \
                                     char * enetAdrs); \
    sysRtl81x9EnetAddrGet (pDrvCtrl, pAddress); \
    }
#endif /* SYS_ENET_ADDR_GET */


/* Cache macros */

#define RTL_CACHE_INVALIDATE(address, len) \
        CACHE_DRV_INVALIDATE (&pDrvCtrl->cacheFuncs, (address), (len))

#define RTL_CACHE_VIRT_TO_PHYS(address) \
        CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheFuncs, (address))


/*
 * MII access routines are provided for the 8129, which
 * doesn't have a built-in PHY. For the 8139, we fake things
 * up by diverting rl_phy_readreg()/rl_phy_writereg() to the
 * direct access PHY registers.
 */

#define MII_SET(x)					\
	rtl81x9CsrWriteByte (pDrvCtrl, RTL_REGS_MII,				\
		rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_MII, RTL_WIN_0) | x, RTL_WIN_0 )

#define MII_CLR(x)					\
	rtl81x9CsrWriteByte (pDrvCtrl, RTL_REGS_MII,				\
		rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_MII, RTL_WIN_0) & ~x, RTL_WIN_0 )

/* EEPROM Macros */

#define EE_SET(x)					\
	rtl81x9CsrWriteByte (pDrvCtrl, RTL_REGS_CFG_9346,			\
		rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_CFG_9346, RTL_WIN_0) | x, RTL_WIN_0)

#define EE_CLR(x)					\
	rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CFG_9346,			\
		rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_CFG_9346, RTL_WIN_0) & ~x, RTL_WIN_0)



/***** LOCALS *****/

LOCAL int rtlRsize = RTL_RMD_RLEN;    /* recv ring size */

/* forward static functions */

LOCAL STATUS	rtl81x9Reset ();
LOCAL void	    rtl81x9Int 			(RTL81X9END_DEVICE *);
LOCAL void		rtl81x9HandleRecvInt(RTL81X9END_DEVICE *);
LOCAL void		rtl81x9HandleTxInt	(RTL81X9END_DEVICE *);
LOCAL void		rtl81x9Restart 		(RTL81X9END_DEVICE *);
LOCAL STATUS 	rtl81x9RestartSetup (RTL81X9END_DEVICE *);
LOCAL void		rtl81x9Config 		(RTL81X9END_DEVICE *);
LOCAL void		rtl81x9AddrFilterSet(RTL81X9END_DEVICE *);
				
/* END Specific interfaces. */


/* This is the only externally visible interface. */

END_OBJ *		rtl81x9EndLoad (char *initString);

LOCAL STATUS	rtl81x9Start 		(RTL81X9END_DEVICE *);
LOCAL STATUS	rtl81x9Stop 		(RTL81X9END_DEVICE *);
LOCAL STATUS	rtl81x9Unload 		(RTL81X9END_DEVICE *);
LOCAL int		rtl81x9Ioctl 		(RTL81X9END_DEVICE *, int, caddr_t);
LOCAL STATUS	rtl81x9Send 		(RTL81X9END_DEVICE *, M_BLK *);
LOCAL STATUS	rtl81x9MCastAddrAdd (RTL81X9END_DEVICE *, char *);
LOCAL STATUS	rtl81x9MCastAddrDel (RTL81X9END_DEVICE *, char *);
LOCAL STATUS	rtl81x9MCastAddrGet (RTL81X9END_DEVICE *, MULTI_TABLE *);
LOCAL STATUS	rtl81x9PollSend 	(RTL81X9END_DEVICE *, M_BLK *);
LOCAL STATUS	rtl81x9PollReceive 	(RTL81X9END_DEVICE *, M_BLK *);
LOCAL STATUS	rtl81x9PollStart 	(RTL81X9END_DEVICE *);
LOCAL STATUS	rtl81x9PollStop 	(RTL81X9END_DEVICE *);
LOCAL STATUS	rtl81x9InitParse	(RTL81X9END_DEVICE *, char *);
LOCAL STATUS	rtl81x9InitMem 		(RTL81X9END_DEVICE *);


LOCAL void		rtl81x9LowPowerMode (RTL81X9END_DEVICE *);
LOCAL UCHAR 	rtl81x9CsrReadByte  (RTL81X9END_DEVICE *, USHORT, int);
LOCAL USHORT	rtl81x9CsrReadWord  (RTL81X9END_DEVICE *, USHORT, int);
LOCAL ULONG		rtl81x9CsrReadLong  (RTL81X9END_DEVICE *, USHORT, int);
LOCAL void   	rtl81x9CsrWriteByte (RTL81X9END_DEVICE *, USHORT, UCHAR, int);
LOCAL void   	rtl81x9CsrWriteWord (RTL81X9END_DEVICE *, USHORT, USHORT, int);
LOCAL void   	rtl81x9CsrWriteLong (RTL81X9END_DEVICE *, USHORT, ULONG, int);
LOCAL void	 	rtl81x9ReadEEPROM 	(RTL81X9END_DEVICE *, UCHAR *, ULONG, ULONG, ULONG);
LOCAL void	 	rtl81x9EEPROMPutByte(RTL81X9END_DEVICE *, ULONG);
LOCAL void	 	rtl81x9EEPROMGetWord(RTL81X9END_DEVICE *, ULONG, USHORT*);

LOCAL void 		rtl81x9Phy_writereg (RTL81X9END_DEVICE *, int, int);
LOCAL USHORT 	rtl81x9Phy_readreg 	(RTL81X9END_DEVICE *, int);
LOCAL int 		rtl81x9MII_writereg (RTL81X9END_DEVICE *, RTL_MII_FRAME *);
LOCAL void 		rtl81x9MII_sync		(RTL81X9END_DEVICE *);
LOCAL void 		rtl81x9MII_send		(RTL81X9END_DEVICE *, ULONG, int);
LOCAL int 		rtl81x9MII_readreg  (RTL81X9END_DEVICE *, RTL_MII_FRAME *);
LOCAL void 		rtl81x9AutoNegTx 	(RTL81X9END_DEVICE *);
LOCAL int 		rtl81x9MII_autoneg	(RTL81X9END_DEVICE *);
LOCAL int 		rtl81x9MediaSet 	(RTL81X9END_DEVICE *, int);
LOCAL int 		rtl81x9MediaConfig	(RTL81X9END_DEVICE *);

void eepromInit(RTL81X9END_DEVICE  *pDrvCtrl);
/* 
 * Define the device function table.  This is static across all driver
 * instances.
 */

LOCAL NET_FUNCS rtlFuncTable = 
  {
  (FUNCPTR)rtl81x9Start,		/* start func. */                 
  (FUNCPTR)rtl81x9Stop,			/* stop func. */
  (FUNCPTR)rtl81x9Unload,		/* unload func. */                
  (FUNCPTR)rtl81x9Ioctl,		/* ioctl func. */                 
  (FUNCPTR)rtl81x9Send,			/* send func. */                  
  (FUNCPTR)rtl81x9MCastAddrAdd,	/* multicast add func. */         
  (FUNCPTR)rtl81x9MCastAddrDel,	/* multicast delete func. */      
  (FUNCPTR)rtl81x9MCastAddrGet,	/* multicast get fun. */          
  (FUNCPTR)rtl81x9PollSend,		/* polling send func. */          
  (FUNCPTR)rtl81x9PollReceive,	/* polling receive func. */       
  endEtherAddressForm,			/* put address info into a NET_BUFFER */
  endEtherPacketDataGet,		/* get pointer to data in NET_BUFFER */
  endEtherPacketAddrGet			/* Get packet addresses. */
  };				

/*数据接收任务0*/
void rtlRecvTask0(RTL81X9END_DEVICE *	pDrvCtrl)
{
	FOREVER
	{
		/* wait for somebody to wake us up */

	    semTake (rtlNetTaskSemId0, WAIT_FOREVER);
	
		rtl81x9HandleRecvInt(pDrvCtrl);
	}
}

/*数据接收任务1*/
void rtlRecvTask1(RTL81X9END_DEVICE *	pDrvCtrl)
{
	FOREVER
	{
		/* wait for somebody to wake us up */

	    semTake (rtlNetTaskSemId1, WAIT_FOREVER);
	
		rtl81x9HandleRecvInt(pDrvCtrl);
	}
}

void rtl8139IntTimer(RTL81X9END_DEVICE  *pDrvCtrl)
{
	unsigned long oldLev;
	while(1)
	{
		oldLev = intLock();
		if(pDrvCtrl->freeDesc<=0)
		{
		if(netJobAdd ((FUNCPTR)rtl81x9HandleTxInt, (int) pDrvCtrl,
	                       0, 0, 0, 0) != OK)
			{
			logMsg("netJobAdd:rtl8139IntTimer error!\n",0,0,0,0,0,0);
			}
		}
		intUnlock(oldLev);

		taskDelay(20);
	}
}


void addTimer(RTL81X9END_DEVICE  *pDrvCtrl)
{
	/*clockid_tint CLOCK_REALTIME;*/
	timer_t mytimer;
	int value = 200;
	
	WDOG_ID   WdId1;
	WdId1 = wdCreate(); 
	
	wdStart(WdId1 , 20, (FUNCPTR)rtl8139IntTimer, pDrvCtrl);
#if 0	
	if(timer_create(CLOCK_REALTIME,0,&mytimer)==ERROR)
	{
	return (ERROR);
	}
	
	if(timer_connect(mytimer,(VOIDFUNCPTR)rtl8139IntTimer,pDrvCtrl)==ERROR)
	{
	return (ERROR);
	}
	
	if(timer_settime(mytimer,0,&value,0)==ERROR)
	{
	   return (ERROR);
	}
#endif
}

/*******************************************************************************
*
* rtl81x9EndLoad - initialize the driver and device
*
* This routine initializes the driver and the device to the operational state.
* All of the device-specific parameters are passed in <initString>, which
* expects a string of the following format:
*
* <unit>:<CSR_reg_addr>:<RAP_reg_addr>:<int_vector>:<int_level>:<shmem_addr>:
* <shmem_size>:<shmem_width>
*
* This routine can be called in two modes. If it is called with an empty but
* allocated string, it places the name of this device (that is, "rtl") into 
* the <initString> and returns 0.
*
* If the string is allocated and not empty, the routine attempts to load
* the driver using the values specified in the string.
*
* RETURNS: An END object pointer, or NULL on error, or 0 and the name of the
* device if the <initString> was NULL.
*/
END_OBJ* rtl81x9EndLoad
    (
    char* initString		/* string to be parse by the driver */
    )
    {
    RTL81X9END_DEVICE 	*pDrvCtrl;
	USHORT				rtl_dev_id = 0;
    int					speed;
	int					i;


    DRV_LOG (DRV_DEBUG_LOAD, "Loading rtl...\n", 1, 2, 3, 4, 5, 6);

    if (initString == NULL)
        return (NULL);
    
    if (initString[0] == NULL)
        {
        bcopy((char *)RTL_DEV_NAME, initString, RTL_DEV_NAME_LEN);
        return (0);
        }
    
    /* allocate the device structure */

    pDrvCtrl = (RTL81X9END_DEVICE *)calloc (sizeof (RTL81X9END_DEVICE), 1);
    if (pDrvCtrl == NULL)
		goto errorExit;

    /* parse the init string, filling in the device structure */

    if (rtl81x9InitParse (pDrvCtrl, initString) == ERROR)
		goto errorExit;

	/* Reset the adaptor */
	rtl81x9Reset (pDrvCtrl);
#if 0
	eepromInit(pDrvCtrl);/*初始化EEPROM*/
	
	/* Read the station address */
	for (i=0; i < 6; i++)
		{
		pDrvCtrl->enetAddr[i] = rtl81x9CsrReadByte (pDrvCtrl, RTL_REGS_IDR0 + i, RTL_WIN_0);
		}
#endif

#if 1/*没有EEPROM*/
	if(pDrvCtrl->unit== 0)
	{

		rtl81x9CsrWriteByte(pDrvCtrl,0x50,0xc0,0);
		
		rtl81x9CsrWriteByte(pDrvCtrl,0x52,0x7f,0);

		rtl81x9CsrWriteWord(pDrvCtrl,0,0xe000,0);
		rtl81x9CsrWriteWord(pDrvCtrl,2,0xaa4d,0);
		rtl81x9CsrWriteWord(pDrvCtrl,4,0x60bb,0);

	for (i=0; i < 6; i++)
		{
		pDrvCtrl->enetAddr[i] = rtl81x9CsrReadByte (pDrvCtrl, RTL_REGS_IDR0 + i, RTL_WIN_0);
		}
/*
		pDrvCtrl->enetAddr[0] = 0;
		pDrvCtrl->enetAddr[1] = 0x08;
		pDrvCtrl->enetAddr[2] = 0x00;
		pDrvCtrl->enetAddr[3] = 0x00;
		pDrvCtrl->enetAddr[4] = 0x08;
		pDrvCtrl->enetAddr[5] = 0x00;
*/
	}
	else
	{
		rtl81x9CsrWriteByte(pDrvCtrl,0x50,0xc0,0);

		rtl81x9CsrWriteWord(pDrvCtrl,0,0xe000,0);
		rtl81x9CsrWriteWord(pDrvCtrl,2,0xaa4d,0);
		rtl81x9CsrWriteWord(pDrvCtrl,4,0x58bb,0);

	for (i=0; i < 6; i++)
		{
		pDrvCtrl->enetAddr[i] = rtl81x9CsrReadByte (pDrvCtrl, RTL_REGS_IDR0 + i, RTL_WIN_0);
		}
	}

#endif
	/*
	 * Now read the exact device type from the EEPROM to find
	 * out if it's an 8129 or 8139.
	 */
	rtl81x9ReadEEPROM (pDrvCtrl, (UCHAR *) &rtl_dev_id, RTL_EE_PCI_DID, 1, 0);
  	DRV_LOG (DRV_DEBUG_LOAD, "rtl_dev_id= 0x%x\n", rtl_dev_id, 2, 3, 4, 5, 6);

	rtl_dev_id = 0x8139;

    /* Perform memory allocation */

    if (rtl81x9InitMem (pDrvCtrl) == ERROR)
		goto errorExit;

	if (rtl_dev_id == RTL_DEVICEID_8139 || rtl_dev_id == ACCTON_DEVICEID_5030 ||
	    rtl_dev_id == DELTA_DEVICEID_8139 || rtl_dev_id == ADDTRON_DEVICEID_8139)
		{
    	if ((rtl81x9CsrReadLong (pDrvCtrl, RTL_REGS_TX_CONFIG, NONE) & RTL_TXCG_BLID))/*vicadd*/
			pDrvCtrl->devType = RTL_DEV_8139A;
		else
			pDrvCtrl->devType = RTL_DEV_8139B;
		}
	else if (rtl_dev_id == RTL_DEVICEID_8129)
		pDrvCtrl->devType = RTL_DEV_8129;
	else {
    	DRV_LOG (DRV_DEBUG_LOAD, "rtl: unknown device ID: %x\n", rtl_dev_id, 2, 3, 4, 5, 6);
		goto errorExit;
	}

    /*speed =  rtl81x9MediaConfig (pDrvCtrl);*/
	speed = 100000000;

	pDrvCtrl->nextDesc = 0;
	pDrvCtrl->freeDesc = RTL_NUM_TX_DESC;

	for (i=0; i < RTL_NUM_TX_DESC; i++)
		pDrvCtrl->pDescMem[i] = NULL; 

    /* Perform memory distribution and reset and reconfigure the device */

    if (rtl81x9RestartSetup (pDrvCtrl) == ERROR)
        goto errorExit;

    /* initialize the END and MIB2 parts of the structure */

    if (END_OBJ_INIT (&pDrvCtrl->end, (DEV_OBJ *)pDrvCtrl, RTL_DEV_NAME,
		    pDrvCtrl->unit, &rtlFuncTable,
                      "RTL 81x9 Fast Ethernet Enhanced Network Driver") == ERROR
     || END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd,
                      &pDrvCtrl->enetAddr[0], 6, ETHERMTU,
                      speed)
		    == ERROR)
		goto errorExit;

    /* set the flags to indicate readiness */

    END_OBJ_READY (&pDrvCtrl->end,
		    IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST
		    | IFF_MULTICAST | IFF_SIMPLEX);

    DRV_LOG (DRV_DEBUG_LOAD, ("rtl81x9EndLoad...\n
			 ADRR: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x \n "), 
			pDrvCtrl->enetAddr[0],
			pDrvCtrl->enetAddr[1],
			pDrvCtrl->enetAddr[2],
			pDrvCtrl->enetAddr[3],
			pDrvCtrl->enetAddr[4],
			pDrvCtrl->enetAddr[5]);

    DRV_LOG (DRV_DEBUG_LOAD, "Done loading rtl...\n", 1, 2, 3, 4, 5, 6);
    
    return (&pDrvCtrl->end);

errorExit:
    if (pDrvCtrl != NULL)
		free ((char *)pDrvCtrl);

    return NULL;
    }



/*******************************************************************************

⌨️ 快捷键说明

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