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

📄 iolicomend.c

📁 操作系统vxworks平台下end设备的驱动程序,支持多种芯片,支持多种cpu
💻 C
📖 第 1 页 / 共 5 页
字号:
     * memory size adjusted to hold the netPool pointer at the head.     */    oliMclBlkConfig.memSize = ((oliMclBlkConfig.mBlkNum *                               (MSIZE + sizeof (long))) +                              (oliMclBlkConfig.clBlkNum *                               (CL_BLK_SZ + sizeof (long))));    if ((oliMclBlkConfig.memArea = (char *)memalign(sizeof (long),			oliMclBlkConfig.memSize)) == NULL)        return (ERROR);    clDesc.clSize       = OLI_BUFSIZ;    clDesc.memSize      = ((clDesc.clNum * (clDesc.clSize + 4)) + 4);    if (DRV_FLAGS_ISSET(OLI_MEMOWN))        {        clDesc.memArea = malloc (clDesc.memSize);        if (clDesc.memArea == NULL)            {            END_LOG_MSG (END_DEBUG_LOAD, "%s%d - system memory unavailable\n",                        DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);            return (ERROR);            }        }    else        clDesc.memArea = (char *) (pDrvCtrl->rxBdBase + pDrvCtrl->rxBdNum);    if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof(NET_POOL))) == NULL)        return (ERROR);    /* Initialize the net buffer pool with transmit buffers */    if (netPoolInit (pDrvCtrl->endObj.pNetPool, &oliMclBlkConfig,                     &clDesc, 1, NULL) == ERROR)        {        END_LOG_MSG (END_DEBUG_LOAD, "%s%d - netPoolInit failed\n",        		DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);        return (ERROR);        }    /* Save the cluster pool id */    pDrvCtrl->clPoolId = clPoolIdGet (pDrvCtrl->endObj.pNetPool,                                      OLI_BUFSIZ, FALSE);    /* Setup the receive ring */    for (ix = 0; ix < pDrvCtrl->rxBdNum; ix++)        {        pBuf = (char *) NET_BUF_ALLOC();        if (pBuf == NULL)            {            END_LOG_MSG (END_DEBUG_LOAD, "%s%d - netClusterGet failed\n",            		DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);            return (ERROR);            }		pBuf = (char *) pBuf + pDrvCtrl->offset;        pDrvCtrl->rxBdBase[ix].dataPointer = pBuf;        }    END_LOG_MSG (END_DEBUG_LOAD, "Memory setup complete\n", 0, 0, 0, 0, 0, 0);    return (OK);    }/********************************************************************************* iOlicomStart - 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 iOlicomStop.  Once a unit is reset by* iOlicomStop, it may be re-initialized to a running state by this routine.** RETURNS: OK if successful, otherwise ERROR*/LOCAL STATUS iOlicomStart    (    END_DEVICE *	pDrvCtrl	/* pointer to END_DEVICE structure */    )    {    STATUS	result;    int		ix;    ULONG	addrC;    END_LOG_MSG (END_DEBUG_ALL_FUNCS, "iOlicomStart()\n", 0, 0, 0, 0, 0, 0);    /* Select bank 0 of the Olicom register set */    SELECTBANK(pDrvCtrl->pcmcia.oliAddr, 0);    /* reset the device */    iOlicomReset (pDrvCtrl);    /* initialize the device */    iOlicomInit (pDrvCtrl);    /* initialize flags */    DRV_FLAGS_CLR(OLI_POLLING | OLI_TX_CLEANING | OLI_TX_STOP);    /* initialize receive buffer descriptors */    for (ix = 0; ix < pDrvCtrl->rxBdNum; ix++)        pDrvCtrl->rxBdBase[ix].statusMode = RX_BD_EMPTY;    pDrvCtrl->rxBdNext = 0;    /* initialize transmit buffer descriptors */    for (ix = 0; ix < pDrvCtrl->txBdNum; ix++)        {	pDrvCtrl->txBdBase[ix].dataPointer =		(char *)(addrC = (RAM_TX_BASE + (ix * OLI_MAX_XMT)));        PCMCIA_IO_WRITE(pDrvCtrl->pcmcia.oliAddr + I595_R12, addrC);        PCMCIA_IO_WRITE(pDrvCtrl->pcmcia.oliAddr + I595_R13, (addrC >> 8));	WRITE_R14_R15 (TX_BD_READY);        }    pDrvCtrl->txBdNext = 0;    pDrvCtrl->txBdIndexC = 0;    /* configure promiscuous mode and multicast addresses list */    iOlicomConfig(pDrvCtrl);    /* connect interrupt */    SYS_INT_CONNECT (pDrvCtrl, iOlicomInt, (int)pDrvCtrl, &result);    if (result == ERROR)	return ERROR;    END_LOG_MSG (END_DEBUG_LOAD, "Interrupt connected.\n", 0, 0, 0, 0, 0, 0);    /* set running & up flags */    END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));    /* enable interrupt */    SYS_INT_ENABLE (pDrvCtrl);    END_LOG_MSG (END_DEBUG_LOAD, "Interrupt enabled.\n", 0, 0, 0, 0, 0, 0);    return (OK);    }/********************************************************************************* iOlicomIntHandle - interrupt service for card interrupts** This routine is called when an interrupt has been detected from the Olicom* card.** RETURNS: N/A.*/void iOlicomIntHandle    (    END_DEVICE *	pDrvCtrl	/* pointer to END_DEVICE structure */    )    {    int		cardStat;    int		intStat;    /*     * Read the card configuration state to verify this is a card I/O     * interrupt.     */    cardStat = PCMCIA_ATTR_READ(pDrvCtrl->pcmcia.oliAttribMem + CARDCONFREG1);    END_LOG_MSG (END_DEBUG_INT, "cardStat (config Reg 1) = 0x%X\n",	    cardStat, 0, 0, 0, 0, 0);    /* I/O Interrupt, examine card to find out what */    if (cardStat & CREG1_INT_IO)	{	END_LOG_MSG (END_DEBUG_INT, "I/O interrupt\n",		     0, 0, 0, 0, 0, 0);	/*	 * Read the chip's interrupt status register to find out why	 * an IRQ was raised.	 */	intStat = PCMCIA_IO_READ(pDrvCtrl->pcmcia.oliAddr + I595_R1);	END_LOG_MSG (END_DEBUG_INT, "intStat (595 Reg 1) = 0x%X\n",		intStat, 0, 0, 0, 0, 0);	/*	 * Decode the interrupt down and take action accordingly. Note	 * that there may be multiple IRQ sources pending.	 */	/* handle receive events */	if (intStat & BNK0_RX_IT)	    {	    /* netTask handles any input packets */	    if (! DRV_FLAGS_ISSET(OLI_RCV_HANDLING))		{		DRV_FLAGS_SET(OLI_RCV_HANDLING);		(void)netJobAdd ((FUNCPTR)iOlicomRxIntHandle,			    (int)pDrvCtrl, 0,0,0,0);		}	    /* Acknowledge receive interrupt */	    PCMCIA_IO_WRITE(pDrvCtrl->pcmcia.oliAddr + I595_R1, BNK0_RX_IT);	    }	/* handle transmitter events */	if (intStat & BNK0_TX_IT)	    {	    /*	     * clean the transmit buffer descriptor queue if we have	     * received a transmit interrupt and if we are not already	     * cleaning this transmit queue.	     */	    if (! DRV_FLAGS_ISSET(OLI_TX_CLEANING))		{		DRV_FLAGS_SET(OLI_TX_CLEANING);		(void)netJobAdd ((FUNCPTR)iOlicomTxBdQueueClean,			    (int)pDrvCtrl, 0,0,0,0);		}	    /* Acknowledge transmit interrupts */	    PCMCIA_IO_WRITE(pDrvCtrl->pcmcia.oliAddr + I595_R1, BNK0_TX_IT);	    }	/* Acknowledge all other interrupts - ignore events */	PCMCIA_IO_WRITE(pDrvCtrl->pcmcia.oliAddr + I595_R1,			     ~(BNK0_TX_IT | BNK0_RX_IT));	if (DRV_FLAGS_ISSET(OLI_TX_STOP))	    /* cause a restart */	    {	    DRV_FLAGS_CLR(OLI_TX_STOP);	    netJobAdd ((FUNCPTR)muxTxRestart, (int)&pDrvCtrl->endObj,			    0, 0, 0, 0);	    }	}    return;    }/********************************************************************************* iOlicomRxIntHandle - task level interrupt service for input packets** This routine is called at task level indirectly by the interrupt* service routine to do any message received processing.** RETURNS: N/A.*/LOCAL void iOlicomRxIntHandle    (    END_DEVICE *	pDrvCtrl	/* pointer to END_DEVICE structure */    )    {    RX_BD *	pRxBd = iOlicomPacketGet (pDrvCtrl);    END_LOG_MSG (END_DEBUG_RX, ("iOlicomRxIntHandle\n"), 0, 0, 0, 0, 0, 0);    do        {        DRV_FLAGS_SET (OLI_RCV_HANDLING);	while (pRxBd != NULL)	    {	    iOlicomRecv (pDrvCtrl, pRxBd);	    pRxBd = iOlicomPacketGet (pDrvCtrl);	    }        DRV_FLAGS_CLR (OLI_RCV_HANDLING);	/* check once more after resetting flags */	pRxBd = iOlicomPacketGet (pDrvCtrl);        }    while (pRxBd != NULL);    }/********************************************************************************* iOlicomPacketGet - get next received message** Get next received message.  Returns NULL if none are ready.** RETURNS: ptr to next packet, or NULL if none ready.*/LOCAL RX_BD * iOlicomPacketGet    (    END_DEVICE *	pDrvCtrl	/* pointer to END_DEVICE structure */    )    {    int			start;    int			event;    int			status;    int			length;    int			s;    int			nextStop;    UINT8 *		pData;    UINT8 *		pDataEnd;    RX_BD *		pRxBd = &pDrvCtrl->rxBdBase[pDrvCtrl->rxBdNext];    volatile UINT8 *	pR14;    END_LOG_MSG (END_DEBUG_RX, "iOlicomPacketGet oliAddr=0x%X\n",    		pDrvCtrl->pcmcia.oliAddr, 0, 0, 0, 0, 0);	    /*     * The RCV STOP register points to the last pair of bytes     * BEFORE the start of the next packet so we must add two     * bytes to reach the correct address.     */    s = intLock();    start = PCMCIA_IO_READ(pDrvCtrl->pcmcia.oliAddr + I595_R6);    start |= (PCMCIA_IO_READ(pDrvCtrl->pcmcia.oliAddr + I595_R7) << 8);    start += 2;    /* Handle the roll over case */    if (start > RAM_RX_LIMIT)	start -= RAM_RX_BASE;    END_LOG_MSG (END_DEBUG_RX, "start= 0x%X\n", start, 0, 0, 0, 0, 0);    /* Set up address from where we wish to start reading data */    PCMCIA_IO_WRITE(pDrvCtrl->pcmcia.oliAddr + I595_R12, start);    PCMCIA_IO_WRITE(pDrvCtrl->pcmcia.oliAddr + I595_R13, (start >> 8));    /* The first word describes the state of reception. */    READ_R14_R15 (event);    /* The following bit will be set once the packet is complete in memory */    if (!(event & RCV_EOF))	{	intUnlock (s);	return ((RX_BD *) NULL);	}    /* Collect the status of the packet */    READ_R14_R15 (status);    /* get next packet pointer */    READ_R14_R15 (nextStop);    /* The next stop value is 2 bytes back in the circular buffer */    nextStop -= 2;    /* Handle the roll over case */    if (nextStop < RAM_RX_BASE)	nextStop += RAM_RX_BASE;    /* get packet length */    READ_R14_R15 (length);    END_LOG_MSG (END_DEBUG_RX, "length= 0x%X\n", length, 0, 0, 0, 0, 0);    /* Check for errors */    if (!(status & RCV_OK))        {        /* Bump input error packet counter */        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);	/* Update the STOP register from the next packet pointer */	PCMCIA_IO_WRITE(pDrvCtrl->pcmcia.oliAddr + I595_R6, nextStop);	PCMCIA_IO_WRITE(pDrvCtrl->pcmcia.oliAddr + I595_R7, (nextStop >> 8));	intUnlock (s);        return ((RX_BD *) NULL);        }    /* check if a receive buffer descriptor is available */    if (!(pRxBd->statusMode & RX_BD_EMPTY))        {        /* Bump input error packet counter */        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);	/* Update the STOP register from the next packet pointer */	PCMCIA_IO_WRITE(pDrvCtrl->pcmcia.oliAddr + I595_R6, nextStop);	PCMCIA_IO_WRITE(pDrvCtrl->pcmcia.oliAddr + I595_R7, (nextStop >> 8));	intUnlock (s);        return ((RX_BD *) NULL);        }    /*     * We always read an even number of bytes from the controller,     * so adjust the length if necessary.     */    if ((length & ODD_MSK) != 0)        ++length;    pRxBd->dataLength = length;    /*     * Read the data from the Rx ring buffer.     *     * Set up the pointer just before the loop: provokes code generator     * into producing much better code.     */    pR14 = (volatile UINT8 *) (pDrvCtrl->pcmcia.oliAddr + I595_R14);    for (pData = (UINT8 *)pRxBd->dataPointer, pDataEnd = pData + length;	 pData != pDataEnd; )	READ_PTR_R14_R15 (pData, pR14);    END_LOG_MSG (END_DEBUG_RX, "data = 0x%X 0x%X\n",		 (pRxBd->dataPointer)[0], (pRxBd->dataPointer)[1], 0, 0, 0, 0);    /* Update the STOP register from the next packet pointer */    PCMCIA_IO_WRITE(pDrvCtrl->pcmcia.oliAddr + I595_R6, nextStop);    PCMCIA_IO_WRITE(pDrvCtrl->pcmcia.oliAddr + I595_R7, (nextStop >> 8));    /* Update status buffer descriptor */    pRxBd->statusMode = 0;    /* incr buffer descriptor count */    pDrvCtrl->rxBdNext = (pDrvCtrl->rxBdNext + 1) % pDrvCtrl->rxBdNum;    intUnlock (s);    return pRxBd;    }/********************************************************************************* iOlicomRecv - process the next incoming packet** This routine processes an input frame, then passes it up to the higher* level in a form it expects.** RETURNS: OK, always.*/

⌨️ 快捷键说明

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