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

📄 esmcend.c

📁 基于嵌入式操作系统VxWorks的lan91c111的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
        pBuf = (unsigned char *) pNode->pCluster;        /* Fetch an mBlk */        pMblk = mBlkGet(pDev->endObj.pNetPool, M_DONTWAIT, MT_DATA);        if (!pMblk)        {            DRV_LOG(DRV_DEBUG_RX, "%s%d: esmcHandleRcvInt: Out of M blocks!\n",                    (int) DEV_NAME, pDev->unit, 3, 4, 5, 6);            /* Save the cluster node and reschedule ourselves */            oldLevel = intLock();            lstInsert(&pDev->busyClusters, NULL, (NODE *) pNode);            intUnlock(oldLevel);            netJobAdd((FUNCPTR) esmcHandleRcvInt, (int) pDev, 0, 0, 0, 0);            goto exit;        }        /* Fetch a ClBlk */        pClBlk = netClBlkGet(pDev->endObj.pNetPool, M_DONTWAIT);        if (!pClBlk)        {            DRV_LOG(DRV_DEBUG_RX, "%s%d: esmcHandleRcvInt: Out of CL blocks!\n",                    (int) DEV_NAME, pDev->unit, 3, 4, 5, 6);            /* Free the Mblk */                        netMblkFree(pDev->endObj.pNetPool, (M_BLK_ID) pMblk);            /* Save the cluster node and reschedule ourselves */            oldLevel = intLock();            lstInsert(&pDev->busyClusters, NULL, (NODE *) pNode);            intUnlock(oldLevel);            netJobAdd((FUNCPTR) esmcHandleRcvInt, (int) pDev, 0, 0, 0, 0);            goto exit;        }        /* Join ClBlk to cluster */        netClBlkJoin(pClBlk, pBuf, ESMC_BUFSIZ, NULL, 0, 0, 0);            /* Join the mBlk and ClBlk */                netMblkClJoin(pMblk, pClBlk);	/* Complete the mBlk header */        pMblk->mBlkHdr.mFlags |= M_PKTHDR;        pMblk->mBlkHdr.mLen    = pNode->length;	pMblk->mBlkPktHdr.len  = pMblk->mBlkHdr.mLen;        pMblk->mBlkHdr.mData  += pDev->offset;	/* Bump input packet counter */	END_ERR_ADD(&pDev->endObj, MIB2_IN_UCAST, +1);	/* Send up to protocol */	END_RCV_RTN_CALL(&pDev->endObj, pMblk);        /* Fetch another cluster to replace the one just loaned */        while ((pNode->pCluster = netClusterGet(pDev->endObj.pNetPool,                                                pDev->clPoolId)) == NULL)        {            DRV_LOG(DRV_DEBUG_RX, "Could not reallocate cluster; retrying\n",                    1, 2, 3, 4, 5, 6);            taskDelay(1);        }        /* Place cluster node back into free list */            oldLevel = intLock();        lstAdd(&pDev->freeClusters, (NODE *) pNode);        intUnlock(oldLevel);    }    oldLevel = intLock();    pDev->flags &= ~ESMC_RCV_HANDLING_FLAG;    intUnlock(oldLevel);    return;exit:    /* Bump the error counter */        END_ERR_ADD(&pDev->endObj, MIB2_IN_ERRS, +1);    oldLevel = intLock();    pDev->flags &= ~ESMC_RCV_HANDLING_FLAG;    intUnlock(oldLevel);    return;#else     oldLevel = intLock();    ESMC_SWITCH_BANK (pDev, 2);    WRITE_WORD(pDev,ESMC_INTERRUPT_, 0);             /* mask all interrupts */    intUnlock(oldLevel);        while (!((packetNo = READ_WORD(pDev,ESMC_FIFO)) & ESMC_FIFO_REMPTY))    {        ESMC_SWITCH_BANK (pDev, 2);        WRITE_WORD (pDev,ESMC_PTR, ESMC_PTR_READ | ESMC_PTR_RCV | ESMC_PTR_AUTOINC);        ldata = sysInLong(pDev->base + ESMC_DATA_1);        statusRx = ldata & 0x0000FFFF;        len = (ldata >> 16) & 0x0000FFFF;        DRV_LOG (DRV_DEBUG_RX, "%s%d: esmcHandleRcvInt: statusRx = 0x%0x len = 0x%0x\n",                 (int) DEV_NAME, pDev->unit, statusRx, len, 0, 0);         /* check for receive errors */        if (statusRx & ESMC_RS_ERROR_MASK)        {            /* increment appropriate error counter */            if(statusRx &  ESMC_RS_ALGNERR)                pDev->alignErr++;                        if(statusRx &  ESMC_RS_BADCRC)                pDev->badCrc++;            if(statusRx &  ESMC_RS_TOOLONG)                pDev->tooLong++;            if(statusRx &  ESMC_RS_TOOSHORT)                pDev->tooShort++;            do            {                 val = READ_WORD(pDev, ESMC_MMU);            } while (val & ESMC_MMU_BUSY);            WRITE_WORD(pDev, ESMC_MMU, ESMC_MMU_RX_RELEASE); /* release */        }        else        {            pBuf = netClusterGet (pDev->endObj.pNetPool, pDev->clPoolId);            if (!pBuf)            {                DRV_LOG (DRV_DEBUG_RX, "%s%d: esmcHandleRcvInt: Out of clusters!\n",                    (int) DEV_NAME, pDev->unit, 0, 0, 0, 0);                /* re-schedule ourselves */                netJobAdd((FUNCPTR) esmcHandleRcvInt,(int) pDev, 0, 0, 0, 0);                goto exit;            }            pMblk = mBlkGet (pDev->endObj.pNetPool, M_DONTWAIT, MT_DATA);            if (!pMblk)            {                netClFree (pDev->endObj.pNetPool, (UCHAR *) pBuf);                DRV_LOG (DRV_DEBUG_RX, "%s%d: esmcHandleRcvInt: Out of M blocks!\n",                    (int) DEV_NAME, pDev->unit, 0, 0, 0, 0);                /* re-schedule ourselves */                netJobAdd((FUNCPTR) esmcHandleRcvInt,(int) pDev, 0, 0, 0, 0);                goto exit;            }                                pClBlk = netClBlkGet (pDev->endObj.pNetPool, M_DONTWAIT);            if (!pClBlk)            {                netMblkFree (pDev->endObj.pNetPool, (M_BLK_ID)pMblk);                netClFree (pDev->endObj.pNetPool, (UCHAR *) pBuf);                DRV_LOG (DRV_DEBUG_RX, "%s%d: esmcHandleRcvInt: Out of CL blocks!\n",                    (int) DEV_NAME, pDev->unit, 0, 0, 0, 0);                /* re-schedule ourselves */                netJobAdd((FUNCPTR) esmcHandleRcvInt,(int) pDev, 0, 0, 0, 0);                goto exit;            }            /* Associate the data pointer with the MBLK */            netClBlkJoin (pClBlk, pBuf, ESMC_BUFSIZ, NULL, 0, 0, 0);                /* Associate the data pointer with the MBLK */            netMblkClJoin (pMblk, pClBlk);            /* finally - read in the packet */            pCur = (unsigned short *) (pBuf + pDev->offset);            /* adjust len for first 4 bytes read */            len -=4;            for(i = 0 ; i < (len >> 1) ; i++)            {                ldata     = sysInLong(pDev->base + ESMC_DATA_1);                val       = ldata & 0x0000FFFF;                pCur[i++] = SWAP_BYTES_IF_NECESSARY(val);                val       = (ldata >> 16) & 0x0000FFFF;                pCur[i]   = SWAP_BYTES_IF_NECESSARY(val);            }            /* adjust length for control byte and odd byte */            if (statusRx & ESMC_RS_ODDFRM)                len -= 1;            else                len -= 2;            do            {                 val = READ_WORD(pDev, ESMC_MMU);            } while (val & ESMC_MMU_BUSY);            WRITE_WORD(pDev,ESMC_MMU, ESMC_MMU_RX_RELEASE); /* release */             pMblk->mBlkHdr.mFlags |= M_PKTHDR;            pMblk->mBlkHdr.mLen    = len;            pMblk->mBlkPktHdr.len  = len;            pMblk->mBlkHdr.mData  += pDev->offset;                        /* Call the upper layer's receive routine. */            END_RCV_RTN_CALL (&pDev->endObj, pMblk);            /* Record received packet */            END_ERR_ADD (&pDev->endObj, MIB2_IN_UCAST, +1);        }    }                         /* re-enable receive interrupt */    oldLevel = intLock();    pDev->flags &= ~ESMC_RCV_HANDLING_FLAG;    pDev->imask |= (ESMC_INT_RCV << 8);    intUnlock(oldLevel);exit:    oldLevel = intLock();    WRITE_WORD(pDev, ESMC_INTERRUPT_, pDev->imask);    intUnlock(oldLevel);        DRV_LOG (DRV_DEBUG_RX, "%s%d: esmcHandleRcvInt: imask = %0x\n",                 (int) DEV_NAME, pDev->unit, pDev->imask, 0,0,0);    return;#endif /* ESMC_USE_ISR_COPY */ }#ifdef ESMC_USE_ISR_COPY/******************************************************************************** esmcIsrCopy - copy received frames from FIFO to preallocated clusters** This routine is called by the ISR to copy received frames from the FIFO* to preallocated clusters.  This should free FIFO frames more quickly,* but will increase interrupt latency.  The ESMC device register bank is* assumed to be set to 2 on entry.** RETURNS: N/A.*/LOCAL void esmcIsrCopy(    ESMC_DEVICE  *pDev){    unsigned short      packetNo = 0;    unsigned long       ldata;    unsigned short      val;    int                 length;    unsigned short      statusRx;    CLUSTER_NODE        *pNode;    BOOL                released;    unsigned short      *pCur;    int                 i;    /* Read packet number from RX fifo */    while (!((packetNo = READ_WORD(pDev, ESMC_FIFO)) & ESMC_FIFO_REMPTY))    {        /* Obtain a free preallocated cluster */        released = FALSE;        if ((pNode = (CLUSTER_NODE *) lstGet(&pDev->freeClusters)) != NULL)        {            /* Program the MMU to read the frame */                WRITE_WORD(pDev, ESMC_PTR,                       ESMC_PTR_READ | ESMC_PTR_RCV | ESMC_PTR_AUTOINC);            /* Read packet status and length */	            ldata = sysInLong(pDev->base + ESMC_DATA_1);            statusRx = ldata & 0x0000FFFF;            length = (ldata >> 16) & 0x0000FFFF;						DRV_LOG (DRV_DEBUG_FN_TRACE, "YK:%s%d: esmcIsrCopy statusRx 0x%x length %d\n",(int) DEV_NAME, pDev->unit,statusRx, length, 5, 6);            /* If no error indicated, fetch the packet */	            if (statusRx & ESMC_RS_ERROR_MASK)            {                                /* Increment appropriate error counters */                if (statusRx & ESMC_RS_ALGNERR)                    pDev->alignErr++;                            if (statusRx & ESMC_RS_BADCRC)                    pDev->badCrc++;                if (statusRx & ESMC_RS_TOOLONG)                    pDev->tooLong++;                if (statusRx & ESMC_RS_TOOSHORT)                    pDev->tooShort++;                                END_ERR_ADD(&pDev->endObj, MIB2_IN_ERRS, +1);                /* Add the node back to the free list */                lstAdd(&pDev->freeClusters, (NODE *) pNode);            }            else            {                /* Point to cluster */                pCur = (unsigned short *) ((char *) pNode->pCluster +                                           pDev->offset);                /* Adjust length for bytes already read */                                length -= 4;                                /* Copy the data from FIFO to cluster */                for (i = 0 ; i < (length >> 1) ; i++)                {                    ldata     = sysInLong(pDev->base + ESMC_DATA_1);                    val       = ldata & 0x0000FFFF;                    pCur[i++] = SWAP_BYTES_IF_NECESSARY(val);                    val       = (ldata >> 16) & 0x0000FFFF;                    pCur[i]   = SWAP_BYTES_IF_NECESSARY(val);                }                /* Adjust length for control byte and odd byte */                if (statusRx & ESMC_RS_ODDFRM)                    length -= 1;                else                    length -= 2;                                /* Wait until MMU is free */                do                {                    val = READ_WORD(pDev, ESMC_MMU);                } while (val & ESMC_MMU_BUSY);                /* Release the memory associated with the packet ASAP */                WRITE_WORD(pDev, ESMC_MMU, ESMC_MMU_RX_RELEASE);                released = TRUE;                /* Complete the cluster node and queue it to the busy list */                pNode->length   = length;                pNode->packetNo = packetNo;                pNode->statusRx = statusRx;                lstAdd(&pDev->busyClusters, (NODE *) pNode);            }        }        else        {            /* Bump the error counter */                END_ERR_ADD(&pDev->endObj, MIB2_IN_ERRS, +1);        }        if (!released)        {            /* Wait until MMU is free */	              do            {                val = READ_WORD(pDev, ESMC_MMU);            } while (val & ESMC_MMU_BUSY);            /* Release the memory associated with the packet */            WRITE_WORD(pDev, ESMC_MMU, ESMC_MMU_RX_RELEASE);        }    }}#endif /* ESMC_USE_ISR_COPY *//******************************************************************************** esmcIsr - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.** RETURNS: N/A.*/LOCAL void esmcIsr(    ESMC_DEVICE  *pDev){    unsigned short bank;    unsigned short savedPointer;    unsigned short savedPacket;    unsigned short val;    unsigned char  status;    bank = READ_WORD(pDev,ESMC_BANK_SELECT);   /* save bank */    if((bank & 0x03) != 2)        ESMC_SWITCH_BANK (pDev,2);    val = READ_WORD(pDev, ESMC_INTERRUPT_);    DRV_ASSERT(((val & 0xff00) & ~pDev->imask) == 0);    WRITE_WORD(pDev,ESMC_INTERRUPT_, 0);  /* mask all interrupts */    DRV_ASSERT((READ_WORD(pDev,ESMC_BANK_SELECT) & 0x03) == 2);    DRV_LOG (DRV_DEBUG_FN_TRACE, "%s%d: esmcIsr status=%x\n",         (int) DEV_NAME, pDev->unit, val, 4, 5, 6);    status = LO_BYTE(val) & HI_BYTE(val);    if(status == 0)        goto exit;    if (status & (ESMC_INT_RCV | ESMC_INT_RX_OVRN)) /* RX done */    {#ifdef ESMC_USE_ISR_COPY                    /* Copy and release all available received frames */                    esmcIsrCopy(pDev);            #endif /* ESMC_USE_ISR_COPY */        if(!(pDev->flags & ESMC_RCV_HANDLING_FLAG))        {            if (netJobAdd ((FUNCPTR) esmcHandleRcvInt,                    (int) pDev, 0, 0, 0, 0) == ERROR)            {                logMsg ("%s%d: failed to queue esmcHandleRcvInt\n",                        (int) DEV_NAME, pDev->unit, 3, 4, 5, 6);                /* failed netJobAdd causes panic */                goto exit;            }            else            {                pDev->flags |= ESMC_RCV_HANDLING_FLAG;#ifndef ESMC_USE_ISR_COPY                pDev->imask &= ~(ESMC_INT_RCV << 8);  /* disable further receive interrupts */

⌨️ 快捷键说明

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