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

📄 rtl81x9.c

📁 VxWorks系统realtek8139网卡驱动(源码).zip
💻 C
📖 第 1 页 / 共 5 页
字号:


/* 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 *);

/* 
 * 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. */
  };				


/*******************************************************************************
*
* 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 (RTL_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);

	/* Read the station address */
	for (i=0; i < 6; i++)
		{
		pDrvCtrl->enetAddr[i] = rtl81x9CsrReadByte (pDrvCtrl, RTL_REGS_IDR0 + i, RTL_WIN_0);
		}
				
	/*
	 * 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);


    /* 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 ((rtl81x9CsrReadWord (pDrvCtrl, RTL_REGS_TX_CONFIG, NONE) & RTL_TXCG_BLID))
			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 (RTL_DRV_DEBUG_LOAD, "rtl: unknown device ID: %x\n", rtl_dev_id, 2, 3, 4, 5, 6);
		goto errorExit;
	}

    speed =  rtl81x9MediaConfig (pDrvCtrl);

	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 (RTL_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;
    }



/*******************************************************************************
*
* rtl81x9InitParse - parse parameter values from initString
*
* Parse the input string.  Fill in values in the driver control structure.
*
* The initialization string format is:
* "<device addr>:<PCI addr>:<ivec>:<ilevel>:<mem base>:<mem size>:	\
*  <user flags>:<offset>"
*
* .IP <device addr>
* base address of hardware device registers
* .IP <PCI addr>
* main memory address over the PCI bus
* .IP <ivec>
* interrupt vector number
* .IP <ilevel>
* interrupt level
* .IP <mem base>
* base address of a DMA-able, cache free,pre-allocated  memory
* .IP <mem size>
* size of the pre-allocated memory
* .IP <user flags>
* User flags control the run-time characteristics of the chip
* .IP <offset>
* Memory offset for alignment
* .LP
*
* RETURNS: OK or ERROR for invalid arguments.
*/

LOCAL STATUS rtl81x9InitParse
    (
    RTL81X9END_DEVICE *	pDrvCtrl,
    char *	initString
    )
    {
    char *		tok;
    char**      holder = NULL;
    UINT32      devMemAddr;
    UINT32      devIoAddr;

    /* Parse the initString */

    DRV_LOG (RTL_DRV_DEBUG_LOAD, "Parse starting ...\n", 1, 2, 3, 4, 5, 6);

    /* Unit number. */

    tok = strtok_r (initString, ":", holder);
    if (tok == NULL)
        return ERROR;

    pDrvCtrl->unit = atoi (tok);

    DRV_LOG (RTL_DRV_DEBUG_LOAD, "Unit : %d ...\n", pDrvCtrl->unit, 2, 3, 4, 5, 6);

    /* devAdrs address. */

    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    devMemAddr = (UINT32) strtoul (tok, NULL, 16);

    DRV_LOG (RTL_DRV_DEBUG_LOAD, "devMemAddr : 0x%X ...\n", devMemAddr,
             2, 3, 4, 5, 6);

    /* devIoAddrs address */

    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    devIoAddr = (UINT32) strtoul (tok, NULL, 16);


    /* always use memory mapped IO if provided, else use io map */
    
    if ((devMemAddr == NONE) && (devIoAddr == NONE))
		{
        DRV_LOG (RTL_DRV_DEBUG_LOAD, "No memory or IO base specified ...\n",
                 1, 2, 3, 4, 5, 6);
        return (ERROR);
		}
    else if (devMemAddr != NONE)
        {
        pDrvCtrl->devAdrs = devMemAddr;
        pDrvCtrl->flags   |= RTL_FLG_MODE_MEM_IO_MAP;
        DRV_LOG (RTL_DRV_DEBUG_LOAD, "devMemAddr specified for devAdrs ...\n",
                 1, 2, 3, 4, 5, 6);
        }
    else
		{
        pDrvCtrl->devAdrs = devIoAddr;
        DRV_LOG (RTL_DRV_DEBUG_LOAD, "devIoAddr specified for devAdrs - 0x%X ...\n",
                 devIoAddr, 2, 3, 4, 5, 6);
		}
        
    /* PCI memory base address as seen from the CPU */
    
    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    pDrvCtrl->pciMemBase = strtoul (tok, NULL, 16);

    DRV_LOG (RTL_DRV_DEBUG_LOAD, "Pci : 0x%X ...\n", pDrvCtrl->pciMemBase,
             2, 3, 4, 5, 6);

    /* Interrupt vector. */

    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    pDrvCtrl->ivec = atoi (tok);

    DRV_LOG (RTL_DRV_DEBUG_LOAD, "ivec : 0x%X ...\n", pDrvCtrl->ivec,
             2, 3, 4, 5, 6);

    /* Interrupt level. */

    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    pDrvCtrl->ilevel = atoi (tok);

    DRV_LOG (RTL_DRV_DEBUG_LOAD, "ilevel : 0x%X ...\n", pDrvCtrl->ilevel,
             2, 3, 4, 5, 6);

    /* Caller supplied memory address. */

    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    pDrvCtrl->memAdrs = (char *)strtoul (tok, NULL, 16);

    DRV_LOG (RTL_DRV_DEBUG_LOAD, "memAdrs : 0x%X ...\n", (int)pDrvCtrl->memAdrs,
             2, 3, 4, 5, 6);

    /* Caller supplied memory size. */

    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    pDrvCtrl->memSize = strtoul (tok, NULL, 16);

    DRV_LOG (RTL_DRV_DEBUG_LOAD, "memSize : 0x%X ...\n", pDrvCtrl->memSize,
             2, 3, 4, 5, 6);

    /* Caller supplied memory width. */

    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    pDrvCtrl->memWidth = atoi (tok);

    DRV_LOG (RTL_DRV_DEBUG_LOAD, "memWidth : 0x%X ...\n", pDrvCtrl->memWidth,
             2, 3, 4, 5, 6);

    /* CSR3B value */

    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
        return ERROR;
    pDrvCtrl->csr3B = strtoul (tok, NULL, 16);

    DRV_LOG (RTL_DRV_DEBUG_LOAD, "csr3b value : %d ...\n", pDrvCtrl->csr3B,
             2, 3, 4, 5, 6);

    /* Caller supplied alignment offset. */
    tok = strtok_r (NULL, ":", holder);
    if (tok == NULL)
	return ERROR;
    pDrvCtrl->offset = atoi (tok);

    DRV_LOG (RTL_DRV_DEBUG_LOAD, "offset value : %d ...\n", pDrvCtrl->offset,

⌨️ 快捷键说明

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