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

📄 if_egl.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    ether_attach (                 &egl->egl_if,                  unit,                  "egl",                  egl_init,                  egl_ioctl,                 ether_output,                  egl_reset);    egl->egl_if.if_start = (FUNCPTR)egl_start;#endif    egl->egl_if.if_mtu = ETHERMTU - 4;  /* MTU = 1496 for block bug */    (void)intConnect (INUM_TO_IVEC (ivec+0), egl_intr, unit);    /* XXX temporarily while R3K targets don't do vectored VME interrupts */#if     CPU_FAMILY!=MIPS    (void)intConnect (INUM_TO_IVEC (ivec+1), egl_intr, unit);    (void)intConnect (INUM_TO_IVEC (ivec+2), egl_intr, unit);    (void)intConnect (INUM_TO_IVEC (ivec+3), egl_intr, unit);    (void)intConnect (INUM_TO_IVEC (ivec+4), egl_intr, unit);#endif  /* CPU_FAMILY!=MIPS */    sysIntEnable (ilevel);    if (egl_init (unit) != 0)        return (ERROR);    return (OK);    }/********************************************************************************* egl_config - configure the Eagle to default settings** RETURNS: 0 or -1 on error.*/LOCAL int egl_config    (    int unit,    int itype    )    {    EGL_SOFTC *egl         = egl_softc [unit];    volatile SHIO *shio    = egl->eglAddr;    volatile CIB *cib      = (CIB *)&shio->sh_SCRTCH[0]; /* scratch area */    volatile IC_IOPB *iopb = (IC_IOPB *)&shio->sh_MCE_IOPB;    int status             = 0;    int ix;    /* Controller Initialization Block */    cib->cib_RES0 = 0;    cib->cib_NCQE = NUM_CQE;    cib->cib_IMOD = (USHORT)M_IMOD_PE;  /* Ethernet */    cib->cib_NTXR = EGL_TX_NRINGS;      /* LANCE Tx Rings */    cib->cib_NRXR = EGL_RX_NRINGS;      /* LANCE Rx Rings */    /* default Physical Address */    bcopy ((char*)egl->egl_cstb.cstb_PHY, (char*)cib->cib_PHY,          sizeof(egl->egl_cstb.cstb_PHY));    /* default Logical Address Filter */    bcopy ((char*)egl->egl_cstb.cstb_FILT, (char*)cib->cib_FILT,          sizeof (egl->egl_cstb.cstb_FILT));    cib->cib_RXSIZ = EGL_RX_BUFSZ;      /* Max Rx Packet */    cib->cib_NRBUF = EGL_RX_NRINGS;     /* Num Rx Buffers */    cib->cib_TXSIZ = EGL_TX_BUFSZ;      /* Max Tx Packet */    cib->cib_NIBUF = EGL_TX_NRINGS;     /* Num Tx Buffers */    cib->cib_NHBUF = EGL_NHBUF;         /* Num Host Buffers */    cib->cib_NVECT = egl->qav_vec;      /* needed for error handling */    cib->cib_EVECT = egl->qav_vec;      /* needed for error handling */    cib->cib_BURST = EGL_BURST;         /* DMA Burst Count */    bzero ((char*)cib->cib_RES1, sizeof(cib->cib_RES1));    /* MCE IOPB */    iopb->ic_iopb_CMD    = CNTR_INIT;    /* XXX big-endian or quad alignment? */    iopb->ic_iopb_OPTION = M_OPT_SG | itype;     /* 0 no int; 1 int */    iopb->ic_iopb_NVCT   = egl->qav_vec;    iopb->ic_iopb_EVCT   = egl->qav_vec;    iopb->ic_iopb_RES0   = 0;    iopb->ic_iopb_BUFF   = (ULONG)cib - (ULONG)shio;/* CIB offset from shio */    bzero ((char*)iopb->ic_iopb_RES1, sizeof(iopb->ic_iopb_RES1));    shio->sh_MCE.cqe_CTAG       = 0;    shio->sh_MCE.cqe_IOPB_ADDR  = O_MCE_IOPB;    shio->sh_MCE.cqe_WORK_QUEUE = 0;    CQE_GO(shio->sh_MCE.cqe_QECR);    if (!itype)        {        ix = egl_wait (&shio->sh_CRB);        if (CRB_ERROR(ix))            {#ifdef EGL_DEBUG            logMsg ("egl%d: *error* unable to configure interface\n",                    unit, 0, 0, 0, 0, 0);            if (iopb->ic_iopb_STATUS)                logMsg ("iopb error status = %#x\n",                        iopb->ic_iopb_STATUS, 0, 0, 0, 0, 0);#endif            status = -1;            }        else if (ix == 0x1000)            {#ifdef EGL_DEBUG            logMsg ("egl%d: *timeout* unable to configure interface\n",                    unit, 0, 0, 0, 0, 0);#endif            status = -1;            }        }    return (status);    }/********************************************************************************* egl_hangrcv - place a receive request for the specified iobp** RETURNS: 1 or 0.*/LOCAL int egl_hangrcv    (    int unit,    int index    )    {    ETH_BUF *eth_buf;    volatile IOPB *iopb;    EGL_SOFTC *egl      = egl_softc [unit];    volatile SHIO *shio = egl->eglAddr;    volatile CQE *cqe   = egl->egl_cqe;    if (egl->egl_qfull != 0)        {#ifdef EGL_DEBUG        logMsg ("egl%d: egl_hangrcv - packet queue full\n", unit, 0, 0, 0, 0,0);#endif  /* EGL_DEBUG */        return (0);        }    /* place a receive request */    if (CQE_BUSY(cqe->cqe_QECR))        {        egl->egl_qfull++;       /* feed queue full */        return (0);        }    if ((eth_buf = egl->egl_rbinfo[index]) == NULL)        GET_ETH_BUF(eth_buf);    iopb                   = eth_buf->iopb;    iopb->iopb_BUFF        = eth_buf->eth_dat_adr;    eth_buf->eth_len       = EGL_MTU;    egl->egl_rbinfo[index] = eth_buf;    egl_ioflush (eth_buf);    cqe->cqe_CTAG          = index;    cqe->cqe_IOPB_ADDR     = (caddr_t)iopb - (caddr_t)shio;    cqe->cqe_WORK_QUEUE    = EGL_RECVQ;    CQE_GO(cqe->cqe_QECR);    if (++egl->egl_cqe == &shio->sh_CQE[MAX_CQE])        egl->egl_cqe = (CQE *)&shio->sh_CQE[0];    return (1);    }/********************************************************************************* egl_init - initialization of interface; clear pending operations** RETURNS: 0 or -1.*/LOCAL int egl_init    (    int unit    )    {    EGL_SOFTC *egl      = egl_softc [unit];    volatile SHIO *shio = egl->eglAddr;    volatile CRB *crb   = &shio->sh_CRB;    struct ifnet *ifp   = &egl->egl_if;    int s;    int ix;    ifp->if_flags &= ~(IFF_UP|IFF_RUNNING);    s = splimp ();    if (egl_reset (unit) == -1)        {        splx (s);        return (-1);        }    /* LANCE is turned OFF now */    if (egl_config (unit, NOINT) == -1)        {        splx (s);        return (-1);        }    /* LANCE is turned ON now */    egl_setiopbs (unit);                        /* setup iopbs */    egl->egl_qmode = 0;                         /* not queue mode */    /* start up queue mode */    if (egl_iworkq (unit, NOINT) == -1)        {        splx (s);#ifdef EGL_DEBUG        logMsg ("egl%d: egl_init - failed\n", 0, 0, 0, 0, 0, 0);#endif        return (-1);        }    for (ix = 0; ix < 10000; ix++)        {        if (CRB_QSTARTED(crb->crb_CRSW))            break;        DELAY(500);        }    if (!CRB_QSTARTED(crb->crb_CRSW))        {#ifdef EGL_DEBUG        logMsg ("egl%d: failed to start Q-Mode\n", unit, 0, 0, 0, 0, 0);#endif        splx (s);        return (-1);        }    egl->egl_qmode++;    CRB_CLR_DONE(crb->crb_CRSW);        /* release Eagle */    /* initial hang receive requests */    for (ix = 0; ix < EGL_RX_NBUFF; ix++)        {        if (egl_hangrcv (unit, ix) == 0)            break;        }    egl->egl_if.if_flags |= IFF_UP | IFF_RUNNING;#ifdef BSD43_DRIVER    egl_start (unit);                   /* start transmits */#else    egl_start (egl);#endif    splx (s);    return (0);    }/********************************************************************************* egl_intr - read vector and dispatch to routine handler*/LOCAL void egl_intr    (    int unit    )    {#ifdef EGL_DEBUG    static char message [150];    char *nullmsg       = "";#endif    EGL_SOFTC *egl      = egl_softc [unit];    volatile SHIO *shio = egl->eglAddr;    volatile CRB *crb   = &shio->sh_CRB;    volatile CSB *csb   = &shio->sh_CSB;    volatile IOPB tiopb;    int real_errors;    int vector;    int index;    int len;    /* ack interrupt, read vector */    vector = sysBusIntAck (egl->eglIntLevel) & 0x00ff;    /* XXX temporarily while R3K targets don't do vectored VME interrupts */    if (vector != (shio->sh_VMEIV & 0x00ff))        {#ifdef EGL_DEBUG        logMsg ("egl%d: vectors disagree: sysBusIntAck = %#x, CSB-vec = %#x\n",                unit, vector, shio->sh_VMEIV & 0x00ff, 0, 0, 0);#endif  /* EGL_DEBUG */        vector = shio->sh_VMEIV & 0x00ff;        }    switch (vector - egl->eglIntVec)        {        case 0: /* xmit */            if (shio->sh_RET_IOPB.iopb_LAN1 & (LANCE_TONE | LANCE_TMORE))                egl->egl_if.if_collisions++;            index = crb->crb_CTAG;            CRB_CLR_DONE(crb->crb_CRSW);        /* release Eagle */            netJobAdd ((FUNCPTR)egl_tint, unit, (int)egl, index, 0, 0);            break;        case 1: /* xmiterr */            tiopb = shio->sh_RET_IOPB;            if (tiopb.iopb_LAN1 & LANCE_TERR)                {#ifdef EGL_DEBUG                sprintf (message,                    "egl%d: transmit error LAN1=%#x LAN3=%#x %s%s%s%s%s\n",                    unit, tiopb.iopb_LAN1, tiopb.iopb_LAN3,                    ((tiopb.iopb_LAN3&LAN3_BUFF) ? "buffer error "   : nullmsg),                    ((tiopb.iopb_LAN3&LAN3_UFLO) ? "underflow "      : nullmsg),                    ((tiopb.iopb_LAN3&LAN3_LCOL) ? "late collision " : nullmsg),                    ((tiopb.iopb_LAN3&LAN3_LCAR) ? "carrier loss "   : nullmsg),                    ((tiopb.iopb_LAN3&LAN3_RTRY) ? "retry error"     : nullmsg));                logMsg (message, 0, 0, 0, 0, 0, 0);#endif                }            else if (tiopb.iopb_STATUS)                {#ifdef EGL_DEBUG                logMsg ("egl%d: transmit error status %#x\n",                        unit, tiopb.iopb_STATUS, 0, 0, 0, 0);#endif                }            index = crb->crb_CTAG;            CRB_CLR_DONE(crb->crb_CRSW);        /* release Eagle */            egl->egl_if.if_oerrors++;            egl->egl_if.if_opackets--;            netJobAdd ((FUNCPTR)egl_tint, unit, (int)egl, index, 0, 0);            break;        case 2: /* rcv */            len = shio->sh_RET_IOPB.iopb_LENGTH;/* length of recv packet */            index = crb->crb_CTAG;            CRB_CLR_DONE(crb->crb_CRSW);        /* release Eagle */            netJobAdd ((FUNCPTR)egl_rint, unit, (int)egl, index, len, 0);            break;        case 3: /* rcverr */            len = shio->sh_RET_IOPB.iopb_LENGTH;   /* length of recv packet */            index = crb->crb_CTAG;            tiopb = shio->sh_RET_IOPB;            if (tiopb.iopb_LAN1 & LANCE_RERR)                {                /* First, check for bogus LANCE errors:                 * call normal completion code if no "real" errors.                 */                real_errors = tiopb.iopb_LAN1;                if ((tiopb.iopb_LAN1&LAN1_OFLO) && (tiopb.iopb_LAN1&LANCE_RENP))                    real_errors ^= LAN1_OFLO;   /* turn off bogus OFLO */                if (!(tiopb.iopb_LAN1&LANCE_RENP)|| (tiopb.iopb_LAN1&LAN1_OFLO))                    real_errors &= (0xffff - (LAN1_FRAM | LAN1_CRC));                if (!(real_errors & (LAN1_FRAM|LAN1_OFLO|LAN1_CRC|LAN1_BUFF)))                    {                    /* Error was bogus.  Treat like normal receive int.  */                    CRB_CLR_DONE(crb->crb_CRSW);        /* release Eagle */                    netJobAdd ((FUNCPTR)egl_rint, unit, (int)egl, index, len,0);                    return;                    }                /* looks like a real receive error */#ifdef EGL_DEBUG                sprintf (message,                        "egl%d: receive error LAN1=%#x LAN3=%#x %s%s%s%s\n",                        unit, tiopb.iopb_LAN1, tiopb.iopb_LAN3,                        (real_errors&LAN1_FRAM) ? "framing error " : nullmsg,                        (real_errors&LAN1_OFLO) ? "overflow "      : nullmsg,                        (real_errors&LAN1_CRC)  ? "CRC error "     : nullmsg,                        (real_errors&LAN1_BUFF) ? "buffer error"   : nullmsg);#endif                if ((++egl->egl_if.if_ierrors % 100) == 0)                    {                    /* Interphase Inc. only reports every 100 errors;                     * we seem to get a fair number of CRC errors but                     * probably they're bogus.                     */#ifdef EGL_DEBUG                    logMsg (message, 0, 0, 0, 0, 0, 0);#endif                    }                }            else if (tiopb.iopb_STATUS)                {                /* only interesting if non RERR */#ifdef EGL_DEBUG                logMsg ("egl%d: receive error status %#x\n",                        unit, tiopb.iopb_STATUS, 0, 0, 0, 0);                /* valid only if no RERR */                if (!tiopb.iopb_LENGTH)                    logMsg ("egl%d: 0 length receive\n", unit, 0, 0, 0, 0, 0);#endif                }            if (csb->csb_CSR0MISS > egl->egl_csr0miss)                {                /* any new ones? */                egl->egl_csr0miss = csb->csb_CSR0MISS;#ifdef EGL_DEBUG                logMsg ("egl%d: csr0 missed receive packet, count = %d\n",                        unit, egl->egl_csr0miss, 0, 0, 0, 0);#endif                }            CRB_CLR_DONE(crb->crb_CRSW);        /* release Eagle */            egl->egl_if.if_ierrors++;            netJobAdd ((FUNCPTR)egl_rint, unit, (int)egl, index, -1, 0);            break;        case 4: /* qav */            netJobAdd ((FUNCPTR)egl_qint, unit, (int)egl, 0, 0, 0);            break;        default:#ifdef EGL_DEBUG            logMsg (            "egl%d: egl_intr - unknown interrupt vector %#x\n",            unit, vector, 0, 0, 0, 0);#endif            break;        }    }/********************************************************************************* egl_ioctl - process an ioctl request** RETURNS: 0 or errno.*/LOCAL int egl_ioctl    (    struct ifnet *ifp,    int cmd,    caddr_t data    )    {    int unit       = ifp->if_unit;    EGL_SOFTC *egl = egl_softc [unit];    int error      = 0;    int status;    int s;    s = splimp ();    switch (cmd)        {        case SIOCSIFADDR:       /* Set */            ((struct arpcom *)ifp)->ac_ipaddr = IA_SIN (data)->sin_addr;            arpwhohas (ifp, &IA_SIN (data)->sin_addr);            break;        case SIOCGIFADDR:       /* Get */            bcopy ((char*)egl->egl_enaddr,                  (caddr_t) ((struct ifreq *)data)->ifr_addr.sa_data, 6);#ifdef  EGL_DEBUG            printf ("egl%d: egl_ioctl - SIOCGIFADDR\n", unit);#endif  /* EGL_DEBUG */            break;        case SIOCGIFFLAGS:      /* Get */            *(short *)data = ifp->if_flags;#ifdef EGL_DEBUG            printf ("egl%d: egl_ioctl - SIOCGIFFLAGS\n", unit);

⌨️ 快捷键说明

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