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

📄 mbcend.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    pBd = pDrvCtrl->rxBdBase;    for (counter = pDrvCtrl->rxBdNum; counter; counter--, pBd++)	{	char * pBuf;	if (pBd->dataPointer != NULL)	    netClFree (pDrvCtrl->end.pNetPool,		       (pBd->dataPointer - pDrvCtrl->offset));	pBuf = netClusterGet (pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId);	if (pBuf == NULL)	    {            DRV_LOG (DRV_DEBUG_LOAD | DRV_DEBUG_ERROR,		     "Could not get a buffer\n", 1, 2, 3, 4, 5, 6);            return (ERROR);	    }        pBd->statusMode = (MBC_RXBD_E | MBC_RXBD_I);	pBd->dataPointer = pBuf + pDrvCtrl->offset;	}    pBd--;    pBd->statusMode |= MBC_RXBD_W;    /* set the interrupt vector number */    SYS_OUT_SHORT (pDrvCtrl, MBC_IVEC, pDrvCtrl->ivec);    /* set BD size and other DMA parameters */    regValue = pDrvCtrl->dmaParms | (pDrvCtrl->bdSize << MBC_EDMA_BDS_SHFT);    SYS_OUT_SHORT (pDrvCtrl, MBC_EDMA, regValue);    /*     * set the operating mode to, no internal loopback, no full duplex, and     * no hearbeat control.     */        SYS_OUT_SHORT (pDrvCtrl, MBC_ECFG, 0);    /*     * set address control to, no hash enable, no index enable, no multicast,     * no physical address rejection.     */        SYS_OUT_SHORT (pDrvCtrl, MBC_AR, 0x00);    /* set max receive frame size */    SYS_OUT_SHORT (pDrvCtrl, MBC_EMRBLR, FRAME_MAX);            return (OK);    }/******************************************************************************** mbcDeviceRestart - restart transmits** This routine re-resets the Ethernet device. Since on a transmit lock* up, the transmitter can be restarted only by resetting the device, this* routine resets, and reinitializes the device.  The device reset counter will* be updated on each reset.** RETURNS: N/A** SEE ALSO: mbcInt(), mbcSend(), mbcPacketGet()** NOMANUAL*/LOCAL void mbcDeviceRestart    (    MBC_DEVICE *	pDrvCtrl	    )    {    mbcReset (pDrvCtrl);    mbcInit (pDrvCtrl);    }/******************************************************************************** mbcConfig - reconfigure the interface under us.** Reconfigure the interface setting promiscuous mode, and changing the* multicast interface list.** RETURNS: N/A.** NOMANUAL*/LOCAL void mbcConfig    (    MBC_DEVICE *	pDrvCtrl	/* device to be re-configured */    )    {    int		i;    int		numMulti;	/* Number of multicast addresses */    UINT16	regValue;    /* Determine the number of multicast addresses */	    numMulti = END_MULTI_LST_CNT (&pDrvCtrl->end);    DRV_LOG (DRV_DEBUG_LOAD, "%s%d: mbcConfig: %d multicast addresses\n",	     (int) DEV_NAME, pDrvCtrl->unit, numMulti, 4, 5, 6);    /* install the ethernet address */        bcopy ((char *) pDrvCtrl->enetAddr,           (char *) (pDrvCtrl->memAddr + MBC_ARTAB),           ENET_ADDR_SIZE);        /*     * Setup address control w/o multicasting enabled, and write     * the entire address arrray.     */        regValue = MBC_AR_MULTI_00;    if (END_FLAGS_GET(&pDrvCtrl->end) & IFF_PROMISC)        regValue |= MBC_AR_PROM;    SYS_OUT_SHORT (pDrvCtrl, MBC_AR, regValue);    for (i = 1; i < MBC_ARTAB_SIZE; i++)        {        SYS_OUT_SHORT (pDrvCtrl, MBC_ARTAB + (i * 8), ~0);        SYS_OUT_SHORT (pDrvCtrl, MBC_ARTAB + (i * 8) + 2, ~0);        SYS_OUT_SHORT (pDrvCtrl, MBC_ARTAB + (i * 8) + 4, ~0);        }        /* Now install the multicast addresses or filter */    if ((numMulti > 0) && (numMulti <= MBC_ARTAB_SIZE-1))	{	ETHER_MULTI * pCurr;	/* Install the multicast addresses directly in the table */	for (i = 1, pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->end);	     pCurr != NULL;	     pCurr = END_MULTI_LST_NEXT(pCurr), ++i)	    {	    bcopy ((char *) &pCurr->addr,		   (char *) (pDrvCtrl->memAddr + MBC_ARTAB + i*8),		   ENET_ADDR_SIZE);	    }	}    else if (numMulti > MBC_ARTAB_SIZE-1)	{	/* Setup the multicast filter */	mbcAddrFilterSet (pDrvCtrl);		DRV_LOG (DRV_DEBUG_LOAD | DRV_DEBUG_MULTI,		 "Multicast Filter 0-3 %02x:%02x:%02x:%02x\n",		 pDrvCtrl->mcastFilter[0], pDrvCtrl->mcastFilter[1],		 pDrvCtrl->mcastFilter[2], pDrvCtrl->mcastFilter[3], 0, 0);	DRV_LOG (DRV_DEBUG_LOAD | DRV_DEBUG_MULTI,		 "Multicast Filter 4-7 %02x:%02x:%02x:%02x\n",		 pDrvCtrl->mcastFilter[4], pDrvCtrl->mcastFilter[5],		 pDrvCtrl->mcastFilter[6], pDrvCtrl->mcastFilter[7], 0, 0);	/* Write out multicast filter */        SYS_OUT_SHORT (pDrvCtrl, MBC_ARTAB + 0x01f0,		       (pDrvCtrl->mcastFilter[0] << 8)		       | pDrvCtrl->mcastFilter[1]);        SYS_OUT_SHORT (pDrvCtrl, MBC_ARTAB + 0x01f2,		       (pDrvCtrl->mcastFilter[2] << 8)		       | pDrvCtrl->mcastFilter[3]);        SYS_OUT_SHORT (pDrvCtrl, MBC_ARTAB + 0x01f8,		       (pDrvCtrl->mcastFilter[4] << 8)		       | pDrvCtrl->mcastFilter[5]);        SYS_OUT_SHORT (pDrvCtrl, MBC_ARTAB + 0x01fa,		       (pDrvCtrl->mcastFilter[6] << 8)		       | pDrvCtrl->mcastFilter[7]);	/* Now enable multicast addressing */	SYS_IN_SHORT (pDrvCtrl, MBC_AR, &regValue);	regValue |= MBC_AR_HASH;	SYS_OUT_SHORT (pDrvCtrl, MBC_AR, regValue);	}    }/******************************************************************************** mbcStart - start the device** This function calls BSP functions to connect interrupts and start the* device running in interrupt mode.** RETURNS: OK or ERROR** NOMANUAL*/LOCAL STATUS mbcStart    (    void *	pObj		/* device ID */    )    {    STATUS	 result;    MBC_DEVICE * pDrvCtrl = pObj;	/* device to be started */    DRV_LOG (DRV_DEBUG_LOAD, "%s%d: mbcStart\n",	     (int) DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6);    SYS_INT_CONNECT (pDrvCtrl, mbcInt, (int)pDrvCtrl, &result);    if (result == ERROR)	return (ERROR);    DRV_LOG (DRV_DEBUG_LOAD, "Interrupt connected.\n", 1, 2, 3, 4, 5, 6);    /* enable interrupts - clear events and set mask */    SYS_OUT_SHORT (pDrvCtrl, MBC_IEVNT, 0xffff);    SYS_OUT_SHORT (pDrvCtrl, MBC_IMASK, MBC_IMASK_RXF | MBC_IMASK_EBE);    /* enable the device */    SYS_UPDATE_SHORT (pDrvCtrl, MBC_ECNTL, MBC_ECNTL_ENBL);        DRV_LOG (DRV_DEBUG_LOAD, "interrupt enabled.\n", 1, 2, 3, 4, 5, 6);    return (OK);    }/******************************************************************************** mbcInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.** RETURNS: N/A.*/LOCAL void mbcInt    (    MBC_DEVICE *	pDrvCtrl	/* interrupting device */    )    {    UINT16 	mask;    UINT16 	events;    /* identify and acknowledge all interrupt events */    SYS_IN_SHORT (pDrvCtrl, MBC_IEVNT, &events);    SYS_IN_SHORT (pDrvCtrl, MBC_IMASK, &mask);    events = (events & (mask | MBC_IMASK_BSY));    SYS_OUT_SHORT (pDrvCtrl, MBC_IEVNT, events);    DRV_LOG (DRV_DEBUG_INT,	     "%s%d: mbcInt events=%04x mask=%04x\n",	     (int) DEV_NAME, pDrvCtrl->unit, events, mask, 0, 0);    /* handle receive events */    if (events & MBC_IEVNT_RXF)	{        if (pDrvCtrl->rxHandling == FALSE)            {	    pDrvCtrl->rxHandling = TRUE;            netJobAdd ((FUNCPTR)mbcHandleRcvInt, (int)pDrvCtrl, 0, 0, 0, 0);	    }        }    /* handle transmitter events - BD full condition -> ever happen ? */    if (events & MBC_IEVNT_TXF)	{	DRV_LOG (DRV_DEBUG_INT | DRV_DEBUG_ERROR,		 "%s%d: mbcInt: transmit full\n",		 (int) DEV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);             wdCancel (pDrvCtrl->wdId);	if (pDrvCtrl->txBlocked)	/* cause a restart */	    {	    netJobAdd ((FUNCPTR)muxTxRestart, (int) &pDrvCtrl->end,		       0, 0, 0, 0);	    pDrvCtrl->txBlocked = FALSE;	    }	SYS_RESET_SHORT (pDrvCtrl, MBC_IMASK, MBC_IEVNT_TXF);	}    /*     * check for input busy condition, we don't enable this interrupt     * but we check for it with each interrupt.     */    if (events & MBC_IEVNT_BSY)	{	DRV_LOG (DRV_DEBUG_INT | DRV_DEBUG_ERROR,		 "%s%d: mbcInt: input busy\n",		 (int) DEV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);        /* count discarded frames as errors */	END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);	}    /* restart the transmitter on a ethernet bus error */    if (events & MBC_IEVNT_EBE)        {	DRV_LOG (DRV_DEBUG_INT | DRV_DEBUG_ERROR,		 "%s%d: mbcInt: ethernet bus error\n",		 (int) DEV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);	netJobAdd ((FUNCPTR)mbcDeviceRestart, (int) pDrvCtrl, 0, 0, 0, 0);	}    if (!pDrvCtrl->txCleaning)        {        pDrvCtrl->txCleaning = TRUE;        netJobAdd ((FUNCPTR)mbcScrubTRing, (int) pDrvCtrl, 0, 0, 0, 0);        }    /* ignore and reset all other events */    SYS_OUT_SHORT (pDrvCtrl, MBC_IEVNT, ~mask);    }/******************************************************************************** mbcScrubTRing - clean the transmit ring** Cleans the transmit ring.** RETURNS: N/A** NOMANUAL*/LOCAL void mbcScrubTRing    (    MBC_DEVICE *	pDrvCtrl    )    {    int			oldLevel;    volatile MBC_BD *	pTxBd;        pDrvCtrl->txCleaning = TRUE;    pTxBd = &pDrvCtrl->txBdBase [pDrvCtrl->txClNext];    while (pTxBd->dataPointer != NULL)        {        /* If the buffer is still owned by MBC, don't touch it */	if (pTxBd->statusMode & MBC_TXBD_R)	    break;        oldLevel = intLock ();        if (pDrvCtrl->freeRtn[pDrvCtrl->txClNext] != NULL)            {            pDrvCtrl->freeRtn[pDrvCtrl->txClNext]	      (pDrvCtrl->freeData[pDrvCtrl->txClNext].arg1,	       pDrvCtrl->freeData[pDrvCtrl->txClNext].arg2);             pDrvCtrl->freeRtn[pDrvCtrl->txClNext] = NULL;            pDrvCtrl->freeData[pDrvCtrl->txClNext].arg1 = NULL;             pDrvCtrl->freeData[pDrvCtrl->txClNext].arg2 = NULL;             }        	pTxBd->dataPointer = NULL;	pTxBd->statusMode &= ~MBC_TXBD_ERRS;        /* now bump the disposal index pointer around the ring */	pDrvCtrl->txClNext = (pDrvCtrl->txClNext + 1) % pDrvCtrl->txBdNum;	pTxBd = &pDrvCtrl->txBdBase [pDrvCtrl->txClNext];        intUnlock (oldLevel);        }    pDrvCtrl->txCleaning = FALSE;    }/******************************************************************************** mbcSend - 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.** RETURNS: OK or ERROR.*/LOCAL STATUS mbcSend    (    void *	pObj,		/* device ptr */    M_BLK_ID	pMblk		/* data to send */    )    {    int		len;    char *	pBuf;    char *	pOrig;    int		oldLevel;    MBC_DEVICE *	pDrvCtrl = pObj;    volatile MBC_BD *	pTxBd;        DRV_LOG (DRV_DEBUG_TX,	     "%s%d: mbcSend txBlocked=%d txCleaning=%d\n",	     (int) DEV_NAME, pDrvCtrl->unit,	     pDrvCtrl->txBlocked, pDrvCtrl->txCleaning, 5, 6);    /*     * Obtain exclusive access to transmitter.  This is necessary because     * we might have more than one stack transmitting at once.     */    if (!(pDrvCtrl->flags & MBC_POLLING))	END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER);    /* check if a transmit buffer descriptor is available */    pTxBd = &pDrvCtrl->txBdBase [pDrvCtrl->txBdNext];    if (pTxBd->statusMode & MBC_TXBD_R)	{	DRV_LOG (DRV_DEBUG_TX | DRV_DEBUG_ERROR,		 "%s%d: mbcSend: #%d still ready\n",		 (int) DEV_NAME, pDrvCtrl->unit,		 pDrvCtrl->txBdNext, 4, 5, 6);	wdStart (pDrvCtrl->wdId, WD_TIMEOUT, (FUNCPTR) mbcDeviceRestart,		 (int) pDrvCtrl);	pDrvCtrl->txBlocked = TRUE;	SYS_UPDATE_SHORT (pDrvCtrl, MBC_IMASK, MBC_IEVNT_TXF);	if (!(pDrvCtrl->flags & MBC_POLLING))	    END_TX_SEM_GIVE (&pDrvCtrl->end);	return (END_ERR_BLOCK);	}    if (pTxBd->dataPointer)	{	/* cleaning still needed, queue cleaning task */	DRV_LOG (DRV_DEBUG_TX | DRV_DEBUG_ERROR,		 "%s%d: mbcSend: #%d needs cleaning (cleaning=%d)\n",		 (int) DEV_NAME, pDrvCtrl->unit,		  pDrvCtrl->txBdNext, pDrvCtrl->txCleaning, 5, 6);	pDrvCtrl->txBlocked = TRUE;	if (pDrvCtrl->txCleaning == FALSE)	    {	    pDrvCtrl->txCleaning = TRUE;	    netJobAdd ((FUNCPTR)mbcScrubTRing, (int) pDrvCtrl, 0, 0, 0, 0);	    }

⌨️ 快捷键说明

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