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

📄 dec21x4xend.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            msb = crc >> 31;            crc <<= 1;            if (msb ^ (eAddrByte & 0x1))                {                crc ^= DEC_CRC_POLY;                crc |= 0x1;                }            eAddrByte >>= 1;            }        }    /*     * return the upper 9 bits of the CRC in a decreasing order of     * significance.     * crc <31..23> as index <0..8>     */    index = 0;    for (bit=0; bit<9; bit++)        index |= ((crc >> (31-bit)) & 0x1) << bit;    return index;    }/********************************************************************************* dec21x4xIASetup - set up physical and multicast addresses** This routine sets up a filter frame to filter the physical addresses* and all the current multicast addresses.** While the first call to this routine during chip initialization requires* that the receiver be turned off, subsequent calls do not.* * RETURNS: OK on success, ERROR otherwise.*/LOCAL STATUS dec21x4xIASetup    (    DRV_CTRL *	pDrvCtrl 	/* pointer to device control structure */    )    {    UINT8	ethBcastAdrs[]={ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };    UINT8 *	pFltrFrm;    UINT8 *	pAdrs;    ETHER_MULTI	* pMCastNode;    DEC_TD *	pTxD;    ULONG	csr7Val;    char *	pBuf;    int		index;    int		timeout;    DRV_LOG (DRV_DEBUG_IOCTL, "IASetup\n", 0, 0, 0, 0, 0, 0);    /* gain exclusive access to transmitter */    END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER);        /* get a free transmit descriptor */    pTxD = dec21x4xTxDGet (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", 0, 0, 0, 0, 0, 0);         END_TX_SEM_GIVE (&pDrvCtrl->endObj);         return (ERROR);         }     /* align the frame */     pFltrFrm = (UINT8 *) (((int)pBuf + 0x3) & ~0x3);     /* clear all entries */     memset (pFltrFrm, 0, FLTR_FRM_SIZE);     /* install multicast addresses */     for (pMCastNode = END_MULTI_LST_FIRST (&pDrvCtrl->endObj);          pMCastNode != NULL;          pMCastNode = END_MULTI_LST_NEXT (pMCastNode))         {         index = dec21x4xHashIndex (pMCastNode->addr);         pFltrFrm [DEC_FLT_INDEX(index/8)] |= 1 << (index % 8);         }     /* install an ethernet broadcast address */     index = dec21x4xHashIndex (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 */    /* Flush the write pipe */     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;     /* 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);    }/********************************************************************************* dec21x4xMCastAddrAdd - add a multicast address** This routine adds a multicast address to whatever the driver* is already listening for.** RETURNS: OK on success, ERROR otherwise.*/LOCAL STATUS dec21x4xMCastAddrAdd    (    DRV_CTRL *	pDrvCtrl,    char *	pAddr    )    {    int	retVal;    DRV_LOG (DRV_DEBUG_IOCTL, "MCastAddrAdd\n", 0, 0, 0, 0, 0, 0);    /* add a multicast address to the list */    retVal = etherMultiAdd (&pDrvCtrl->endObj.multiList, pAddr);    /* reconfigure the device */    if (retVal == ENETRESET)        return dec21x4xIASetup (pDrvCtrl);    return ((retVal == OK) ? OK : ERROR);    }/********************************************************************************* dec21x4xMCastAddrDel - remove a multicast address** This routine deletes a multicast address from the current list of* multicast addresses.** RETURNS: OK on success and ERROR otherwise.*/LOCAL STATUS dec21x4xMCastAddrDel    (    DRV_CTRL *	pDrvCtrl,    char *	pAddr    )    {    int retVal;    DRV_LOG (DRV_DEBUG_IOCTL, "MCastAddrDel\n", 0, 0, 0, 0, 0, 0);    /* remove a multicast address from the list */    retVal = etherMultiDel (&pDrvCtrl->endObj.multiList, pAddr);    /* reconfigure the device */     if (retVal == ENETRESET)        return dec21x4xIASetup (pDrvCtrl);    return ((retVal == OK) ? OK : ERROR);    }/********************************************************************************* dec21x4xMCastAddrGet - retreive current multicast address list** This routine returns the current multicast address list in <pTable>** RETURNS: OK on success; otherwise ERROR.*/LOCAL STATUS dec21x4xMCastAddrGet    (    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));    }/********************************************************************************* dec21x4xSend - transmit 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. 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.** muxSend() calls this routine each time it wants to send a packet.* Errors are detected at interrupt level.** RETURNS: OK on success; and ERROR otherwise.*/LOCAL STATUS dec21x4xSend    (    DRV_CTRL *	pDrvCtrl,    M_BLK *	pMblk    )    {    DEC_TD *	pTxD;    char *	pBuf;    int		len;    int         s;    DRV_LOG (DRV_DEBUG_TX, "S:%#x ", pDrvCtrl->txIndex, 0, 0, 0, 0, 0);#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 = dec21x4xTxDGet (pDrvCtrl);    pBuf = NET_BUF_ALLOC();    if ((pTxD == NULL) || (pBuf == NULL))        {        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)            dec21x4xTxRingClean (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);    /* setup the transmit buffer pointers */    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);          /* Flush the write pipe */    CACHE_PIPE_FLUSH();    /* Save the buf info */    pDrvCtrl->freeBuf[pDrvCtrl->txIndex].pClBuf = pBuf;    /* Advance our management index */    pDrvCtrl->txIndex = (pDrvCtrl->txIndex + 1) % pDrvCtrl->numTds;     /* start tx */    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);    }/********************************************************************************* dec21x4xRecv - pass a received frame to the upper layer** This routine processes an input frame, then passes it up to the higher* level in a form it expects.  Buffer loaning, promiscuous mode are all* supported.  Trailer protocols is not supported.** RETURNS: OK, always.*/LOCAL STATUS dec21x4xRecv    (    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 */    char *	pTmp;    int     	len;	    /* Len of the current data */    DRV_LOG (DRV_DEBUG_RX, "R", 0, 0, 0, 0, 0, 0);         /* check for errors */    if (pRxD->rDesc0 & PCISWAP(RDESC0_ES))        {        DRV_LOG (DRV_DEBUG_RX, "- ",0, 0, 0, 0, 0, 0);        END_ERR_ADD (pEndObj, MIB2_IN_ERRS, +1);        goto cleanRxD;        }    /* 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))        {        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));    /*     * The code above solves alignment problem when the CPU and the     * ethernet chip don't accept longword unaligned addresses.     *      * Pb: When the ethernet chip receives a packet from the network,     * it needs a l

⌨️ 快捷键说明

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