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

📄 ln97xend.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    )    {    LN_RMD * 		pRmd = (LN_RMD *)NULL;    do        {        pDrvCtrl->flags |= LS_RCV_HANDLING_FLAG;        while ((pRmd = ln97xFullRMDGet (pDrvCtrl)) != (LN_RMD *)NULL) 	    {            ln97xRecv (pDrvCtrl, pRmd);	    }        /*         * There is a RACE right here.  The ISR could add a receive packet         * and check the boolean below, and decide to exit.  Thus the         * packet could be dropped if we don't double check before we         * return.         */        pDrvCtrl->flags &= ~LS_RCV_HANDLING_FLAG;	}    while (ln97xFullRMDGet (pDrvCtrl) != NULL);    /* this double check solves the RACE */    }/********************************************************************************* ln97xFullRMDGet - get next received message RMD** Returns ptr to next Rx desc to process, or NULL if none ready.*/LOCAL LN_RMD * ln97xFullRMDGet    (    LN_97X_DRV_CTRL * 	pDrvCtrl /* device to be initialized */    )    {    LN_RMD *		pRmd;    pRmd = pDrvCtrl->pRring + pDrvCtrl->rmdIndex;  /* form ptr to Rx desc */    LN_CACHE_INVALIDATE (pRmd, RMD_SIZ);    /* If receive buffer has been released to us, return it */    if (LN_RMD_OWNED (pRmd) == 0)        return (pRmd);    else        return ((LN_RMD *) NULL);    }/********************************************************************************* ln97xRecv - process the next incoming packet** RETURNS: OK/ERROR*/LOCAL STATUS ln97xRecv    (    LN_97X_DRV_CTRL * 	pDrvCtrl, /* device to be initialized */    LN_RMD *		pRmd    )    {    int         	len;    M_BLK_ID    	pMblk;    char *       	pCluster;    char *       	pNewCluster;    char *       	pTemp;    CL_BLK_ID   	pClBlk;    UINT32		rmd1Tmp;    /* Packet must be checked for errors, Read rmd1 once only */    rmd1Tmp = PCI_SWAP (pRmd->rBufRmd1);    DRV_LOG (DRV_DEBUG_TX, "Recv : rmd1 = %X index = %d\n", rmd1Tmp,             pDrvCtrl->rmdIndex, 3, 4, 5, 6);    /* If error flag OR if packet is not completely in one buffer */    if  ((rmd1Tmp & RMD1_ERR) ||          (rmd1Tmp & (RMD1_STP | RMD1_ENP)) != (RMD1_STP | RMD1_ENP))	{        DRV_LOG (DRV_DEBUG_RX, "RMD error!\n", 1, 2, 3, 4, 5, 6);        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        goto cleanRXD;                          /* skip to clean up */	}    /* If we cannot get a buffer to loan then bail out. */    pNewCluster = netClusterGet (pDrvCtrl->endObj.pNetPool,                                 pDrvCtrl->pClPoolId);    if (pNewCluster == NULL)        {        DRV_LOG (DRV_DEBUG_RX, "Cannot loan!\n", 1, 2, 3, 4, 5, 6);        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        goto cleanRXD;        }    if ((pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) == NULL)        {        netClFree (pDrvCtrl->endObj.pNetPool, pNewCluster);        DRV_LOG (DRV_DEBUG_RX, "Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6);        END_ERR_ADD (&pDrvCtrl->endObj, 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->endObj.pNetPool, M_DONTWAIT, MT_DATA))        == NULL)        {        netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk);        netClFree (pDrvCtrl->endObj.pNetPool, pNewCluster);        DRV_LOG (DRV_DEBUG_RX, "Out of M Blocks!\n", 1, 2, 3, 4, 5, 6);        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        goto cleanRXD;        }    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);    len = LN_PKT_LEN_GET (pRmd);	/* get packet length */    LN_RMD_TO_ADDR (pRmd, pCluster);	/* Get pointer to packet */    pCluster -= pDrvCtrl->offset;        DRV_LOG (DRV_DEBUG_RX, "Packet @ 0x%X for %d bytes!\n", pCluster,             len, 3, 4, 5, 6);    /* Join the cluster to the MBlock */    netClBlkJoin (pClBlk, pCluster, len, NULL, 0, 0, 0);    netMblkClJoin (pMblk, pClBlk);    /* make the packet data coherent */    LN_CACHE_INVALIDATE (pMblk->mBlkHdr.mData, len);    pMblk->mBlkHdr.mData  += pDrvCtrl->offset;    pMblk->mBlkHdr.mLen   = len;    pMblk->mBlkHdr.mFlags |= M_PKTHDR;    pMblk->mBlkPktHdr.len = len;    DRV_LOG (DRV_DEBUG_RX, "Calling upper layer!\n", 1, 2, 3, 4, 5, 6);    /* Deal with memory alignment. */    pNewCluster += pDrvCtrl->offset;    /* Give receiver a new buffer */    LN_RMD_BUF_TO_ADDR (pRmd, pTemp, pNewCluster);    /* Call the upper layer's receive routine. */    END_RCV_RTN_CALL(&pDrvCtrl->endObj, pMblk);cleanRXD:    /* clear status bits */    LN_CLEAN_RXD (pRmd);    /* Flush the write pipe */    CACHE_PIPE_FLUSH ();    /* Advance our management index */    pDrvCtrl->rmdIndex = (pDrvCtrl->rmdIndex + 1) & (pDrvCtrl->rringSize - 1);    return (OK);    }/********************************************************************************* lnSend - the driver send routine** 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 or ERROR.*/LOCAL STATUS ln97xSend    (    LN_97X_DRV_CTRL * 	pDrvCtrl,  /* device to be initialized */    M_BLK_ID 		pMblk      /* data to send */    )    {    LN_TMD *		pTmd;    UINT32		ltmd1;    void *       	pTemp;    char *       	pBuf;    char *       	pOrig;    int         	len = 0;    /* check device mode */    if (pDrvCtrl->flags & LS_POLLING)        {        netMblkClChainFree (pMblk);        errno = EINVAL;        return (ERROR);        }    /*     * 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);    pTmd = pDrvCtrl->pTring + pDrvCtrl->tmdIndex;    LN_CACHE_INVALIDATE (pTmd, TMD_SIZ);    DRV_LOG (DRV_DEBUG_TX, "Send : index %d tmd = 0x%X\n",             pDrvCtrl->tmdIndex, (int)pTmd, 3, 4, 5, 6);    ltmd1 = PCI_SWAP (pTmd->tBufTmd1);        if ((ltmd1 & TMD1_OWN) ||	(((pDrvCtrl->tmdIndex + 1) & (pDrvCtrl->tringSize - 1))         == pDrvCtrl->tmdIndexC))        {        /* Are we still on the first chunk? */        DRV_LOG (DRV_DEBUG_TX, "Out of TMDs!\n", 1, 2, 3, 4, 5, 6);        pDrvCtrl->txBlocked = TRUE;        END_TX_SEM_GIVE (&pDrvCtrl->endObj);        return (END_ERR_BLOCK);        }    DRV_LOG (DRV_DEBUG_TX, "before cluster get %d %d\n",             pDrvCtrl->endObj.pNetPool,             pDrvCtrl->pClPoolId, 3, 4, 5, 6);    pOrig = pBuf = netClusterGet (pDrvCtrl->endObj.pNetPool,                                  pDrvCtrl->pClPoolId);    DRV_LOG (DRV_DEBUG_TX, "after cluster get pBuf = 0x%X\n",             (int)pBuf, 2, 3, 4, 5, 6);    if (pBuf == NULL)        {        pDrvCtrl->txBlocked = TRUE;        END_TX_SEM_GIVE (&pDrvCtrl->endObj);        return (END_ERR_BLOCK);        }    pBuf += pDrvCtrl->offset;	/* take care of the alignment */    len = netMblkToBufCopy (pMblk, pBuf, NULL);    netMblkClChainFree(pMblk);    LN_TMD_BUF_TO_ADDR(pTmd, pTemp, pBuf);    len = max (len, ETHERSMALL);    pTmd->tBufTmd2 = 0;         /* clear buffer error status */    ltmd1 = TMD1_STP | TMD1_ENP | TMD1_CNST;    ltmd1 |= (TMD1_BCNT_MSK & -len);    ltmd1 |= TMD1_OWN;          /* set ownership bit in software */    DRV_LOG (DRV_DEBUG_TX, "TMD1 = 0x%X\n", ltmd1, 2, 3, 4, 5, 6);    /* Advance our management index */    pDrvCtrl->tmdIndex = (pDrvCtrl->tmdIndex + 1) & (pDrvCtrl->tringSize - 1);    /* write transmit descriptor (with OWN-bit set) to actual register */    pTmd->tBufTmd1 = PCI_SWAP (ltmd1);    /* Flush the write pipe */    CACHE_PIPE_FLUSH ();    if (lnKickStartTx)        {        ln97xCsrWrite (pDrvCtrl, 0, (CSR0_INEA | CSR0_TDMD));        }    /* Bump the statistic counter. */    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1);    END_TX_SEM_GIVE (&pDrvCtrl->endObj);    return (OK);    }/********************************************************************************* ln97xIoctl - the driver I/O control routine** Process an ioctl request.** RETURNS OK or ERROR value*/LOCAL int ln97xIoctl    (    LN_97X_DRV_CTRL * 	pDrvCtrl, /* device to be initialized */    int 		cmd,	 /* ioctl command to execute */    caddr_t 		data	 /* date to get or set */    )    {    long 		value;    int 		error = 0;    switch (cmd)        {        case EIOCSADDR:	    if (data == NULL)		return (EINVAL);            bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->endObj),		   END_HADDR_LEN (&pDrvCtrl->endObj));            break;        case EIOCGADDR:	    if (data == NULL)		return (EINVAL);            bcopy ((char *)END_HADDR (&pDrvCtrl->endObj), (char *)data,		    END_HADDR_LEN (&pDrvCtrl->endObj));            break;        case EIOCSFLAGS:	    value = (long)data;            	    if (value < 0)		{		value = -value;		value--;		/* HELP: WHY ??? */		END_FLAGS_CLR (&pDrvCtrl->endObj, value);		}	    else		{		END_FLAGS_SET (&pDrvCtrl->endObj, value);		}	    ln97xConfig (pDrvCtrl);            break;        case EIOCGFLAGS:	    *(int *)data = END_FLAGS_GET (&pDrvCtrl->endObj);            break;        case EIOCMULTIADD:            error = ln97xMCastAddrAdd (pDrvCtrl, (char *) data);            break;        case EIOCMULTIDEL:            error = ln97xMCastAddrDel (pDrvCtrl, (char *) data);            break;        case EIOCMULTIGET:            error = ln97xMCastAddrGet (pDrvCtrl, (MULTI_TABLE *) data);            break;	case EIOCPOLLSTART:	    error = ln97xPollStart (pDrvCtrl);	    break;	case EIOCPOLLSTOP:	    error = ln97xPollStop (pDrvCtrl);	    break;        case EIOCGMIB2:            if (data == NULL)                return (EINVAL);            bcopy((char *)&pDrvCtrl->endObj.mib2Tbl, (char *)data,                  sizeof(pDrvCtrl->endObj.mib2Tbl));            break;        case EIOCGFBUF:            if (data == NULL)                return (EINVAL);            *(int *)data = LN_MIN_FBUF;            break;        case EIOCGMWIDTH:            if (data == NULL)                return (EINVAL);            *(int *)data = pDrvCtrl->memWidth;            break;        case EIOCGHDRLEN:            if (data == NULL)                return (EINVAL);            *(int *)data = 14;            break;        default:            error = EINVAL;        }    return (error);    }/********************************************************************************* ln97xReset - hardware reset of chip (stop it)** This routine is responsible for resetting the device and switching into* 32 bit mode.** RETURNS: OK/ERROR*/LOCAL int ln97xReset    (    LN_97X_DRV_CTRL * 	pDrvCtrl /* device to be initialized */    )    {    UINT32 		resetTmp;    /* Enable 32 bit access by doing a 32 bit write */    SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRdp, 0);    ln97xCsrWrite (pDrvCtrl, CSR(0), CSR0_STOP);        /* Generate a soft-reset of the controller */    SYS_IN_LONG(pDrvCtrl, pDrvCtrl->pReset, resetTmp);    /* This isn't a real test - it just stops the compiler ignoring the read */

⌨️ 快捷键说明

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