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

📄 mbcend.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
* device.** RETURNS: OK upon success.  EAGAIN is returned when no packet is available.*/LOCAL STATUS mbcPollRcv    (    void * 	pObj,	/* device to be polled */    M_BLK_ID	pMblk	/* ptr to buffer */    )    {    int			len;    MBC_DEVICE *	pDrvCtrl = pObj;	/* device to be polled */    volatile MBC_BD *	pRxBd;    pRxBd = &pDrvCtrl->rxBdBase [pDrvCtrl->rxBdNext];    len = pRxBd->dataLength;    /* If no packet is available return immediately */    if (pRxBd->statusMode & MBC_RXBD_E)        return (EAGAIN);    /* Upper layer must provide a valid buffer. */    if ((pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT)))	{	DRV_LOG (DRV_DEBUG_POLL_RX, "%s%d: mbcPollRcv: rxBdNext=%d bad mblk\n",		 (int) DEV_NAME, pDrvCtrl->unit, pDrvCtrl->rxBdNext, 4, 5, 6);	return (EAGAIN);	}    /* Check packet and device for errors */    if (((pRxBd->statusMode & (MBC_RXBD_F | MBC_RXBD_L))	 != (MBC_RXBD_F | MBC_RXBD_L))	|| (pRxBd->statusMode & (MBC_RXBD_CL | MBC_RXBD_OV |				 MBC_RXBD_CR | MBC_RXBD_SH |				 MBC_RXBD_NO | MBC_RXBD_LG)))	{	/* packet has an error */	DRV_LOG (DRV_DEBUG_POLL_RX | DRV_DEBUG_ERROR,		 "%s%d: mbcPollRcv: rxBdNext=%d bad packet stat=%x\n",		 (int) DEV_NAME, pDrvCtrl->unit, pDrvCtrl->rxBdNext,		 pRxBd->statusMode, 5, 6);		pRxBd->statusMode |= MBC_RXBD_E;	pDrvCtrl->rxBdNext = (pDrvCtrl->rxBdNext + 1) % pDrvCtrl->rxBdNum;        return (EAGAIN);	}    END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);    pMblk->mBlkHdr.mData += pDrvCtrl->offset;    bcopy (pRxBd->dataPointer, pMblk->mBlkHdr.mData, len);    pMblk->mBlkHdr.mLen = len;    pMblk->mBlkHdr.mFlags |= M_PKTHDR;    pMblk->mBlkPktHdr.len = len;    /* Done with packet, clean up and give it to the device. */    pRxBd->statusMode |= MBC_RXBD_E;    pDrvCtrl->rxBdNext = (pDrvCtrl->rxBdNext + 1) % pDrvCtrl->rxBdNum;            DRV_LOG (DRV_DEBUG_POLL_RX,	     "%s%d: mbcPollRcv: rxBdNext=%d good packet len=%d\n",	     (int) DEV_NAME, pDrvCtrl->unit, pDrvCtrl->rxBdNext,	     len, 5, 6);    return (OK);    }/******************************************************************************** mbcPollSend - routine to send a packet in polled mode.** This routine is called by a user to try to send a packet on the* device.** RETURNS: OK upon success.  EAGAIN if device is busy.*/LOCAL STATUS mbcPollSend    (    void * 	pObj,	/* device to be polled */    M_BLK_ID    pMblk	/* packet to send */    )    {    char *		pBuf = NULL;    int			len;    int			oldLevel;    MBC_DEVICE *	pDrvCtrl = pObj;	/* device to be polled */    volatile MBC_BD *	pTxBd;        /* test to see if TX is busy */        pTxBd = &pDrvCtrl->txBdBase [pDrvCtrl->txBdNext];    if (pTxBd->statusMode & MBC_TXBD_R)	{	DRV_LOG (DRV_DEBUG_POLL_TX | DRV_DEBUG_ERROR,		 "%s%d: mbcPollSend: no Tx desc. txBdNext=%d\n",		 (int) DEV_NAME, pDrvCtrl->unit, pDrvCtrl->txBdNext, 4, 5, 6);	return (EAGAIN);	}    /* Check if descriptor is clean */    if (pTxBd->dataPointer)	{	DRV_LOG (DRV_DEBUG_POLL_TX | DRV_DEBUG_ERROR,		 "%s%d: mbcPollSend: needs cleaning\n",		 (int) DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6);	if (!pDrvCtrl->txCleaning == TRUE);	    netJobAdd ((FUNCPTR)mbcScrubTRing, (int) pDrvCtrl, 0, 0, 0, 0);	return (EAGAIN);	}    /*     * If packet is in a single block, we can transmit     * directly from the M_BLK, otherwise we have to copy.     */    #if 0	/* XXX */    if (pMblk->mBlkHdr.mNext == NULL)        {        len = max (ETHERSMALL, pMblk->m_len);	pTxBd->dataPointer = pMblk->m_data;        }    else#endif  /* 0 */        {        pBuf = netClusterGet (pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId);        if (pBuf == NULL)	    {	    DRV_LOG (DRV_DEBUG_POLL_TX | DRV_DEBUG_ERROR,		     "%s%d: mbcPollSend: no clusters\n",		     (int) DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6);            return (EAGAIN);	    }        len = netMblkToBufCopy (pMblk, pBuf, NULL);	pTxBd->dataPointer = pBuf;        }        DRV_LOG (DRV_DEBUG_POLL_TX, "%s%d: mbcPollSend: txBdNext=%d len=%d\n",	     (int) DEV_NAME, pDrvCtrl->unit, pDrvCtrl->txBdNext, len, 5, 6);    CACHE_PIPE_FLUSH ();    /* Bump the statistic counter. */    END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);      /* Start transmission */    oldLevel = intLock ();    pTxBd->dataLength = len;    pTxBd->statusMode &= ~(MBC_TXBD_ERRS|MBC_TXBD_RC);    pTxBd->statusMode |= MBC_TXBD_R;    intUnlock (oldLevel);    /* Advance our management index. */    pDrvCtrl->txBdNext = (pDrvCtrl->txBdNext + 1) % pDrvCtrl->txBdNum;    /* Spin until packet has been sent. */    while (pTxBd->statusMode & MBC_TXBD_R)	;    /* Manually clean descriptor. */    pTxBd->dataPointer = NULL;    pTxBd->statusMode &= ~MBC_TXBD_ERRS;    /* Free allocated cluster (if any), and clean tx ring (if needed) */    if (pBuf != NULL)        netClFree (pDrvCtrl->end.pNetPool, pBuf);    if (!pDrvCtrl->txCleaning)        {        pDrvCtrl->txCleaning = TRUE;        mbcScrubTRing (pDrvCtrl);        }        return (OK);    }/******************************************************************************** mbcMCastAdd - add a multicast address for the device** This routine adds a multicast address to whatever the driver* is already listening for.  It then resets the address filter.** RETURNS: OK or ERROR.*/LOCAL STATUS mbcMCastAdd    (    void *	pObj,		/* device pointer */    char *	pAddress	/* new address to add */    )    {    int error;    MBC_DEVICE * pDrvCtrl = pObj;	/* device pointer */    DRV_LOG (DRV_DEBUG_LOAD | DRV_DEBUG_MULTI,	     "mbcMCastAdd %02x:%02x:%02x:%02x:%02x:%02x\n",	     pAddress[0]&0xff, pAddress[1]&0xff, pAddress[2]&0xff,	     pAddress[3]&0xff, pAddress[4]&0xff, pAddress[5]&0xff);    error = etherMultiAdd (&pDrvCtrl->end.multiList, pAddress);    if (error == ENETRESET)	mbcConfig (pDrvCtrl);    return (OK);    }/******************************************************************************** mbcMCastDel - delete a multicast address for the device** This routine removes a multicast address from whatever the driver* is listening for.  It then resets the address filter.** RETURNS: OK or ERROR.*/LOCAL STATUS mbcMCastDel    (    void *	pObj,		/* device pointer */    char *	pAddress	/* address to be deleted */    )    {    int		 error;    MBC_DEVICE * pDrvCtrl = pObj;	/* device pointer */    DRV_LOG (DRV_DEBUG_LOAD | DRV_DEBUG_MULTI,	     "mbcMCastDel %02x:%02x:%02x:%02x:%02x:%02x\n",	     pAddress[0]&0xff, pAddress[1]&0xff, pAddress[2]&0xff,	     pAddress[3]&0xff, pAddress[4]&0xff, pAddress[5]&0xff);    error = etherMultiDel (&pDrvCtrl->end.multiList, pAddress);    if (error == ENETRESET)	mbcConfig (pDrvCtrl);    return (OK);    }/******************************************************************************** mbcMCastGet - get the multicast address list for the device** This routine gets the multicast list of whatever the driver* is already listening for.** RETURNS: OK or ERROR.*/LOCAL STATUS mbcMCastGet    (    void *		pObj,		/* device pointer */    MULTI_TABLE *	pTable		/* address table to be filled in */    )    {    MBC_DEVICE * pDrvCtrl = pObj;	/* device pointer */    return (etherMultiGet (&pDrvCtrl->end.multiList, pTable));    }/******************************************************************************** mbcStop - stop the device** This function calls BSP functions to disconnect interrupts and stop* the device from operating in interrupt mode.** RETURNS: OK or ERROR.*/LOCAL STATUS mbcStop    (    void *	pObj	/* device to be stopped */    )    {    MBC_DEVICE *	pDrvCtrl = pObj;	/* device to be stopped */    STATUS		result = OK;    /* stop/disable the device. */        mbcReset (pDrvCtrl);        SYS_INT_DISCONNECT (pDrvCtrl, mbcInt, (int)pDrvCtrl, &result);#ifdef DRV_DEBUG    if (result == ERROR)	{	DRV_LOG (DRV_DEBUG_LOAD | DRV_DEBUG_ERROR,		 "Could not disconnect interrupt!\n",		 1, 2, 3, 4, 5, 6);	}#endif	/* DRV_DEBUG */    return (result);    }/******************************************************************************** mbcUnload - unload a driver from the system** This function first brings down the device, and then frees any* stuff that was allocated by the driver in the load function.** RETURNS: OK.*/LOCAL STATUS mbcUnload    (    void *	pObj	/* device to be unloaded */    )    {    MBC_DEVICE * pDrvCtrl = pObj;	/* device to be unloaded */    END_OBJECT_UNLOAD (&pDrvCtrl->end);        /* Free the shared DMA memory. */    if (pDrvCtrl->flags & MBC_MEM_ALLOC_FLAG)	cacheDmaFree (pDrvCtrl->bufBase);        return (OK);    }/******************************************************************************** mbcPollStart - start polled mode operations** RETURNS: OK.*/LOCAL STATUS mbcPollStart    (    MBC_DEVICE *	pDrvCtrl	/* device to be polled */    )    {    int	oldLevel;    DRV_LOG (DRV_DEBUG_POLL, "%s%d: ultraPollStart\n",	     (int) DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6);         oldLevel = intLock ();		/* disable ints during update */    SYS_OUT_SHORT (pDrvCtrl, MBC_IMASK, 0x00);    pDrvCtrl->flags |= MBC_POLLING;    intUnlock (oldLevel);		/* now mbcInt won't get confused */    return (OK);    }/******************************************************************************** mbcPollStop - stop polled mode operations** 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 or ERROR.*/LOCAL STATUS mbcPollStop    (    MBC_DEVICE *	pDrvCtrl	/* device to be polled */    )    {    int	oldLevel;    DRV_LOG (DRV_DEBUG_POLL, "%s%d: ultraPollStop\n",	     (int) DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6);         /* re-enable interrupts */          oldLevel = intLock ();	/* disable ints during register updates */    SYS_OUT_SHORT (pDrvCtrl, MBC_IMASK, MBC_IMASK_RXF | MBC_IMASK_EBE);    pDrvCtrl->flags &= ~MBC_POLLING;    intUnlock (oldLevel);    return (OK);    }/******************************************************************************** mbcReset - reset device** RETURNS: N/A.** NOMANUAL*/LOCAL void mbcReset    (    MBC_DEVICE *	pDrvCtrl	/* interrupting device */    )    {    int counter = 0xffff;        /* Disable interrupts */        SYS_OUT_SHORT (pDrvCtrl, MBC_IMASK, 0x00);    /* clear pending `graceful stop complete' event, and start one */    SYS_OUT_SHORT (pDrvCtrl, MBC_IEVNT, MBC_IEVNT_GRA);    SYS_OUT_SHORT (pDrvCtrl, MBC_ECNTL, MBC_ECNTL_GTS);    /* wait for graceful stop to register */    while (counter--)	{	USHORT event;		SYS_IN_SHORT (pDrvCtrl, MBC_IEVNT, &event);	if (event & MBC_IEVNT_GRA)	    break;	}    /* disable the receiver and transmitter. */    SYS_RESET_SHORT (pDrvCtrl, MBC_ECNTL, MBC_ECNTL_ENBL);        pDrvCtrl->resetCounter++;    }

⌨️ 快捷键说明

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