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

📄 bcm1250macend.c

📁 操作系统vxworks平台下end设备的驱动程序,支持多种芯片,支持多种cpu
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* disable mac hw */    ETH_MAC_REG_WRITE (pDrvCtrl->regMacEnable, 0);    /* diasble VxW interrupt */    (void)bcm1250IntDisable (pDrvCtrl->intSource);    /* disconnect interrupt handler */    (void)bcm1250IntDisconnect (pDrvCtrl->intSource);    DRV_LOG (DRV_DEBUG_LOAD, "bcm1250MacStop done.\n", 1, 2, 3, 4, 5, 6);    return (OK);    }/********************************************************************************* bcm1250MacSend - send an Ethernet packet** This routine() takes a M_BLK_ID and 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.** muxSend() calls this routine each time it wants to send a packet.** RETURNS: OK, or END_ERR_BLOCK, if no resources are available, or ERROR, if* the device is currently working in polling mode, or is passed a bad M_BLK* pointer.*/LOCAL STATUS bcm1250MacSend    (    DRV_CTRL *  pDrvCtrl,       /* driver control structure */    M_BLK *     pMblk           /* pointer to the mBlk/cluster pair */    )    {    STATUS  rtv = OK;       /* function return value */    int     fragNum = 0;    /* number of fragments in this mBlk */    BOOL    zeroCopyReady;  /* able to transmit without buffer copy */    DRV_LOG (DRV_DEBUG_TX, "bcm1250MacSend...\n", 1, 2, 3, 4, 5, 6);    /*     * Obtain exclusive access to transmitter.  This is necessary because     * we might have more than one stack transmitting at once.     */    END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER);    /* check device mode */    if (DRV_FLAGS_ISSET (BCM1250_MAC_POLLING))        {        netMblkClChainFree (pMblk);        rtv = ERROR;        errno = EINVAL;        goto bcm1250MacSendError;        }    /* check for valid M_BLK */    if (pMblk == (M_BLK *)NULL)        {        DRV_LOG (DRV_DEBUG_TX, "Invalid pMblk\n", 1, 2, 3, 4, 5, 6);        rtv = ERROR;        errno = EINVAL;        goto bcm1250MacSendError;        }    /* walk the mBlk */    bcm1250MacMblkWalk (pMblk, &fragNum, &zeroCopyReady);    /* check we have enough resources */    if (zeroCopyReady &&        ((pDrvCtrl->txDma.maxDescr - pDrvCtrl->txDma.ringCount) >= fragNum))        {        DRV_LOG (DRV_DEBUG_TX, "bcm1250MacSend fragNum = %d\n", fragNum,                 2, 3, 4, 5, 6);        /* transmit the packet in zero-copy mode */        rtv = bcm1250MacPktTransmit (pDrvCtrl, pMblk, fragNum);        }    else        {        /* transmit the packet in copy mode */        rtv = bcm1250MacPktCopyTransmit (pDrvCtrl, pMblk);        }bcm1250MacSendError:    END_TX_SEM_GIVE (&pDrvCtrl->endObj);    DRV_LOG (DRV_DEBUG_TX, "bcm1250MacSend...Done\n", 1, 2, 3, 4, 5, 6);    return (rtv);    }/********************************************************************************* bcm1250MacPktCopyTransmit - copy and transmit a packet** This routine transmits the packet described by the given parameters* over the network, after copying the mBlk to the driver's buffer.* It also updates statistics.** RETURNS: OK, or ERROR if no resources were available.*/LOCAL STATUS bcm1250MacPktCopyTransmit    (    DRV_CTRL *  pDrvCtrl,   /* driver control structure */    M_BLK *     pMblk       /* pointer to the mBlk */    )    {    int             len = 0;                /* length of data to be sent */    char *          pBuf = (char *)NULL;    /* pointer to data to be sent */    ETH_DMA_DSCR *  pTxDscr;                /* DMA buffer descriptor */    ETH_MAC_DMA *   pTxDma;                 /* ethernet DMA structure */    UINT64          dscrCnt;                /* buffer descriptor count */    DRV_LOG (DRV_DEBUG_TX, "bcm1250Mac CopyTx ...\n", 1, 2, 3, 4, 5, 6);    pTxDma = &pDrvCtrl->txDma;    /* get a cluster buffer from the pool */    pBuf = NET_BUF_ALLOC ();    if (pBuf == (char *)NULL)        {        /* set to stall condition */        pDrvCtrl->txDma.txBlocked = TRUE;        return (END_ERR_BLOCK);        }    /* Check for all DMA buffer descriptors in use. */    if (pTxDma->ringCount >= pTxDma->maxDescr)        {        DRV_LOG (DRV_DEBUG_TX, "No available TxBufs\n", 1, 2, 3, 4, 5, 6);        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, 1);        NET_BUF_FREE (pBuf);        pDrvCtrl->txDma.txBlocked = TRUE;        return (END_ERR_BLOCK); /* just return without freeing mBlk chain */        }    len = netMblkToBufCopy (pMblk, (char *)pBuf, (FUNCPTR)NULL);    netMblkClChainFree (pMblk);    len = max (ETHERSMALL, len);    DRV_LOG (DRV_DEBUG_TXD,             "tx - *pBuf= 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",             pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5]);    DRV_LOG (DRV_DEBUG_TXD,             "tx - *pBuf= 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",             pBuf[6], pBuf[7], pBuf[8], pBuf[9], pBuf[10], pBuf[11]);    DRV_LOG (DRV_DEBUG_TXD,             "tx - *pBuf= 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",             pBuf[12], pBuf[13], pBuf[14], pBuf[15], pBuf[16], pBuf[17]);    /* point to next buffer descriptor */    pTxDscr = &pTxDma->pDscrTable[pTxDma->tailIndex];    DRV_LOG (DRV_DEBUG_TXD, "pTxd->desc_a = 0x%08x\n",             (UINT32)&pTxDscr->dscr_a, 2, 3, 4, 5, 6);    DRV_LOG (DRV_DEBUG_TXD, "pTxd->desc_b = 0x%08x\n",             (UINT32)&pTxDscr->dscr_b, 2, 3, 4, 5, 6);    /* set buffer ptr, size in cache line, enable intr, mark as 1st pkt */    pTxDscr->dscr_a = (UINT64)((UINT32)KVTOPHYS (pBuf)) |                      V_DMA_DSCRA_A_SIZE (NUMCACHEBLKS (len)) |                      M_DMA_DSCRA_INTERRUPT |                      M_DMA_ETHTX_SOP;    /* set pkt len and  option */    pTxDscr->dscr_b = V_DMA_DSCRB_OPTIONS (K_DMA_ETHTX_APPENDCRC_APPENDPAD) |                      V_DMA_DSCRB_PKT_SIZE (len);    DRV_LOG (DRV_DEBUG_TXD, "dscr_a = 0x%08x%08x\n", (pTxDscr->dscr_a) >> 32,             pTxDscr->dscr_a, 3, 4, 5, 6);    DRV_LOG (DRV_DEBUG_TXD, "dscr_b = 0x%08x%08x\n", (pTxDscr->dscr_b) >> 32,             pTxDscr->dscr_b, 3, 4, 5, 6);    /* save pointer to buffer and the buffer type. */    pTxDma->bufTable[pTxDma->tailIndex].pBuf = pBuf;    pTxDma->bufTable[pTxDma->tailIndex].type = BUF_TYPE_CL;    /* advance ring management variables */    pTxDma->tailIndex = (pTxDma->tailIndex + 1) % pTxDma->maxDescr;    pTxDma->ringCount++;    /* tell hw one more dscr to go */    ETH_DMA_REG_WRITE (pTxDma->regDscrCnt, 1);    /* debug purpose */    dscrCnt = ETH_DMA_REG_READ (pTxDma->regDscrCnt);    DRV_LOG (DRV_DEBUG_TX, "tx0 DMA dscrcnt=0x%08x%08x\n", (dscrCnt >> 32),              dscrCnt, 3, 4, 5, 6);    DRV_LOG (DRV_DEBUG_TX, "bcm1250Mac CopyTx Done.\n", 1, 2, 3, 4, 5, 6);    return (OK);    }/********************************************************************************* bcm1250MacMblkWalk - walk the mBlk** This routine walks the mBlk whose address is in <pMblk>, computes* the number of fragments it is made of, and returns it in the parameter* <pFragNum>. In addition, it finds out whether the specified packet* is unicast or multicast.** RETURNS: OK, or ERROR in case of invalid mBlk.*/LOCAL void bcm1250MacMblkWalk    (    M_BLK * pMblk,          /* pointer to the mBlk */    int *   pFragNum,       /* number of fragments in this mBlk */    BOOL *  pZeroCopyReady  /* no buffer copy flag */    )    {    M_BLK * pCurr = pMblk;  /* the current mBlk */    DRV_LOG (DRV_DEBUG_TX, "bcm1250MacMblkWalk: start\n", 1, 2, 3, 4, 5, 6);    *pZeroCopyReady = TRUE; /* assume no buffer copy is required */    /* walk this mBlk */    do        {        /* if not first buffer in a packet, must start at cache line boundary */        if (pCurr != pMblk)            {            if (((UINT32)pCurr->mBlkHdr.mData & (CACHELINESIZE - 1)) != 0)                {                DRV_LOG (DRV_DEBUG_TX,                         "bcm1250MacMblkWalk: beginning align fail\n",                         1, 2, 3, 4, 5, 6);                *pZeroCopyReady = FALSE;    /* buffer copy required */                }            }        /* if not last buffer in a pacet, must end at cache line boundary */        if (pCurr->mBlkHdr.mNext != (M_BLK *)NULL)            {            if ((((UINT32)pCurr->mBlkHdr.mData + pCurr->mBlkHdr.mLen) &                 (CACHELINESIZE - 1)) != 0)                {                DRV_LOG (DRV_DEBUG_TX,                         "bcm1250MacMblkWalk: ending align fail\n",                         1, 2, 3, 4, 5, 6);                *pZeroCopyReady = FALSE;    /* buffer copy required */                }            }        /* keep track of the number of fragments in this mBlk */        (*pFragNum)++;        pCurr = ((M_BLK *)pCurr->mBlkHdr.mNext);        DRV_LOG (DRV_DEBUG_TX, "bcm1250MacMblkWalk: next\n", 1, 2, 3, 4, 5, 6);        }    while (pCurr != (M_BLK *)NULL);    }/********************************************************************************* bcm1250MacPktTransmit - zero copy packet transmit** This routine transmits the packet described by the given parameters* over the network, zero mbuf copying** RETURNS: OK, or ERROR if no resources were available or condition* does not meet.*/LOCAL STATUS bcm1250MacPktTransmit    (    DRV_CTRL *  pDrvCtrl,   /* driver control structure */    M_BLK *     pMblk,      /* pointer to the mBlk */    int         fragNum     /* number of fragments in this mBlk */    )    {    int             len = 0;                /* length of data to be sent */    UINT32          offset;                 /* offset to cache line */    char *          pBuf = (char *)NULL;    /* pointer to data to be sent */    ETH_DMA_DSCR *  pTxDscr;                /* DMA buffer descriptor */    ETH_MAC_DMA *   pTxDma;                 /* ethernet DMA structure */    M_BLK *         pCurrentMblk;           /* current mBlk pointer */    DRV_LOG (DRV_DEBUG_TX, "bcm1250Mac Zero-Copy Tx ...\n", 1, 2, 3, 4, 5, 6);    pTxDma = &pDrvCtrl->txDma;    pCurrentMblk = pMblk;    while (pCurrentMblk != (M_BLK *)NULL)        {        /* point to next buffer descriptor */        pTxDscr = &pTxDma->pDscrTable[pTxDma->tailIndex];        pBuf = pCurrentMblk->mBlkHdr.mData;        len = pCurrentMblk->mBlkHdr.mLen;        offset = (UINT32)(pCurrentMblk->mBlkHdr.mData) & (CACHELINESIZE - 1);        /* set buffer ptr, size in cache line */        pTxDscr->dscr_a = (UINT64)((UINT32)KVTOPHYS (pBuf)) |                          V_DMA_DSCRA_A_SIZE (NUMCACHEBLKS (offset + len));        pTxDscr->dscr_b = V_DMA_DSCRB_OPTIONS (K_DMA_ETHTX_APPENDCRC_APPENDPAD);        if (pCurrentMblk == pMblk)            {            /* set pkt len and  option */            pTxDscr->dscr_a |= M_DMA_ETHTX_SOP;            pTxDscr->dscr_b |= V_DMA_DSCRB_PKT_SIZE(                                    pCurrentMblk->mBlkPktHdr.len);            }        DRV_LOG (DRV_DEBUG_TXD, "dscr_a = 0x%08x%08x\n",                 (pTxDscr->dscr_a) >> 32, pTxDscr->dscr_a, 3, 4, 5, 6);        DRV_LOG (DRV_DEBUG_TXD, "dscr_b = 0x%08x%08x\n",                 (pTxDscr->dscr_b) >> 32, pTxDscr->dscr_b, 3, 4, 5, 6);        /* Is this the last one? */        if (pCurrentMblk->mBlkHdr.mNext == (M_BLK *)NULL)            {            pTxDscr->dscr_a |= M_DMA_DSCRA_INTERRUPT;            /* save pointer to buffer and the buffer type. */            pTxDma->bufTable[pTxDma->tailIndex].pBuf = (char *)pMblk;            pTxDma->bufTable[pTxDma->tailIndex].type = BUF_TYPE_MBLK;            }        else            {            /*             * Save pointer to buffer and the buffer type for              * the last descriptor.             */            pTxDma->bufTable[pTxDma->tailIndex].pBuf = (char *)NULL;            pTxDma->bufTable[pTxDma->tailIndex].type = BUF_TYPE_NONE;            }        /* advance ring management variables */        pTxDma->tailIndex = (pTxDma->tailIndex + 1) %  pTxDma->maxDescr;        pTxDma->ringCount++;        pCurrentMblk = pCurrentMblk->mBlkHdr.mNext;        }    /* tell hw one more dscr to go */    ETH_DMA_REG_WRITE (pTxDma->regDscrCnt, fragNum);    DRV_LOG (DRV_DEBUG_TX, "bcm1250Mac Zero-Copy Tx Done.\n",             1, 2, 3, 4, 5, 6);    return (OK);    }/********************************************************************************* bcm1250MacInt - entry point for handling interrupts** The interrupting events are acknowledged to the device, so that the device* will de-assert its interrupt signal.  The amount of work done here is kept* to a minimum; the bulk of the work is deferred to the netTask.** RETURNS: N/A*/LOCAL void bcm1250MacInt    (    DRV_CTRL *  pDrvCtrl    /* driver control structure */    )    {    UINT64  status; /* Interrupt status */    /* Get the interrupt status register value. */

⌨️ 快捷键说明

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