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

📄 sh7615end.c

📁 操作系统vxworks平台下end设备的驱动程序,支持多种芯片,支持多种cpu
💻 C
📖 第 1 页 / 共 5 页
字号:
    /*     * We implicitly are loaning here, if copying is necessary this     * step may be skipped, but the data must be copied before being     * passed up to the protocols.     */        pNewCluster = NET_BUF_ALLOC ();    if (pNewCluster == NULL)        {	pDrvCtrl->lastError.errCode = END_ERR_NO_BUF;	muxError (&pDrvCtrl->end, &pDrvCtrl->lastError);	DRV_LOG (DRV_DEBUG_RX, "Cannot loan!\n", 1, 2, 3, 4, 5, 6);	END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);	goto cleanRxD;        }    /* Grab a cluster block to marry to the cluster we received. */    if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL)        {	pDrvCtrl->lastError.errCode = END_ERR_NO_BUF;	muxError (&pDrvCtrl->end, &pDrvCtrl->lastError);        NET_BUF_FREE (pNewCluster);	DRV_LOG (DRV_DEBUG_RX, "Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6);	END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);	goto cleanRxD;        }        /*     * OK we've got a spare, let's get an M_BLK_ID and marry it to the     * one in the ring.     */    if ((pMblk = mBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL)        {        netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk);         NET_BUF_FREE (pNewCluster);	DRV_LOG (DRV_DEBUG_RX, "Out of M Blocks!\n", 1, 2, 3, 4, 5, 6);	END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);	goto cleanRxD;        }    END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);    len = SH7615END_FRAME_LEN_GET (pRxD->rDesc1);     /*     * Invalidate cache and copy to ensure 4 byte alignment of IP header.     * This is required by the IP network stack.     */     SH7615END_CACHE_INVALIDATE ((char *) (pRxD->rDesc2), len);    len = (len + 1) & 0xfffffffe;    bcopy((char*)pRxD->rDesc2,(char*)pRxD->rDesc2+2,len);    /* Join the cluster to the MBlock */    netClBlkJoin (pClBlk, (char *) (pRxD->rDesc3), SH7615END_BUFSIZ, NULL, 		  0, 0, 0);    netMblkClJoin (pMblk, pClBlk);    pMblk->mBlkHdr.mFlags |= M_PKTHDR;    pMblk->mBlkHdr.mLen = len;    pMblk->mBlkHdr.mData = (char *) (pRxD->rDesc2 + 2);    pMblk->mBlkPktHdr.len  = pMblk->mBlkHdr.mLen;    /* save the new True data buffer address for freeing later */     pRxD->rDesc3 = (UINT32) pNewCluster;    /* Install new data buffer - force 16 byte alignment */    pRxD->rDesc2 = NET_TO_SH7615END_BUF (pNewCluster);    /* mark the descriptor ready to receive, preserve the RDL bit */     pRxD->rDesc0 = (pRxD->rDesc0 & RD0_RDL) | RD0_OWN;     /* advance management index */     pDrvCtrl->rxIndex = (pDrvCtrl->rxIndex + 1) % pDrvCtrl->numRds;     /* Call the upper layer's receive routine. */    DRV_LOG (DRV_DEBUG_RX, "Calling upper layer!\n", 1, 2, 3, 4, 5, 6);    END_RCV_RTN_CALL(&pDrvCtrl->end, pMblk);    return (OK);cleanRxD:    /* mark the descriptor ready to receive - make sure to preserve the RDL bit */    pRxD->rDesc0 = (pRxD->rDesc0 & RD0_RDL) | RD0_OWN;     /* advance management index */     pDrvCtrl->rxIndex = (pDrvCtrl->rxIndex + 1) % pDrvCtrl->numRds;    return (OK);    }/********************************************************************************* sh7615EndRcvIntHandle - 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 sh7615EndRcvIntHandle    (    DRV_CTRL *pDrvCtrl	/* interrupting device */    )    {    SH7615_RD *pRxD;    pDrvCtrl->rxHandling = TRUE;	/* interlock with sh7615EndInt() */    while ((pRxD = sh7615EndRxDGet (pDrvCtrl)) != NULL)	sh7615EndRecv (pDrvCtrl, pRxD);    pDrvCtrl->rxHandling = FALSE;	/* interlock with sh7615EndInt() */    /* Make sure the Receive Request is still ON */    SH7615END_REG_WRITE(E_DMAC_EDRRR, EDRRR_RR);    /* enable receive interrupt */    SH7615END_BIT_SET (E_DMAC_EESIPR, EESIPR_FRIP);    }/********************************************************************************* sh7615EndSend - transmit an ethernet packet** This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it.  This is done by a higher layer.  The last arguments are a free* routine to be called when the device is done with the buffer and a pointer* to the argument to pass to the free routine.** RETURNS: OK on success; and ERROR otherwise.*/ LOCAL STATUS sh7615EndSend    (    DRV_CTRL *	pDrvCtrl,    M_BLK *	pMblk    )    {    SH7615_TD *	pTxD;    char *      pBuf;    int         len;    DRV_LOG (DRV_DEBUG_TX, "EndSend\n", 1, 2, 3, 4, 5, 6);    /* Gain exclusive access to transmit */    END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER);     /* Get the next TXD */    pTxD = sh7615EndTxDGet (pDrvCtrl);    if (pTxD == NULL)        {        DRV_LOG (DRV_DEBUG_TX, "No available TxD-s \n", 1, 2, 3, 4, 5, 6);        END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_ERRS, +1);        END_TX_SEM_GIVE (&pDrvCtrl->end);         if (!pDrvCtrl->txCleaning && !pDrvCtrl->txBlocked)            sh7615EndTxRingClean (pDrvCtrl);         pDrvCtrl->txBlocked = TRUE;        /* transmitter not ready */         return (END_ERR_BLOCK); /* just return without freeing mBlk chain */        }     pBuf = NET_BUF_ALLOC();    if (pBuf == NULL)        {	pDrvCtrl->lastError.errCode = END_ERR_NO_BUF;	muxError (&pDrvCtrl->end, &pDrvCtrl->lastError);        DRV_LOG (DRV_DEBUG_TX, "No available TxBufs \n", 1, 2, 3, 4, 5, 6);        END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_ERRS, +1);        END_TX_SEM_GIVE (&pDrvCtrl->end);         if (!pDrvCtrl->txCleaning && !pDrvCtrl->txBlocked)            sh7615EndTxRingClean (pDrvCtrl);         pDrvCtrl->txBlocked = TRUE;        /* transmitter not ready */        return (END_ERR_BLOCK); /* just return without freeing mBlk chain */        }    /*     * Store the buf info. Do this before adjusting alignment below      * so that the netBufFree will work correctly later.     */     pDrvCtrl->freeBuf[pDrvCtrl->txIndex].pClBuf = pBuf;     /* force 16 byte alignment of send buffer */    (UINT32) pBuf = NET_TO_SH7615END_BUF (pBuf);     /* Now copy data to 16 byte aligned location in pBuf and free Mblk */    len = netMblkToBufCopy (pMblk, pBuf, NULL);    len = max (ETHERSMALL, len);    netMblkClChainFree (pMblk);    /* flush the cache, if necessary */     SH7615END_CACHE_FLUSH (pBuf, len);    /* initialize the transmit descriptor -- preserve TD0_TDL bit */    pTxD->tDesc0  = ((pTxD->tDesc0 & TD0_TDL) | (TD0_OWN | TD0_TFP));    pTxD->tDesc1 = SH7615END_TBS_PUT(len);    pTxD->tDesc2 = (UINT32) pBuf;    pTxD->tDesc3 = 0;    /* Advance our management index */    pDrvCtrl->txIndex = (pDrvCtrl->txIndex + 1) % pDrvCtrl->numTds;    SH7615END_REG_WRITE(E_DMAC_EDTRR, EDTRR_TR);  /* Transmit request */    END_TX_SEM_GIVE (&pDrvCtrl->end);     /* update statistics */    END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);     return (OK);    }/********************************************************************************* sh7615EndPollStart - starting polling mode** This routine starts polling mode by disabling ethernet interrupts and* setting the polling flag in the END_CTRL stucture.** RETURNS: OK, always.*/ LOCAL STATUS sh7615EndPollStart    (    DRV_CTRL *  pDrvCtrl    )    {    int         intLevel;     DRV_LOG (DRV_DEBUG_POLL, "PollStart\n", 1, 2, 3, 4, 5, 6);     intLevel = intLock();     /* Disable system interrupts */    SYS_INT_DISABLE (pDrvCtrl);     /* mask interrupts */    SH7615END_BIT_CLR(E_DMAC_EESIPR, pDrvCtrl->intrMask);     DRV_FLAGS_SET (SH7615END_POLLING);     intUnlock (intLevel);     return (OK);    }/********************************************************************************* sh7615EndPollStop - stop polling mode** This function terminates polled mode operation.  The device returns to* interrupt mode.** The device interrupts are enabled, the current mode flag is switched* to indicate interrupt mode and the device is then reconfigured for* interrupt operation.** RETURNS: OK, always.*/ LOCAL STATUS sh7615EndPollStop    (    DRV_CTRL *  pDrvCtrl    )    {    int intLevel;    DRV_LOG (DRV_DEBUG_POLL, "PollStop\n", 1, 2, 3, 4, 5, 6);    intLevel = intLock();     DRV_FLAGS_CLR (SH7615END_POLLING);    /* Enable chip interrupts */    SH7615END_REG_WRITE(E_DMAC_EESIPR, pDrvCtrl->intrMask);     /* Enable system interrupts */    SYS_INT_ENABLE (pDrvCtrl);    intUnlock (intLevel);     DRV_LOG (DRV_DEBUG_POLL, "s\n", 1, 2, 3, 4, 5, 6);     return (OK);    }/********************************************************************************* sh7615EndPollSend - send a packet in polled mode** This routine is called by a user to try and send a packet on the* device.** RETURNS: OK on success, EAGAIN on failure*/ LOCAL STATUS sh7615EndPollSend    (    DRV_CTRL *	pDrvCtrl,    M_BLK *	pMblk    )    {    SH7615_TD *	pTxD;    char *	pBuf;    char *	pBufAligned;    int		len;     DRV_LOG (DRV_DEBUG_POLL, "PollSend\n", 1, 2, 3, 4, 5, 6);    pTxD = sh7615EndTxDGet (pDrvCtrl);    pBuf = NET_BUF_ALLOC ();     if ((pTxD == NULL) || (pBuf == NULL))        {	pDrvCtrl->lastError.errCode = END_ERR_NO_BUF;	muxError (&pDrvCtrl->end, &pDrvCtrl->lastError);        sh7615EndTxRingClean (pDrvCtrl);        if (pBuf)  NET_BUF_FREE (pBuf);        return (EAGAIN);        }    /* force 16 byte alignment of send buffer */     (UINT32) pBufAligned = NET_TO_SH7615END_BUF (pBuf);     /* copy the MBLK */    len = netMblkToBufCopy (pMblk, pBufAligned, NULL);    len = max (ETHERSMALL, len);    /* flush the cache, if necessary */     SH7615END_CACHE_FLUSH (pBufAligned, len);     pTxD->tDesc0 = ((pTxD->tDesc0 & TD0_TDL) | (TD0_OWN | TD0_TFP));    pTxD->tDesc1 = SH7615END_TBS_PUT(len);    pTxD->tDesc2 = (UINT32) pBufAligned;    pTxD->tDesc3 = 0;     /* Advance our management index */    pDrvCtrl->txIndex = (pDrvCtrl->txIndex + 1) % pDrvCtrl->numTds;     /* Transmit request */    SH7615END_REG_WRITE(E_DMAC_EDTRR, EDTRR_TR);      /* The buffer does not belong to us; Spin until it can be freed */    while (pTxD->tDesc0 & TD0_OWN)        ;    NET_BUF_FREE (pBuf);     /* Try again on transmit errors */    if (pTxD->tDesc0 & TD0_TFE)        return (EAGAIN);    return (EAGAIN);    }/********************************************************************************* sh7615EndPollReceive - get a packet in polled mode** This routine is called by a user to try and get a packet from the* device.** RETURNS: OK on success, EAGAIN on failure.*/ LOCAL STATUS sh7615EndPollReceive    (    DRV_CTRL    *pDrvCtrl,    M_BLK       *pMblk    )    {    SH7615_RD 	*pRxD;    char        *pRxBuf;    int         len;    BOOL        gotOne=FALSE;     DRV_LOG (DRV_DEBUG_POLL, "PollReceive\n", 1, 2, 3, 4, 5, 6);    if ((pMblk->mBlkHdr.mFlags & M_EXT) != M_EXT)        return (EAGAIN);    while (((pRxD = sh7615EndRxDGet (pDrvCtrl)) != NULL) && !gotOne)        {        /* Check if the packet was received OK */        if ((pRxD->rDesc0 & RD0_RFE) &&	   !((pRxD->rDesc0 & RD0_RFS7) && (DRV_FLAGS_GET() & SH7615END_MCAST)))            {            /* Update the error statistics and discard the packet */            END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);            }        else            {            len = SH7615END_FRAME_LEN_GET (pRxD->rDesc1);            if ((len <= pMblk->mBlkHdr.mLen) && (len >= ETHERSMALL))                {                gotOne = TRUE;                END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);                 pMblk->mBlkHdr.mFlags |= M_PKTHDR; /* set the packet header */                pMblk->mBlkHdr.mLen = len;         /* set the data len */                pMblk->mBlkPktHdr.len = len;       /* set the total len */ 		/* cache invalidate to prepare for the copy */                pRxBuf = (char *) pRxD->rDesc2;                SH7615END_CACHE_INVALIDATE (pRxBuf, len);                /* bump the buffer mData by 2 to ensure alignment */

⌨️ 快捷键说明

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