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

📄 if_ene.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 3 页
字号:
            pSoftc->eneStat.collisions += 16;            }        if (txStat & TSTAT_UNDER)            pSoftc->eneStat.underruns++;        }    if ( (intStat & ISTAT_PTX) != 0)    /* Transmit-packet sent */        {        if (txStat & TSTAT_CDH)            pSoftc->eneStat.heartbeats++;        if (txStat & TSTAT_OWC)            pSoftc->eneStat.outofwindow++;        if (txStat & TSTAT_PTX)            pSoftc->eneStat.tnoerror++;        }    if ( (intStat & (ISTAT_TXE | ISTAT_PTX)) != 0) /* Transmit complete */        if (pSoftc->es_if.if_snd.ifq_head != NULL)#ifdef BSD43_DRIVER            (void) netJobAdd ((FUNCPTR)enePut, unit, 0,0,0,0);#else            (void) netJobAdd ((FUNCPTR)enePut, (int)pSoftc, 0,0,0,0);#endif    }/********************************************************************************* eneGet - read a packet off the interface** Copy packets from the buffer ring into mbufs and hand them to the next* higher layer.*/static void eneGet     (    int unit    )    {    FAST ENE_SOFTC * pSoftc = pEneSoftc [unit];    FAST struct ether_header * eh;    FAST MBUF * m;#ifdef BSD43_DRIVER    int         off;#endif    UINT        packetSize;    UCHAR *     pData;    static UCHAR uppByteCnt;    UINT8       tempPage;               /* used in buffer validation */    UINT8       pageCount;              /* used in buffer validation */    ENE_HEADER  h;unlucky:    while (TRUE)        {        if (pSoftc->nextPacket == pSoftc->current)            break;                      /* done all complete frames */        eneDataIn (unit, (((UINT)pSoftc->nextPacket << 8) & 0x0000ffff),                   sizeof (ENE_HEADER), (char *) &h);#ifdef ENE_DEBUGprintf ("ene: Get: next=%02x, uppByteCnt=%02x, lowByteCnt=%02x\n",        h.next, h.uppByteCnt, h.lowByteCnt);#endif        /* Calculate upper byte count in case it's corrupted,         * though this supposedly happens only in StarLAN applications         * with bus clock frequence greater than 4 mHz.         */        if (h.next > pSoftc->nextPacket)            uppByteCnt = h.next - pSoftc->nextPacket;        else            uppByteCnt = (NE2000_PSTOP - pSoftc->nextPacket) +                         (h.next - NE2000_PSTART);        if (h.lowByteCnt > 0xfc)            uppByteCnt -= 2;        else            uppByteCnt -= 1;        h.uppByteCnt = uppByteCnt;        /* compute packet size excluding Ethernet checksum bytes */        packetSize = ( ( (UINT)h.uppByteCnt << 8) + h.lowByteCnt) - 4;        /* Check for packet (and header) shifted in memory (by heavy load).         * The method and solution are recommended by 3Com in their         * EtherLink II Adapter Technical Manual, with the addition of         * a reasonableness check on the next-page link.         */        pageCount = (packetSize + 4 + sizeof (ENE_HEADER) + (ENE_PAGESIZE - 1))                    / ENE_PAGESIZE;        tempPage = pSoftc->nextPacket + pageCount;        if (tempPage >= NE2000_PSTOP)            tempPage -= (NE2000_PSTOP - NE2000_PSTART);        if ((h.next != tempPage) ||            (h.next < NE2000_PSTART) || (h.next >= NE2000_PSTOP))            {            pSoftc->eneStat.badPacket++; /* can't trust anything now */            pSoftc->eneStat.rerror++;            eneInit (unit);             /* stop and restart the interface */            pSoftc->flags &= ~RXING;            eneIntEnable (unit);            return;            }        /* reject runts, although we are configured to reject them */        if (packetSize < 60)            {            pSoftc->eneStat.shortPacket++;            goto doneGet;            }        /* reject packets larger than our scratch buffer */        if (packetSize > MAX_FRAME_SIZE)            goto doneGet;        if (h.rstat & RSTAT_PRX)            {            /* 3Com says this status marks a packet bit-shifted in memory;             * the data cannot be trusted but the NIC header is OK.             */            if ( (h.rstat & (RSTAT_DFR | RSTAT_DIS)) != 0)                {                pSoftc->eneStat.badPacket++;                pSoftc->eneStat.rerror++;                goto doneGet;                }            pSoftc->eneStat.rnoerror++;            }        else            {            if ( (h.rstat & RSTAT_DFR) != 0)                pSoftc->eneStat.jabber++;            pSoftc->eneStat.rerror++;            goto doneGet;            }        /* copy separated frame to a temporary buffer */        eneDataIn (unit,                   ((UINT)pSoftc->nextPacket << 8) + sizeof (ENE_HEADER),                   packetSize,                   pSoftc->packetBuf);        eh = (struct ether_header *)(pSoftc->packetBuf);        pSoftc->es_if.if_ipackets++;        /* bump statistic. */        /* call input hook if any */        if ((etherInputHookRtn != NULL) &&            (* etherInputHookRtn) (&pSoftc->es_if, (char *) eh, packetSize))            {            goto doneGet;            }        if (packetSize >= SIZEOF_ETHERHEADER)            packetSize -= SIZEOF_ETHERHEADER;        else            goto doneGet;        pData = ((unsigned char *) eh) + SIZEOF_ETHERHEADER;#ifdef BSD43_DRIVER        check_trailer (eh, pData, (int *) &packetSize, &off, &pSoftc->es_if);        /* copy data from the scratch buffer to mbuf a long-word at a time */        m = bcopy_to_mbufs (pData, packetSize, off,                            (IFNET *) &pSoftc->es_if, 2);        if (m == NULL)            {            pSoftc->es_if.if_ierrors++;         /* bump error statistic. */            goto doneGet;            }        do_protocol_with_type (eh->ether_type, m, &pSoftc->es_ac, packetSize);#else        m = bcopy_to_mbufs (pData, packetSize, 0, (IFNET *)&pSoftc->es_if, 2);        if (m == NULL)            {            pSoftc->es_if.if_ierrors++;         /* bump error statistic. */            goto doneGet;            }        do_protocol (eh, m, &pSoftc->es_ac, packetSize);#endifdoneGet:        pSoftc->nextPacket = h.next;        sysOutByte (ENE_BOUND (pSoftc->eneAddr),                    (pSoftc->nextPacket != NE2000_PSTART ?                     pSoftc->nextPacket - 1 : NE2000_PSTOP - 1));        }    pSoftc->flags &= ~RXING;    /* go back if we received an interrupt and a new packet */    if (pSoftc->nextPacket != pSoftc->current)        goto unlucky;    }#ifdef BSD43_DRIVER/********************************************************************************* eneoutput - ethernet output routine** Encapsulate a packet of type family for the local net.* Use trailer local net encapsulation if enough data in first* packet leaves a multiple of 512 bytes of data in remainder.* If destination is this address or broadcast, send packet to* loop device to kludge around the fact that 3com interfaces can't* talk to themselves.** RETURNS: ?*/static int eneoutput     (    IFNET * ifp,    MBUF * m0,    SOCK * dst     )    {    return (ether_output (ifp, m0, dst, (FUNCPTR)enePut,                          & pEneSoftc [ifp->if_unit]->es_ac));    }#endif/********************************************************************************* enePut - copy a packet to the interface.** Copy from mbuf chain to transmitter buffer in shared memory.**/#ifdef BSD43_DRIVERstatic void enePut     (    int unit    )    {    FAST ENE_SOFTC * pSoftc   = pEneSoftc [unit];#elsestatic void enePut     (    ENE_SOFTC * pSoftc    )    {    int unit = pSoftc->es_if.if_unit;#endif    FAST MBUF * m;    FAST int len;    long qdtimer;        int s = splnet ();    if (pSoftc->es_if.if_snd.ifq_head != NULL)        {        qdtimer = 10000L;        while ( ( (sysInByte (ENE_CMD (pSoftc->eneAddr)) & CMD_TXP) != 0)               && (--qdtimer > 0))            ;        if (qdtimer == 0)            eneInit (unit);        IF_DEQUEUE (&pSoftc->es_if.if_snd, m);        /* we assume no packet will be larger than MAX_FRAME_SIZE,         * based on our advertised MTU.         */        copy_from_mbufs (pSoftc->packetBuf, m, len);        len = max (ETHERSMALL, len);        /* call output hook if there is one, else send the packet */        if ( (etherOutputHookRtn != NULL) &&             (* etherOutputHookRtn) (&pSoftc->es_if, pSoftc->packetBuf, len))            {            }        else            {            /* put packet in board's output buffer */            eneDataOut (unit, pSoftc->packetBuf, len, (NE2000_TSTART << 8));            /* kick Transmitter */            sysOutByte (ENE_INTMASK (pSoftc->eneAddr), 0x00);            sysOutByte (ENE_TSTART (pSoftc->eneAddr), NE2000_TSTART);            sysOutByte (ENE_TCNTH (pSoftc->eneAddr), len >> 8);            sysOutByte (ENE_TCNTL (pSoftc->eneAddr), len & 0xff);            sysOutByte (ENE_CMD (pSoftc->eneAddr), CMD_TXP);            eneIntEnable (unit);            }        }    splx (s);    }/********************************************************************************* eneBoardReset - reset the whole board** The NE2000 has an I/O port dedicated to hardware reset; you READ the port* to initiate the reset then WRITE 0 to the port.*/static void eneBoardReset    (    int unit    )    {    FAST ENE_SOFTC * pSoftc   = pEneSoftc [unit];    (void) sysInByte (ENE_RESET (pSoftc->eneAddr));    taskDelay (sysClkRateGet () >> 1);    sysOutByte (ENE_RESET (pSoftc->eneAddr), 0x00);    taskDelay (sysClkRateGet () >> 1);    sysOutByte (ENE_CMD (pSoftc->eneAddr), CMD_NODMA | CMD_PAGE0 | CMD_STOP);    while ((sysInByte (ENE_INTSTAT (pSoftc->eneAddr)) & ISTAT_RST) != ISTAT_RST)        ;    }/********************************************************************************* eneReset - reset the chip** Reset the chip.**/static void eneReset     (    int unit    )    {    FAST ENE_SOFTC * pSoftc   = pEneSoftc [unit];    int s = splnet ();    /* mask interrupt */    sysOutByte (ENE_INTMASK (pSoftc->eneAddr), 0x00);    eneInit (unit);    eneIntEnable (unit);    pSoftc->eneStat.reset++;    splx (s);    }/********************************************************************************* eneioctl - ioctl for interface** RETURNS: ?*/static int eneioctl     (    FAST IFNET * ifp,    int cmd,    caddr_t data     )    {    int unit;    ENE_SOFTC * pSoftc;    int error = 0;    int s;    unit = ifp->if_unit;    pSoftc = pEneSoftc [unit];    s = splimp();    switch (cmd)        {        case SIOCSIFADDR:            ((struct arpcom *)ifp)->ac_ipaddr = IA_SIN (data)->sin_addr;            arpwhohas (ifp, &IA_SIN (data)->sin_addr);            break;        case SIOCSIFFLAGS:            /* Set promiscuous mode according to current interface flags */            pSoftc->rxFilter = ( (ifp->if_flags & IFF_PROMISC) != 0) ?                                   RCON_BROAD | RCON_PROM : RCON_BROAD;            sysOutByte (ENE_RCON (pSoftc->eneAddr), pSoftc->rxFilter);            break;        default:            error = EINVAL;        }    splx (s);    return (error);    }/********************************************************************************* eneInit - initialize SMC8390 ENE (Ethernet LAN Controller)** RETURNS: N/A** NOMANUAL*/static void eneInit     (    int unit    )    {    FAST ENE_SOFTC * pSoftc          = pEneSoftc [unit];    UCHAR * pAddr               = (UCHAR *)pSoftc->es_enaddr;    /* 1. program Command Register for page 0 and for no DMA */    sysOutByte (ENE_CMD (pSoftc->eneAddr), CMD_NODMA | CMD_PAGE0 | CMD_STOP);

⌨️ 快捷键说明

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