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

📄 if_sn.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
** snStartOutput - start pending output** This routine removes mbuf chains from the driver queue and attempts to* set up a SONIC transmit descriptor for each chain.  The transmit descriptors* are fed to the SONIC and subsequently transmitted onto the media.*/LOCAL void snStartOutput (unit)    int unit;    {    DRV_CTRL       *pDrvCtrl;    MBUF           *pMbuf;    MBUF           *pMbufTemp;    TX_DESC        *pTXD;    int            len;    int            adj_len;    int            fragIndex;    int            nUseableFrags;    char           *m_data;    u_long	   temp;    pDrvCtrl = & drvCtrl [unit];    /* Loop as long as our incoming queue is not empty */    while (pDrvCtrl->sn_if.if_snd.ifq_head != NULL)        {        IF_DEQUEUE (&pDrvCtrl->sn_if.if_snd, pMbuf);        /* call output hook if any */        /* etherOutputHookRtn not supported.         * This would require copying mbufs to contiguous buf.         *  if ((etherOutputHookRtn != NULL) &&         *      (* etherOutputHookRtn) (&pDrvCtrl->sn_if, buf, len))         *      continue;         */        /* Calculate length  & number of fragments */#ifdef SN_DEBUG	if (SN_DEBUG_TRACE)	    {	    static char buf[ETHERMTU];	    struct ether_header *pPktHdr;        /* ptr to packet header */	    FAST char *p = buf;	    FAST struct mbuf *m = pMbuf;	    for (; m != NULL; p += m->m_len, m = m->m_next)		bcopy (mtod (m, char *), p, m->m_len);	    pPktHdr = (struct ether_header *)&buf;	    logMsg ("sn: Tx: 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	        pMbufTemp     = pMbuf;        len           =        nUseableFrags = 0;        while (pMbufTemp != NULL)            /* while valid pointer */            {            if (pMbufTemp->m_len)        /* only count non-zero length frags */                {                len += pMbufTemp->m_len;     /* add length of this fragment */                nUseableFrags++;             /* bump fragment counter */                }            pMbufTemp = pMbufTemp->m_next;   /* advance to next mbuf fragment */            }        /* Bail out if too many frags */        if (nUseableFrags >= MAX_TX_FRAGS)            {            logMsg ("sn: Tx: too many mbuf fragments\n",0,0,0,0,0,0);            m_freem (pMbuf);                      /* packet is thrown away */            pDrvCtrl->sn_if.if_opackets--;        /* correct the stats */            pDrvCtrl->sn_if.if_oerrors++;            continue;            }        /* See if next transmit descriptor is available */        pTXD = pDrvCtrl->pTXDFree;        if (pTXD->flag)                           /* still in use */            {            m_freem (pMbuf);                      /* packet is thrown away */            pDrvCtrl->sn_if.if_opackets--;        /* correct the stats */            pDrvCtrl->sn_if.if_oerrors++;#ifdef SN_DEBUG            if (SN_DEBUG_TX)                logMsg ("sn: Tx, no descriptors", 0, 0, 0, 0, 0, 0);#endif /* SN_DEBUG */            break;            }        /* Mark this descriptor as "in use" */        pTXD->flag   = TRUE;        pTXD->status = 0;	/* remember the mbuf associated with this packet */	pTXD->pMbuf = pMbuf;        /* Ensure we send a minimum sized packet */        adj_len = max (ETHERSMALL, len);        /* Build a transmit descriptor.         * Loop thru each fragment in the mbuf chain and stuff our info.         */        for (            fragIndex = 0, pMbufTemp = pMbuf;            pMbufTemp != NULL;                  /* while valid mbuf pointer */            pMbufTemp = pMbufTemp->m_next       /* advance to next mbuf frag */            )            {            /* ignore zero-length mbufs */            if ( pMbufTemp->m_len == 0 )                continue;            m_data = mtod(pMbufTemp, char *);   /* get pointer to mbuf data */            /* ensure data is flushed */            CACHE_USER_FLUSH (m_data, pMbufTemp->m_len);#ifdef notdef	    /* This is what we should be able to do... */	    temp = (u_long) CACHE_DRV_VIRT_TO_PHYS (&cacheUserFuncs, m_data);#else	    temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (m_data);#endif            pTXD->frag [fragIndex].frag_ptr0 = (u_long) temp & UMASK;            pTXD->frag [fragIndex].frag_ptr1 = (u_long) temp >> 16;            pTXD->frag [fragIndex].frag_size = pMbufTemp->m_len;            fragIndex++;            }        pTXD->pkt_size   = adj_len;                    /* set packet length */        pTXD->frag_count = fragIndex;                  /* set fragment count */        if (adj_len != len)                            /* pad pkt size to min */            pTXD->frag [fragIndex-1].frag_size += (adj_len-len);        /* copy link field to where device will expect it */        pTXD->frag [fragIndex].frag_ptr0 =            (u_long) CACHE_DMA_VIRT_TO_PHYS (pTXD->pLink) | TX_EOL;#ifdef SN_DEBUG        if (SN_DEBUG_TX && SN_DEBUG_VERBOSE)            logMsg ("sn: Tx: pTXD=%x\n", (int)pTXD, 0, 0, 0, 0, 0);#endif /* SN_DEBUG */        /* Find previous desc in chain. (see NOTE #1)         * If prev desc has been used, then get a ptr to the actual         * link field within the desc, and clear the EOL bit.         */        {        TX_DESC *pPrevTXD;        u_long *pLink;        if (pTXD == pDrvCtrl->pTDA)            pPrevTXD = ((TX_DESC *)((char *)pDrvCtrl->pTDA + TDA_SIZE)) - 1;        else            pPrevTXD = pTXD - 1;        if (pPrevTXD->frag_count)            {            pLink = & pPrevTXD->frag [pPrevTXD->frag_count].frag_ptr0;            *pLink &= ~TX_EOL;            }        }                /* start the transmitter */        pDrvCtrl->pDev->cr = TXP;        /* And finally, adjust pointer to next TXD. */        pDrvCtrl->pTXDFree = pTXD->pLink;        }    }#else/********************************************************************************* snStartOutput - start pending output** This routine removes mbuf chains from the driver queue and attempts to* set up a SONIC transmit descriptor for each chain.  The transmit descriptors* are fed to the SONIC and subsequently transmitted onto the media.*/LOCAL void snStartOutput     (    DRV_CTRL * 	pDrvCtrl    )    {    MBUF           *pMbuf;    MBUF           *pMbufTemp;    TX_DESC        *pTXD;    int            len;    int            adj_len;    int            fragIndex;    int            nUseableFrags;    char           *mbuf_data;    u_long	   temp;    /* Loop as long as our incoming queue is not empty */    while (pDrvCtrl->sn_ac.ac_if.if_snd.ifq_head != NULL)        {        IF_DEQUEUE (&pDrvCtrl->sn_if.if_snd, pMbuf);        /* call output hook if any */        /* etherOutputHookRtn not supported.         * This would require copying mbufs to contiguous buf.         *  if ((etherOutputHookRtn != NULL) &&         *      (* etherOutputHookRtn) (&pDrvCtrl->sn_if, buf, len))         *      continue;         */        /* Calculate length  & number of fragments */#ifdef SN_DEBUG	if (SN_DEBUG_TRACE)	    {	    static char buf[ETHERMTU];	    struct ether_header *pPktHdr;        /* ptr to packet header */	    FAST char *p = buf;	    FAST struct mbuf *m = pMbuf;	    for (; m != NULL; p += m->m_len, m = m->m_next)		bcopy (mtod (m, char *), p, m->m_len);	    pPktHdr = (struct ether_header *)&buf;	    logMsg ("sn: Tx: 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	        pMbufTemp     = pMbuf;        len           =        nUseableFrags = 0;        while (pMbufTemp != NULL)            /* while valid pointer */            {            if (pMbufTemp->m_len)        /* only count non-zero length frags */                {                len += pMbufTemp->m_len;     /* add length of this fragment */                nUseableFrags++;             /* bump fragment counter */                }            pMbufTemp = pMbufTemp->m_next;   /* advance to next mbuf fragment */            }        /* Pull up the mbuf, if too many frags */        if (nUseableFrags >= MAX_TX_FRAGS)            {             pMbufTemp = pMbuf;             pMbuf = m_pullup (pMbufTemp, len);             m_freem (pMbufTemp);             if (pMbuf == NULL)                 continue;            }        /* See if next transmit descriptor is available */        pTXD = pDrvCtrl->pTXDFree;        if (pTXD->flag)                           /* still in use */            {            m_freem (pMbuf);                      /* packet is thrown away */            pDrvCtrl->sn_if.if_oerrors++;#ifdef SN_DEBUG            if (SN_DEBUG_TX)                logMsg ("sn: Tx, no descriptors", 0, 0, 0, 0, 0, 0);#endif /* SN_DEBUG */            break;            }        /* Mark this descriptor as "in use" */        pTXD->flag   = TRUE;        pTXD->status = 0;	/* remember the mbuf associated with this packet */	pTXD->pMbuf = pMbuf;        /* Ensure we send a minimum sized packet */        adj_len = max (ETHERSMALL, len);        /* Build a transmit descriptor.         * Loop thru each fragment in the mbuf chain and stuff our info.         */        fragIndex = 0;        for (pMbufTemp = pMbuf; pMbufTemp != NULL;              pMbufTemp = pMbufTemp->m_next)            {            /* ignore zero-length mbufs */            if ( pMbufTemp->m_len == 0 )                continue;            mbuf_data = mtod(pMbufTemp, char *); /* get pointer to mbuf data */            /* ensure data is flushed */            CACHE_USER_FLUSH (mbuf_data, pMbufTemp->m_len);#ifdef notdef	    /* This is what we should be able to do... */	    temp = (u_long) CACHE_DRV_VIRT_TO_PHYS (&cacheUserFuncs, mbuf_data);#else	    temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (mbuf_data);#endif            pTXD->frag [fragIndex].frag_ptr0 = (u_long) temp & UMASK;            pTXD->frag [fragIndex].frag_ptr1 = (u_long) temp >> 16;            pTXD->frag [fragIndex].frag_size = pMbufTemp->m_len;            fragIndex++;            }        pTXD->pkt_size   = adj_len;                    /* set packet length */        pTXD->frag_count = fragIndex;                  /* set fragment count */        if (adj_len != len)                            /* pad pkt size to min */            pTXD->frag [fragIndex-1].frag_size += (adj_len-len);        /* copy link field to where device will expect it */        pTXD->frag [fragIndex].frag_ptr0 =            (u_long) CACHE_DMA_VIRT_TO_PHYS (pTXD->pLink) | TX_EOL;#ifdef SN_DEBUG        if (SN_DEBUG_TX && SN_DEBUG_VERBOSE)            logMsg ("sn: Tx: pTXD=%x\n", (int)pTXD, 0, 0, 0, 0, 0);#endif /* SN_DEBUG */        /* Find previous desc in chain. (see NOTE #1)         * If prev desc has been used, then get a ptr to the actual         * link field within the desc, and clear the EOL bit.         */        {        TX_DESC *pPrevTXD;        u_long *pLink;        if (pTXD == pDrvCtrl->pTDA)            pPrevTXD = ((TX_DESC *)((char *)pDrvCtrl->pTDA + TDA_SIZE)) - 1;        else            pPrevTXD = pTXD - 1;        if (pPrevTXD->frag_count)            {            pLink = & pPrevTXD->frag [pPrevTXD->frag_count].frag_ptr0;            *pLink &= ~TX_EOL;            }        }        pDrvCtrl->sn_if.if_opackets++;        /* bump the statistic */        /* start the transmitter */        pDrvCtrl->pDev->cr = TXP;        /* And finally, adjust pointer to next TXD. */        pDrvCtrl->pTXDFree = pTXD->pLink;        }    }#endif    /* BSD43_DRIVER *//********************************************************************************* snTxReclaim - reclaims transmit descriptors that the device has serviced**/LOCAL void snTxReclaim (pDrvCtrl)    DRV_CTRL *pDrvCtrl;    {    TX_DESC *pTXD;    int unit;    unit = pDrvCtrl->sn_if.if_unit;                /* get our unit number */    pTXD = pDrvCtrl->pTXDReclaim;                  /* get ptr to desc */    CACHE_DMA_INVALIDATE (&pTXD->status, sizeof (u_long));    /* The device is deemed to be done with the descriptor if the     * the descriptor had been flagged as "given" to the device,     * and the descriptor status field is set.     */    while (pTXD->flag && pTXD->status)        {        if ( pTXD->status & PTX )            {            /* Packet was transmitted successfully.  Extract mbuf ptr and             * free the mbufs.             */            m_freem (pTXD->pMbuf);            /* done with the desc, so clean it up */            pTXD->flag    = FALSE;            pTXD->status  = 0;

⌨️ 快捷键说明

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