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

📄 dec21x40end.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* get a free transmit descriptor */    pTxD = dec21x40TxDGet (pDrvCtrl);    if (pTxD == NULL)        {        END_TX_SEM_GIVE (&pDrvCtrl->endObj);        return (ERROR);        }    /* get a buffer */     pBuf = NET_BUF_ALLOC();     if (pBuf == NULL)         {         DRV_LOG (DRV_DEBUG_LOAD, "netClusterGet failed\n", 1, 2, 3, 4, 5, 6);         END_TX_SEM_GIVE (&pDrvCtrl->endObj);         return (ERROR);         }     /* align the frame */     pFltrFrm = (UINT8 *) (((int)pBuf + 0x3) & ~0x3);     /* clear all entries */     bzero (pFltrFrm, FLTR_FRM_SIZE);     /* install multicast addresses */     for (pMCastNode = END_MULTI_LST_FIRST (&pDrvCtrl->endObj);          pMCastNode != NULL;          pMCastNode = END_MULTI_LST_NEXT (pMCastNode))         {         index = dec21x40HashIndex (pMCastNode->addr);         pFltrFrm [DEC_FLT_INDEX(index/8)] |= 1 << (index % 8);         }     /* install an ethernet broadcast address */     index = dec21x40HashIndex (ethBcastAdrs);     pFltrFrm [DEC_FLT_INDEX(index/8)] |= 1 << (index % 8);     /* install the physical address */     pAdrs = (UINT8 *)END_HADDR (&pDrvCtrl->endObj);     for (index=0; index<6; index++)         pFltrFrm [FLTR_FRM_PHY_ADRS_OFF + DEC_FLT_INDEX(index)] = pAdrs[index];     /* transmit the frame */     pTxD->tDesc2  = PCISWAP (DEC_VIRT_TO_PCI (pFltrFrm));     pTxD->tDesc3  = 0;     /* frame type is SETUP, filtering mode is HASH + 1 perfect */     pTxD->tDesc1 |= PCISWAP (TDESC1_SET | TDESC1_FT0);      pTxD->tDesc1 &= PCISWAP (~TDESC1_TBS1_MSK);     pTxD->tDesc1 |= PCISWAP (TDESC1_TBS1_PUT(FLTR_FRM_SIZE));     pTxD->tDesc1 &= PCISWAP (~(TDESC1_LS|TDESC1_FS));     pTxD->tDesc0  = PCISWAP(TDESC0_OWN);      /* ready for transmit */     CACHE_PIPE_FLUSH();     /* Advance our management index */     pDrvCtrl->txIndex = (pDrvCtrl->txIndex + 1) % pDrvCtrl->numTds;     /* mask interrupts */     csr7Val = DEC_CSR_READ (CSR7);     DEC_CSR_WRITE (CSR7, 0);     /* start tx */     if (DRV_FLAGS_ISSET(DEC_TX_KICKSTART))         DEC_CSR_WRITE (CSR1, CSR1_TPD);     /* wait for completion */     timeout=0xffffff;     while (timeout && (pTxD->tDesc0 != (~PCISWAP (TDESC0_OWN))))         timeout--;     /* restore TXD bits */     pTxD->tDesc0  = 0;     pTxD->tDesc1 &= PCISWAP (~(TDESC1_SET | TDESC1_FT0));     pTxD->tDesc1 |= PCISWAP (TDESC1_LS | TDESC1_FS);     pTxD->tDesc2  = 0;     CACHE_PIPE_FLUSH();     /* restore interrupts */     DEC_CSR_WRITE (CSR7, csr7Val);     /* free the buffer */     NET_BUF_FREE (pBuf);    /* release exclusive access */    END_TX_SEM_GIVE (&pDrvCtrl->endObj);    /* return success */    return (OK);    }/********************************************************************************* dec21x40MCastAddrAdd - add a multicast address*** RETURNS: OK on success, ERROR otherwise.*/LOCAL STATUS dec21x40MCastAddrAdd    (    DRV_CTRL *	pDrvCtrl,    char *	pAddr    )    {    int retVal;    DRV_LOG (DRV_DEBUG_IOCTL, "MCastAddrAdd\n", 0, 0, 0, 0, 0, 0);    retVal = etherMultiAdd (&pDrvCtrl->endObj.multiList, pAddr);    if (retVal == ENETRESET)        return dec21x40IASetup (pDrvCtrl);    return ((retVal == OK) ? OK : ERROR);    }/********************************************************************************* dec21x40MCastAddrDel - remove a multicast address*** RETURNS: OK on success, ERROR otherwise.*/LOCAL STATUS dec21x40MCastAddrDel    (    DRV_CTRL *	pDrvCtrl,    char *	pAddr    )    {    int retVal;    DRV_LOG (DRV_DEBUG_IOCTL, "MCastAddrDel\n", 0, 0, 0, 0, 0, 0);    retVal = etherMultiDel (&pDrvCtrl->endObj.multiList, pAddr);    if (retVal == ENETRESET)        return dec21x40IASetup (pDrvCtrl);    return ((retVal == OK) ? OK : ERROR);    }/********************************************************************************* dec21x40MCastAddrGet - retreive current multicast address list*** RETURNS: OK on success; otherwise ERROR.*/LOCAL STATUS dec21x40MCastAddrGet    (    DRV_CTRL *	pDrvCtrl,    MULTI_TABLE *pTable    )    {    DRV_LOG (DRV_DEBUG_IOCTL, "MCastAddrGet\n", 0, 0, 0, 0, 0, 0);    return (etherMultiGet (&pDrvCtrl->endObj.multiList, pTable));    }/********************************************************************************* dec21x40Send - transmit an ethernet packet** RETURNS: OK on success; and ERROR otherwise.*/LOCAL STATUS dec21x40Send    (    DRV_CTRL	*pDrvCtrl,    M_BLK	*pMblk    )    {    DEC_TD *	pTxD;    char *	pBuf;    int		len;    int         s;    DRV_PRINT (DRV_DEBUG_TX, ("S:0x%x ", pDrvCtrl->txIndex));#if 0        if (pDrvCtrl->txBlocked)        return (END_ERR_BLOCK); /* transmitter not ready */#endif        /* Gain exclusive access to transmit */    END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER);    /* Get the next TXD */    pTxD = dec21x40TxDGet (pDrvCtrl);    pBuf = NET_BUF_ALLOC();    if ((pTxD == NULL) || (pBuf == NULL))        {	DRV_LOG (DRV_DEBUG_TX, "No available TxBufs \n", 0, 0, 0, 0, 0, 0);        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, +1);        END_TX_SEM_GIVE (&pDrvCtrl->endObj);        if (pBuf)            NET_BUF_FREE (pBuf);        if (!pDrvCtrl->txCleaning && !pDrvCtrl->txBlocked)            dec21x40TxRingClean (pDrvCtrl);                s = intLock();        pDrvCtrl->txBlocked = TRUE;        /* transmitter not ready */        intUnlock(s);        return (END_ERR_BLOCK); /* just return without freeing mBlk chain */        }    /* copy and free the MBLK */    len = netMblkToBufCopy (pMblk, pBuf, NULL);    NET_MBLK_CHAIN_FREE (pMblk);    /* setup the transmit buffer pointers */    pTxD->tDesc2 = PCISWAP (DEC_VIRT_TO_PCI (pBuf));    pTxD->tDesc3 = 0;    /* setup frame len */    pTxD->tDesc1 &= PCISWAP (~TDESC1_TBS1_MSK);    pTxD->tDesc1 |= PCISWAP (TDESC1_TBS1_PUT(len));    /* transfer ownership to device */    pTxD->tDesc0  = PCISWAP(TDESC0_OWN);          CACHE_PIPE_FLUSH();    /* Save the buf info */    pDrvCtrl->freeBuf[pDrvCtrl->txIndex].pClBuf    = pBuf;    /* Advance our management index */    pDrvCtrl->txIndex = (pDrvCtrl->txIndex + 1) % pDrvCtrl->numTds;    if (DRV_FLAGS_ISSET(DEC_TX_KICKSTART))        DEC_CSR_WRITE (CSR1, CSR1_TPD);    END_TX_SEM_GIVE (&pDrvCtrl->endObj);    /* update statistics */    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1);    return (OK);    }/********************************************************************************* dec21x40Recv - pass a received frame to the upper layer*** RETURNS: OK, always.*/LOCAL STATUS dec21x40Recv    (    DRV_CTRL *	pDrvCtrl,    DEC_RD *	pRxD    )    {    END_OBJ *	pEndObj = &pDrvCtrl->endObj;    M_BLK_ID	pMblk;      /* MBLK to send upstream */    CL_BLK_ID	pClBlk;	    /* pointer to clBlk */    char *	pBuf; 	    /* A replacement buffer for the current RxD */    char *	pData;      /* Data pointer for the current RxD */    int     	len;	    /* Len of the current data */    DRV_PRINT (DRV_DEBUG_RX, ("R"));        /* check for errors */    if (pRxD->rDesc0 & PCISWAP(RDESC0_ES))        {        DRV_PRINT (DRV_DEBUG_RX, ("- "));        END_ERR_ADD (pEndObj, MIB2_IN_ERRS, +1);        goto cleanRxD;        }    DRV_PRINT (DRV_DEBUG_RX, ("+ "));    END_ERR_ADD (pEndObj, MIB2_IN_UCAST, +1);    /* Allocate an MBLK, and a replacement buffer */    pMblk = NET_MBLK_ALLOC();    pBuf  = NET_BUF_ALLOC();    pClBlk = NET_CL_BLK_ALLOC();     if ((pMblk == NULL) || (pBuf == NULL) || (pClBlk == NULL))        {	DRV_LOG (DRV_DEBUG_RX, "No available RxBufs \n", 0, 0, 0, 0, 0, 0);        END_ERR_ADD (pEndObj, MIB2_IN_ERRS, +1);        if (pMblk)            NET_MBLK_FREE (pMblk);        if (pBuf)            NET_BUF_FREE (pBuf);        if (pClBlk)            NET_CL_BLK_FREE (pClBlk);        goto cleanRxD;        }    /* Get the data pointer and len from the current RxD */    len   = DEC_FRAME_LEN_GET (PCISWAP (pRxD->rDesc0)) - ETH_CRC_LEN;     pData = (char *) DEC_PCI_TO_VIRT (PCISWAP (pRxD->rDesc2));    /* Associate the data pointer with the MBLK */    NET_CL_BLK_JOIN (pClBlk, pData, DEC_BUFSIZ);        /* Associate the data pointer with the MBLK */    NET_MBLK_CL_JOIN (pMblk, pClBlk);    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 */    /* Make cache consistent with memory */    DEC_CACHE_INVALIDATE (pData, len);    /* Install the new data buffer */    pRxD->rDesc2 = PCISWAP (DEC_VIRT_TO_PCI (pBuf));    /* mark the descriptor ready to receive */    pRxD->rDesc0 = PCISWAP (RDESC0_OWN);        /* advance management index */    pDrvCtrl->rxIndex = (pDrvCtrl->rxIndex + 1) % pDrvCtrl->numRds;    CACHE_PIPE_FLUSH();    /* send the frame to the upper layer, and possibly switch to system mode */    END_RCV_RTN_CALL (pEndObj, pMblk);    return (OK);cleanRxD:    /* mark the descriptor ready to receive */    pRxD->rDesc0 = PCISWAP (RDESC0_OWN);        CACHE_PIPE_FLUSH();    /* advance management index */    pDrvCtrl->rxIndex = (pDrvCtrl->rxIndex + 1) % pDrvCtrl->numRds;    return (OK);    }/********************************************************************************* dec21x40RxIntHandle - perform receive processing** RETURNS: N/A*/LOCAL void dec21x40RxIntHandle    (    DRV_CTRL *	pDrvCtrl    )    {    DEC_RD	*pRxD;    pDrvCtrl->rxHandling = TRUE;        while ((pRxD = dec21x40RxDGet (pDrvCtrl)))            dec21x40Recv (pDrvCtrl, pRxD);    DEC_CSR_UPDATE (CSR7, CSR7_RIM);     /* turn on Rx interrupts */    pDrvCtrl->rxHandling = FALSE;    }/********************************************************************************* dec21x40RxDGet - get a ready receive descriptor** RETURNS: a filled receive descriptor, otherwise NULL.*/LOCAL DEC_RD * dec21x40RxDGet    (    DRV_CTRL	*pDrvCtrl    )    {    DEC_RD	*pRxD = pDrvCtrl->rxRing + pDrvCtrl->rxIndex;        DEC_CACHE_INVALIDATE (pRxD, RD_SIZ);    /* check if the descriptor is owned by the chip */    if (pRxD->rDesc0 & PCISWAP (RDESC0_OWN))        return NULL;    return pRxD;    }/*******

⌨️ 快捷键说明

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