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

📄 rtl81x9.c

📁 在Tornado环境下实现的8139网卡芯片的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    )    {    UINT	sz = 0;           	/* temporary size holder */    /***** Establish size of shared memory region we require *****/    /*DRV_LOG (DRV_DEBUG_LOAD, "rtl81x9InitMem\n", 0, 0, 0, 0, 0, 0);*/    if ((int) pDrvCtrl->memAdrs != NONE)  /* specified memory pool */        {        /*         * With a specified memory pool we want to maximize         * rtlRsize and rtlTsize         */		DRV_LOG (DRV_DEBUG_LOAD, "No memAdrs supplied\n", 0, 0, 0, 0, 0, 0);         sz = (pDrvCtrl->memSize - (RMD_SIZ + sizeof (rtl_ib)))               / ((2 * RTL_BUFSIZ) + RMD_SIZ);        sz >>= 1;               /* adjust for roundoff */        for (rtlRsize = 0; sz != 0; rtlRsize++, sz >>= 1)        	;        }    /* limit ring sizes to reasonable values */    rtlRsize = max (rtlRsize, 2);		/* 4 Rx buffers is reasonable min */    rtlRsize = min (rtlRsize, 7);		/* 128 Rx buffers is max for chip */    /* Add it all up */    sz = (((1 << rtlRsize) + 1) * RMD_SIZ) + IB_SIZ + 24;    /*DRV_LOG (DRV_DEBUG_LOAD, "sx - %d\n",sz, 0, 0, 0, 0, 0); */    /***** Establish a region of shared memory *****/    /* OK. We now know how much shared memory we need.  If the caller     * provides a specific memory region, we check to see if the provided     * region is large enough for our needs.  If the caller did not     * provide a specific region, then we attempt to allocate the memory     * from the system, using the cache aware allocation system call.     */    switch ((int) pDrvCtrl->memAdrs)        {        default :       /* caller provided memory */            if (pDrvCtrl->memSize < sz)     /* not enough space */                {    			DRV_LOG (DRV_DEBUG_LOAD, "rtl81x9: not enough memory provided need %ul got %d\n",                          						pDrvCtrl->memSize, sz, 0, 0, 0, 0);                return (NULL);                }	    	/* set the beginning of pool */            pDrvCtrl->pShMem = pDrvCtrl->memAdrs;            /* assume pool is cache coherent, copy null structure */            pDrvCtrl->cacheFuncs = cacheNullFuncs;    		DRV_LOG (DRV_DEBUG_LOAD, "Memory checks out\n",0, 0, 0, 0, 0, 0);             break;        case NONE :     /* get our own memory */            /* Because the structures that are shared between the device             * and the driver may share cache lines, the possibility exists             * that the driver could flush a cache line for a structure and             * wipe out an asynchronous change by the device to a neighboring             * structure. Therefore, this driver cannot operate with memory             * that is not write coherent.  We check for the availability of             * such memory here, and abort if the system did not give us what             * we need.             */            if (!CACHE_DMA_IS_WRITE_COHERENT ())                {                DRV_LOG (DRV_DEBUG_LOAD, "rtl: device requires cache coherent memory\n", 0, 0, 0, 0, 0, 0);                return (ERROR);                }            pDrvCtrl->pShMem = (char *) cacheDmaMalloc (sz);            if ((int)pDrvCtrl->pShMem == NULL)                {                DRV_LOG (DRV_DEBUG_LOAD, "rtl: system memory unavailable\n", 0, 0, 0, 0, 0, 0);                return (ERROR);                }            /* copy the DMA structure */            pDrvCtrl->cacheFuncs = cacheDmaFuncs;            break;        }    /*                        Turkey Carving     *                        --------------     *     *                          LOW MEMORY     *     *             |----------------------------------------|     *             |       The initialization block         |     *             |         (sizeof (rtl_ib))              |     *             |----------------------------------------|     *             |         The Rx descriptors             |     *             | ((1 << rtlRsize) + 1)*sizeof (RTL_RMD) |     *             |----------------------------------------|     */    /* align */    pDrvCtrl->pShMem = (char *) ( ( (int)pDrvCtrl->pShMem + 3) & ~3);    /* Save some things */    pDrvCtrl->memBase  = (char *)((ULONG)pDrvCtrl->pShMem & 0xff000000);    if ((int) pDrvCtrl->memAdrs == NONE)        pDrvCtrl->flags |= RTL_FLG_MEM_ALLOC_FLAG;    /* first let's clear memory */    bzero ((char *) pDrvCtrl->pShMem, (int) sz);     /* setup Rx memory pointers */    pDrvCtrl->pRring      = (RTL_RMD *) ((int)pDrvCtrl->pShMem + IB_SIZ);    pDrvCtrl->rringLen    = rtlRsize;    pDrvCtrl->rringSize   = 1 << rtlRsize;   	/* Allocate a chunk of memory for the Chip to place the Rx Buffers in */		pDrvCtrl->ptrRxBufSpace = malloc (RTL_RXBUFLEN + 64);	pDrvCtrl->ptrRxBufSpace += 4;	if (pDrvCtrl->ptrRxBufSpace == NULL)		{		DRV_LOG (DRV_DEBUG_LOAD, "ptrRxBufSpace == NULL\n", 0, 0, 0, 0, 0, 0);		return (ERROR);		}    pDrvCtrl->rmdNext = 0;    /*     * Allocate receive buffers from our own private pool.     */    if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL)        return (ERROR);    rtlMclConfig.mBlkNum = pDrvCtrl->rringSize * 2;    rtlClDesc[0].clNum = pDrvCtrl->rringSize *2;    rtlMclConfig.clBlkNum = rtlClDesc[0].clNum;    rtlMclConfig.memSize = (rtlMclConfig.mBlkNum * (MSIZE + sizeof (long))) +                          (rtlMclConfig.clBlkNum * (CL_BLK_SZ + sizeof(long)));    if ((rtlMclConfig.memArea = (char *) memalign (sizeof(long),                                                  rtlMclConfig.memSize))        == NULL)        return (ERROR);    rtlClDesc[0].clNum = pDrvCtrl->rringSize *2;        rtlClDesc[0].memSize = (rtlClDesc[0].clNum * (RTL_BUFSIZ + 8))        + sizeof(int);    if ((int) pDrvCtrl->memAdrs != NONE) /* Do we hand over our own memory? */        {        rtlClDesc[0].memArea =                 (char *)(pDrvCtrl->pRring + (((1 << rtlRsize) + 1) * RMD_SIZ));        }    else        {        rtlClDesc[0].memArea =            (char *) cacheDmaMalloc (rtlClDesc[0].memSize);        if ((int)rtlClDesc[0].memArea == NULL)            {            DRV_LOG(DRV_DEBUG_LOAD,                    "system memory unavailable\n", 1, 2, 3, 4, 5, 6);            return (ERROR);            }        }    if (netPoolInit(pDrvCtrl->end.pNetPool, &rtlMclConfig,                    &rtlClDesc[0], rtlClDescNumEnt, NULL) == ERROR)        {    	DRV_LOG (DRV_DEBUG_LOAD, "Could not init buffering\n",0, 0, 0, 0, 0, 0);         return (ERROR);        }    /* Store the cluster pool id as others need it later. */    pDrvCtrl->pClPoolId = clPoolIdGet(pDrvCtrl->end.pNetPool,                                      RTL_BUFSIZ, FALSE);    return OK;    }/********************************************************************************* rtl81x9Start - start the device** This function initializes the device and calls BSP functions to connect* interrupts and start the device running in interrupt mode.** The complement of this routine is rtl81x9Stop.  Once a unit is reset by* rtl81x9Stop, it may be re-initialized to a running state by this routine.** RETURNS: OK if successful, otherwise ERROR*/LOCAL STATUS rtl81x9Start    (    RTL81X9END_DEVICE *	pDrvCtrl    )    {    STATUS 	result;	int		rxcfg;    DRV_LOG (DRV_DEBUG_ALL, "RTL81x9 start\n",1 , 2, 3, 4, 5, 6);		    pDrvCtrl->txBlocked = FALSE;    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);    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;			/* 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_INT, "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);			}    	/* Check for transmit Interrupt */		if (stat & RTL_IPT_TX_OK)			{        	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);			}								}    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

⌨️ 快捷键说明

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