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

📄 if_mbc.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    MBC_REG_WRITE (pDrvCtrl->ether.pDevBase, MBC_IEVNT, MBC_IEVNT_GRA);    MBC_REG_UPDATE (pDrvCtrl->ether.pDevBase, MBC_ECNTL, MBC_ECNTL_GTS);    /* wait for graceful stop to register */        while ((counter--) &&           (! (MBC_IEVNT_READ (pDrvCtrl->ether.pDevBase) & MBC_IEVNT_GRA)));    /* disable the receiver and transmitter. */    MBC_REG_RESET (pDrvCtrl->ether.pDevBase, MBC_ECNTL, MBC_ECNTL_ENBL);    /* mark the driver as down */    pDrvCtrl->idr.ac_if.if_flags &= ~(IFF_UP | IFF_RUNNING);    /* mark the driver as no longer initialized */    pDrvCtrl->initialized = FALSE;    pDrvCtrl->resetCounter++;        }/********************************************************************************* mbcIntr - network interface interrupt handler** This routine is called at interrupt level. It handles work that * requires minimal processing. Interrupt processing that is more * extensive gets handled at task level. The network task, netTask(), is * provided for this function. Routines get added to the netTask() work * queue via the netJobAdd() command.** RETURNS: N/A*/void mbcIntr    (    int		unit		/* unit number */    )    {    DRV_CTRL * 		pDrvCtrl = & drvCtrl[unit];    volatile char *	pDevBase = pDrvCtrl->ether.pDevBase;    int 		events;    /* identify and acknowledge all interrupt events */    events = (MBC_IEVNT_READ (pDevBase) &              (MBC_IMASK_READ (pDevBase) | MBC_IMASK_BSY));        MBC_INTR_ACK (pDevBase, events);    /* check for spurious interrupt -> driver initialized ? */    if (! pDrvCtrl->initialized)	{	MBC_INTR_ACK (pDevBase, 0xffff);	return;	}    /* handle receive events */    if (events & MBC_IEVNT_RXF)	{        (void) netJobAdd ((FUNCPTR) mbcHandleInt, (int) pDrvCtrl, 0,0,0,0); 	/* turn off receive interrupts - mbcHandleInt turns back on */	MBC_INTR_DISABLE (pDevBase, MBC_IEVNT_RXF);        }    /* handle transmitter events - BD full condition -> ever happen ? */    if (events & MBC_IEVNT_TXF)	{        wdCancel (pDrvCtrl->wdId);#ifdef BSD43_DRIVER                (void) netJobAdd ((FUNCPTR) mbcStartOutput, unit, 0, 0, 0, 0); #else        (void) netJobAdd ((FUNCPTR) mbcStartOutput, (int)pDrvCtrl, 0, 0, 0, 0); #endif	MBC_INTR_DISABLE (pDevBase, 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)	{        /* count discarded frames as errors */        pDrvCtrl->idr.ac_if.if_ierrors += 1;	}    /* restart the transmitter on a ethernet bus error */        if (events & MBC_IEVNT_EBE)        {        (void) netJobAdd ((FUNCPTR) mbcDeviceRestart, unit, 0,0,0,0);                        MBC_INTR_ACK (pDevBase, MBC_IEVNT_EBE);        }    /* ignore and reset all other events */    MBC_INTR_ACK (pDevBase, ~(MBC_IMASK_READ(pDevBase)));    return;    }/********************************************************************************* mbcHandleInt - task-level interrupt handler** This is the task-level interrupt handler, which is called from * netTask(). mbcHandleInt() gets input frames from the device and then calls * mbcRecv() to process each frame.  mbcRecv() only gets called if no error* stats were reported in the buffer descriptor.  Data chaining is not* supported.** This routine should be called with MBC receive interrupts masked so that* more netJobAdds of this routine are not performed by mbcIntr().* Receive interrupts are turned back on by this routine before exiting.** RETURNS: N/A*/LOCAL void mbcHandleInt    (    DRV_CTRL *	pDrvCtrl	/* pointer to DRV_CTRL structure */    )    {    volatile char *  pDevBase = pDrvCtrl->ether.pDevBase;    MBC_BD *	     pRxBd;    pRxBd = & pDrvCtrl->ether.rxBdBase[pDrvCtrl->ether.rxBdNext];        while (!(pRxBd->statusMode & MBC_RXBD_E))        {        /* data chaining is not supported - check all error conditions */        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)))            mbcRecv (pDrvCtrl, pRxBd);        else            {            pDrvCtrl->idr.ac_if.if_ierrors++;            /*             * Fix for errata #9 -- Device Errata, Feb 20, 1997.             * Ethernet frames may be incorrectly received after a rx FIFO             * overflow.             */                        if ((pRxBd->statusMode & MBC_RXBD_L) &&                ! (pRxBd->statusMode & MBC_RXBD_F))                {                mbcDeviceRestart (pDrvCtrl->ether.mbcNum);                return;                }            }        /* reset buffer descriptor as empty */        pRxBd->statusMode |= MBC_RXBD_E;                /* incr BD count */        pDrvCtrl->ether.rxBdNext = (pDrvCtrl->ether.rxBdNext + 1) %				    pDrvCtrl->ether.rxBdNum;        pRxBd = & pDrvCtrl->ether.rxBdBase[pDrvCtrl->ether.rxBdNext];        /* clear Rx events */	MBC_INTR_ACK (pDevBase, MBC_IEVNT_RXF);        }    /* re-enable Rx interrupts */    MBC_INTR_ENABLE (pDevBase, MBC_IEVNT_RXF);    }/********************************************************************************* mbcRecv - process an input frame** This routine processes an input frame, then passes it up to the higher * level in a form it expects.  Buffer loaning, promiscuous mode, and* etherInputHookRtns are all supported.  Trailer protocols is not supported.** RETURNS: N/A*/LOCAL void mbcRecv    (    DRV_CTRL *	pDrvCtrl,	/* pointer to DRV_CTRL structure */    MBC_BD *	pRxBd		/* receive buffer descriptor */    )    {     MBUF *	pMbuf = NULL;	/* MBUF pointer */    UINT8 *	pData;    int		length;#ifdef BSD43_DRIVER    UINT16	type;#else    struct ether_header * 	pEh;#endif    /* bump input packet counter */    pDrvCtrl->idr.ac_if.if_ipackets++;    /* call hook if one is connected */    if ((etherInputHookRtn != NULL) && ((*etherInputHookRtn)	(& pDrvCtrl->idr.ac_if, pRxBd->dataPointer, pRxBd->dataLength) != 0))        return;     /* check the M bit, to filter frames not destined for this station. */    if (pRxBd->statusMode & MBC_RXBD_M)        return;    /* adjust length to data only */    length = pRxBd->dataLength - SIZEOF_ETHERHEADER;    if (length <= 0)	{         pDrvCtrl->idr.ac_if.if_ierrors++;	return;	}    /* point to data */    pData = pRxBd->dataPointer + SIZEOF_ETHERHEADER;#ifdef BSD43_DRIVER    /* save type - build_cluster trashes the type field */    type = ((ETH_HDR *) pRxBd->dataPointer)->ether_type;#else    /* BSD 4.4 uses Ethernet header */       pEh = (struct ether_header *) pRxBd->dataPointer;#endif    /* OK to loan out buffer ? -> build a mbuf cluster */    if ((pDrvCtrl->nLoan > 0) && (USE_CLUSTER (length)))	pMbuf = build_cluster (pData, length, & pDrvCtrl->idr, MC_MBC,	    pDrvCtrl->pRefCnt[(pDrvCtrl->nLoan - 1)], mbcLoanFree,	    (int) pDrvCtrl, (int) pRxBd->dataPointer,	    (int) pDrvCtrl->pRefCnt[(pDrvCtrl->nLoan - 1)]);    /* if buffer was successfully turned into mbuf cluster */    if (pMbuf != NULL)	pRxBd->dataPointer = pDrvCtrl->lPool[--pDrvCtrl->nLoan];    else        {	/* else do same ol' copy to mbuf */        pMbuf = copy_to_mbufs (pData, length, 0, & pDrvCtrl->idr.ac_if);        if (pMbuf == NULL)	    {            pDrvCtrl->idr.ac_if.if_ierrors++;            return;	    }        }    /* send up to protocol */#ifdef BSD43_DRIVER    do_protocol_with_type (type, pMbuf, & pDrvCtrl->idr, length);#else    do_protocol (pEh, pMbuf, & pDrvCtrl->idr, length);#endif    }/********************************************************************************* mbcDeviceRestart - restart transmits** This routine re-resets the Ethernet device.  It is called by the watchdog* timer which expires when transmit BDs are all full, and a transmit frame* interrupt does not occur with in 20 clock ticks.  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, and can be examined with mbcShow().** RETURNS: N/A** SEE ALSO: mbcIntr(), mbcShow(), mbcStartOutput()*/LOCAL void mbcDeviceRestart    (    int 	unit    )    {    mbcReset (unit);    mbcInit (unit);    }/********************************************************************************* mbcLoanFree - return the given buffer to loaner pool** This routine returns <pRxBuf> to the pool of available loaner buffers.* It also returns <pRef> to the pool of available loaner reference counters,* then zeroes the reference count.** RETURNS: N/A*/LOCAL void mbcLoanFree    (    DRV_CTRL *	pDrvCtrl,    UINT8 *	pRxBuf,    UINT8 *	pRefCnt    )    {    /* return loaned buffer to pool */    pDrvCtrl->lPool[pDrvCtrl->nLoan] = pRxBuf;    /* return loaned reference count to pool */    pDrvCtrl->pRefCnt[pDrvCtrl->nLoan++] = pRefCnt;    /* reset reference count - should have been done from above, but... */    *pRefCnt = 0;    }/********************************************************************************* mbcShow - displays the internal state of an Ethernet unit** This routine prints the following information about the device unit,* .iP* - txBdNum, the number of transmit buffer descriptors * .iP* - rxBdNum, the number of receive buffer descriptors* .iP* - txBdNext, the next transmit buffer descriptor index* .iP* - rxBdNext, the next receive buffer descriptor index* .iP* - all the Ethernet configuration registers* .LP** RETURNS: N/A.** NOMANUAL*/void mbcShow    (    int unit                    /* unit number */    )    {    DRV_CTRL *		pDrvCtrl;    volatile char *	pDevBase;         if (unit < 0 || unit >= MAX_UNITS)        return;    pDrvCtrl = & drvCtrl[unit];    pDevBase = pDrvCtrl->ether.pDevBase;    printf ("mbc (unit %d):\n", unit);    printf ("    0x%x Resets\n",            pDrvCtrl->resetCounter);        printf ("    %d transmit BDs, %d receive BDs, %d loaner buffers\n",            pDrvCtrl->ether.txBdNum, pDrvCtrl->ether.rxBdNum,            pDrvCtrl->nLoan);    printf ("    Next transmit BD is %d,  Next receive BD is %d\n",            pDrvCtrl->ether.txBdNext, pDrvCtrl->ether.rxBdNext);    printf ("    Registers: ectrl (0x%x), edma (0x%x), mrbl (0x%x)\n",            MBC_REG_READ (pDevBase, MBC_ECNTL),            MBC_REG_READ (pDevBase, MBC_EDMA),            MBC_REG_READ (pDevBase, MBC_EMRBLR));        printf ("               ivec (0x%x), ievent (0x%x), imask (0x%x)\n",            MBC_REG_READ (pDevBase, MBC_IVEC),            MBC_REG_READ (pDevBase, MBC_IEVNT),            MBC_REG_READ (pDevBase, MBC_IMASK));                    printf ("               ecnfg (0x%x), etest (0x%x), ar(0x%x)\n",            MBC_REG_READ (pDevBase, MBC_ECFG),            MBC_REG_READ (pDevBase, MBC_TEST),            MBC_REG_READ (pDevBase, MBC_AR));    }/********************************************************************************* mbcBdShow - display buffer descriptors** This routine displays the flags, len, and the buffer pointer fields of each* buffer descriptor in the requested range. The parameter <start> is the* beginning buffer descriptor, and <count> is number of buffer descriptors to* display.** RETURNS: N/A.** NOMANUAL*/void mbcBdShow    (    int unit,                   /* unit number */    int start,                  /* starting BD */    int count                   /* number of BDs */    )    {    DRV_CTRL *		pDrvCtrl;    volatile MBC_BD *	pBd;    /* buffer descriptor pointer */            if (unit < 0 || unit >= MAX_UNITS)        return;    pDrvCtrl = & drvCtrl[unit];    pBd      = pDrvCtrl->ether.txBdBase;    while (start < 128 && count)        {        printf ("BD %d: flags=0x%x, len=0x%x, pBuf=0x%xn",                start, pBd[start].statusMode,                pBd[start].dataLength,                (UINT32) pBd[start].dataPointer);         start++;        count--;        }    }

⌨️ 快捷键说明

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