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

📄 if_sn.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifdef SN_DEBUG            if (SN_DEBUG_TX && SN_DEBUG_VERBOSE)                logMsg ("sn: Tx: reclaimed TXD=%x\n", (int)pTXD, 0, 0, 0, 0, 0);#endif /* SN_DEBUG */            }        else                                    /* ERROR! */            {            pDrvCtrl->TxErrs++;                 /* bump our counter */            pDrvCtrl->pDev->cr = TXP;           /* restart transmitter */            break;            }        /* Advance to the next TXD. */        pTXD = pTXD->pLink;        /* Update the reclaim pointer for next time. */        pDrvCtrl->pTXDReclaim = pTXD;        /* invalidate the cache for this TXD */        CACHE_DMA_INVALIDATE (&pTXD->status, sizeof (pTXD->status));        }    }/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * SECTION: Receive related routines *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*//****************************************************************************** snRxPktReady - indicates a received packet is ready for processing*/LOCAL BOOL snRxPktReady (pDrvCtrl)    DRV_CTRL *pDrvCtrl;    {    RX_DESC *pRXD;    pRXD = pDrvCtrl->pRXDNext;    CACHE_DMA_INVALIDATE (pRXD, RX_DESC_SIZ);    if (pRXD->in_use == NOT_IN_USE)              /* if not yet filled */        return (FALSE);    return (TRUE);    }/********************************************************************************* snRxPktProcess - process one received packet**/LOCAL STATUS snRxPktProcess (pDrvCtrl)    DRV_CTRL *pDrvCtrl;    {    RX_DESC *pRXD;                       /* ptr to a packet descriptor */    struct ether_header *pPktHdr;        /* ptr to packet header */    u_char *pData;                       /* ptr to packet data */    MBUF *pMbuf;                         /* ptr to mbuf structs */    SONIC *pDev;                         /* ptr to the device regs */    int len;    int ndx;                                  /* index into RRA desc array */    int status;                               /* return status */    u_short ether_type;                       /* safe copy of packet type */    int spl;    /* The current RX_DESC will already have been made cache coherent     * by the snRxPktReady() routine.  There is no need to do it here.     */    pRXD    = pDrvCtrl->pRXDNext;               /* get ptr to the desc */    len     = (pRXD->byte_count & UMASK) - 4;   /* get pkt length - FCS */    pPktHdr = (struct ether_header *)           /* get ptr to pkt header */                (((pRXD->pkt_ptr1 & UMASK) << 16) | (pRXD->pkt_ptr0 & UMASK));    pPktHdr = (struct ether_header *) CACHE_DMA_PHYS_TO_VIRT (pPktHdr);    /* Do some sanity checks on the RXD info */    if  (        (len < 60)                      ||        (len > 1514)                    ||        (pPktHdr == NULL)               ||        (!(pRXD->status & PRX))         ||        (pRXD->link == RX_EOL)          ||        (pRXD->link == NULL)        )        {        logMsg ("sn: Fatal error.  Receive structures invalid.\n",0,0,0,0,0,0);        taskSuspend (0);        return (ERROR);        }    pDrvCtrl->sn_if.if_ipackets++;          /* bump statistic */                                            /* advance our mgmt variable */    pDrvCtrl->pRXDNext = (RX_DESC *) CACHE_DMA_PHYS_TO_VIRT (pRXD->link);#ifdef SN_DEBUG    if (SN_DEBUG_RX && SN_DEBUG_VERBOSE)        logMsg ("sn: Rx: packet addr=0x%x, len=0x%x, pRXD=0x%x\n",                (int)pPktHdr, len, (int)pRXD, 0, 0, 0);    if (SN_DEBUG_TRACE)	{        logMsg ("sn: Rx: packet type 0x%x from %s",		pPktHdr->ether_type, (int)ether_sprintf (&pPktHdr->ether_shost),		0, 0, 0, 0);        logMsg (" to %s\n", (int) ether_sprintf (&pPktHdr->ether_dhost),		0, 0, 0, 0, 0);	}#endif /* SN_DEBUG */    CACHE_DMA_INVALIDATE (pPktHdr, len);    /* call input hook if any */    if (etherInputHookRtn != NULL)        {        if ((* etherInputHookRtn) (&pDrvCtrl->sn_if, (char *)pPktHdr, len))            return (OK);        }    /* Subtract size of enet header from packet length. */    len -= 14;    /* Set pData to begining of packet data. */    pData = (u_char *)pPktHdr;    pData += 14;    /* save the packet type, since build_cluster modifies the packet header */    ether_type = pPktHdr->ether_type;    /* convert packet data into mbufs */    spl = splnet ();    pMbuf = copy_to_mbufs (pData, len, 0, (IFNET *) &pDrvCtrl->sn_if);    splx (spl);    /* We are now done with the packet descriptor and the packet data.     * First we manage the packet buffer mechanisms, then we manage     * the packet descriptor mechanisms.     */    { /* done with packet buffer */    if (pRXD->status & LPKT)                 /* if last pkt in this buffer */        {        /* form index to RRA descriptor this packet associates with */        ndx = (((pRXD->seq_no & 0x0000ff00) >> 8) + 1) % NUM_RRA_DESC;        pDev = pDrvCtrl->pDev;        pDev->rwp = (unsigned long)(&((RRA_DESC *)pDrvCtrl->RSA)[ndx]) & UMASK;        if (pDev->isr & RBE)                /* deal with RBE condition */            pDev->isr = RBE;                /* clear the RBE condition */        }    }    {  /* done with the desc */    pRXD->in_use = NOT_IN_USE;                     /* Set NOT_IN_USE */    pRXD->link = RX_EOL;                           /* Last one */    /* Link into list */    pDrvCtrl->pRXDLast->link = (RX_DESC *) CACHE_DMA_VIRT_TO_PHYS (pRXD);    pDrvCtrl->pRXDLast = pRXD;                /* update our mgmt variable */    }    if (pMbuf == NULL)        {        logMsg ("sn: out of mbufs\n",0,0,0,0,0,0);        pDrvCtrl->sn_if.if_ierrors++;           /* bump error statistic */        status = ERROR;        }    else        { /* give the packet to the appropriate protocol */        spl = splnet ();#ifdef BSD43_DRIVER        do_protocol_with_type (ether_type, pMbuf, &pDrvCtrl->sn_ac, len);#else        do_protocol (pPktHdr, pMbuf, &pDrvCtrl->sn_ac, len);#endif        splx (spl);        status = OK;        }    return (status);    }/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * SECTION: Interrupt driven routines, and primary event handler *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*//********************************************************************************* snIntr - device interrupt handler** This routine is called at interrupt level in response to an interrupt from* the device.** Only the "received packet" interrupt event is acknowledged and serviced* in this routine.  Some of the exception conditions are handled elsewhere.*/LOCAL void snIntr (int unit)    {    DRV_CTRL *pDrvCtrl;                  /* ptr to driver ctrl struct */    SONIC *pDev;                         /* ptr to the device regs */    pDrvCtrl = & drvCtrl [unit];    pDev = pDrvCtrl->pDev;    if ((pDev->isr & pDev->imr) & TCEN)	{	if (pDrvCtrl->timerIntHandler)	    {	    pDev->cr = STP;	    pDev->isr = TCEN;	    (*pDrvCtrl->timerIntHandler)();	    pDev->wt0 = pDrvCtrl->ticks & 0xffff;	    pDev->wt1 = pDrvCtrl->ticks >> 16;	    pDev->cr = ST;	    }	}    if ((pDev->isr & pDev->imr) & (PKTRX | TXDN | TXER))	{        /* disable further interrupts (except timer and bus retry enable). */	pDev->imr = (pDrvCtrl->imr &= BREN | TCEN);        (void) netJobAdd (                   /* queue netTask job */                         (FUNCPTR)snEventHandler,                         unit,                         0,0,0,0                         );	}    /* Handle bus retry interrupt. */    if (pDev->isr & BR)        pDev->isr = BR;    sysEnetIntAck (unit);                /* do system int ack */    }/********************************************************************************* snEventHandler - device event handler, a netTask job*/LOCAL void snEventHandler (int unit)    {    DRV_CTRL *pDrvCtrl;    SONIC *pDev;                         /* ptr to the device regs */    int loops;#ifdef SN_DEBUG    if (SN_DEBUG_EVENT)        logMsg ("sn: event handler enter\n", 0, 0, 0, 0, 0, 0);#endif /* SN_DEBUG */    /* Give up the spl semaphore. We don't need it yet, even though the     * netTask thinks we do.     */    splx (0);    pDrvCtrl = & drvCtrl [unit];    pDev = pDrvCtrl->pDev;    loops = 0;    /* Loop, processing events */    while ( pDev->isr & (PKTRX | TXDN | TXER) )        {        /* Process received packets */        if (pDev->isr & PKTRX)            {            while (snRxPktReady (pDrvCtrl))             /* packets ready? */                {                pDev->isr = PKTRX;                /* clear this interrupt */                snRxPktProcess (pDrvCtrl);                }            }        /* Process transmitter events */        if ( pDev->isr & (TXDN | TXER) )            {            pDev->isr = (TXDN | TXER);            /* clear these interrupts */            snTxReclaim (pDrvCtrl);            }         loops++;        }    /* Take the spl semaphore before we return to the main loop of the     * netTask.  This is done because the spl semaphore is assumed to be     * owned by netTask after this routine returns.     */    (void) splnet ();    /* Enable the interrupts */    pDev->imr = (pDrvCtrl->imr |= PKTRX | TXDN | TXER);#ifdef SN_DEBUG    if (SN_DEBUG_EVENT)        logMsg ("sn: event handler exit %d\n", loops, 0, 0, 0, 0, 0);#endif /* SN_DEBUG */    }/********************************************************************************* snClkEnable - enable the SONIC timer interrupt** This routine enables the SONIC timer to give a periodic interrupt.* The <unit> parameter selects the SONIC device.  The <ticksPerSecond>* parameter specifies the number of interrupts to generate per second.* When an interrupt occurs, the function in <intHandler> is called.** NOTE:* The SONIC clock interrupt is dependent on the SONIC interface being* configured and enabled.  For this reason, this interrupt is unsuitable* for use as the main system clock.  It is suitable for use as an auxiliary* clock source for boards that have no other source of clock.** RETURNS: N/A** SEE ALSO: snClkDisable()** NOMANUAL*/void snClkEnable    (    int unit,			/* unit number */    int ticksPerSecond,		/* interrupt frequency */    FUNCPTR intHandler		/* interrupt handler */    )    {    DRV_CTRL *pDrvCtrl;    SONIC *pDev;    int key;    pDrvCtrl = & drvCtrl [ unit ];    pDev = pDrvCtrl->pDev;    key = intLock ();    pDrvCtrl->timerIntHandler = intHandler;    pDrvCtrl->ticks = 5000000 / ticksPerSecond;    pDrvCtrl->imr |= TCEN;    if (pDev)	{	pDev->cr = STP;	pDev->wt0 = pDrvCtrl->ticks & 0xffff;	pDev->wt1 = pDrvCtrl->ticks >> 16;	pDev->imr = pDrvCtrl->imr;	pDev->cr = ST;	}    intUnlock (key);    }/********************************************************************************* snClkDisable - disable the SONIC timer interrupt** This routine disables the SONIC timer interrupt.  The <unit> parameter* selects the SONIC device.** RETURNS: N/A** SEE ALSO: snClkEnable()** NOMANUAL*/void snClkDisable    (    int unit			/* unit number */    )    {    DRV_CTRL *pDrvCtrl;    SONIC *pDev;    int key;    pDrvCtrl = & drvCtrl [ unit ];    pDev = pDrvCtrl->pDev;    if (pDev)	{	key = intLock ();	pDev->imr = (pDrvCtrl->imr &= ~TCEN);	pDev->cr = STP;	intUnlock (key);	}    }/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * SECTION: NOTES *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*//* END OF FILE */

⌨️ 快捷键说明

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