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

📄 if_egl.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 4 页
字号:
#endif  /* EGL_DEBUG */            break;        case SIOCSIFFLAGS:      /* Set */            /* Handled outside module - nothing more to do. */            break;        default:#ifdef EGL_DEBUG            printf ("egl%d: egl_ioctl - unknown ioctl\n", unit);#endif  /* EGL_DEBUG */            error = EINVAL;            break;        }    splx (s);    return (error);    }/********************************************************************************* egl_iworkq - initialize work queues** RETURNS: 0 or -1 on error.*/LOCAL int egl_iworkq    (    int unit,    int itype    )    {    EGL_SOFTC *egl       = egl_softc [unit];    volatile SHIO *shio  = egl->eglAddr;    volatile WQCF *iopb  = (WQCF *)&shio->sh_MCE_IOPB;    volatile USHORT *mcr = &shio->sh_MCSB.mcsb_MCR;    int ix;    iopb->wqcf_CMD      = CNTR_INIT_WORKQ;    iopb->wqcf_OPTION  |= itype;        /* 0 no int; 1 int (M_OPT_IE) */    iopb->wqcf_NVCT     = egl->qav_vec;    iopb->wqcf_EVCT     = egl->qav_vec;    bzero ((char*)iopb->wqcf_RES0, sizeof(iopb->wqcf_RES0));    iopb->wqcf_WORKQ    = EGL_MISCQ;            /* misc queue */    iopb->wqcf_WOPT     = 0;    iopb->wqcf_SLOTS    = EGL_MS_SLOTS;         /* misc queue size */    iopb->wqcf_PRIORITY = EGL_MS_PRIORITY;      /* misc queue priority */    iopb->wqcf_WDIV     = EGL_MS_WDIV;          /* misc queue work division */    bzero ((char*)iopb->wqcf_RES1, sizeof(iopb->wqcf_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 initialize misc workq\n",                    unit, 0, 0, 0, 0, 0);#endif            return (-1);            }        else if (ix == 0x1000) /* unused value */            {#ifdef EGL_DEBUG            logMsg ("egl%d: *timeout* unable to initialize misc workq\n",                    unit, 0, 0, 0, 0, 0);#endif            return (-1);            }        }    else        {#ifdef EGL_DEBUG        logMsg ("egl%d: initialize misc workq done\n",                unit, 0, 0, 0, 0, 0);#endif  /* EGL_DEBUG */        }    /* DMA MCE IOPB */    iopb->wqcf_CMD = CNTR_INIT_WORKQ;    iopb->wqcf_OPTION |= itype;     /* 0 no int; 1 int (M_OPT_IE) */    iopb->wqcf_NVCT = egl->qav_vec;    iopb->wqcf_EVCT = egl->qav_vec;    bzero ((char*)iopb->wqcf_RES0, sizeof(iopb->wqcf_RES0));    iopb->wqcf_WORKQ    = EGL_DMAQ;             /* misc queue */    iopb->wqcf_WOPT     = 0;    iopb->wqcf_SLOTS    = EGL_DM_SLOTS; /* misc queue size */    iopb->wqcf_PRIORITY = EGL_DM_PRIORITY;      /* misc queue priority */    iopb->wqcf_WDIV     = EGL_DM_WDIV;          /* misc queue work division */    bzero ((char*)iopb->wqcf_RES1, sizeof(iopb->wqcf_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 initialize DMA workq\n",                    unit, 0, 0, 0, 0, 0);#endif            return (-1);            }        else if (ix == 0x1000) /* unused value */            {#ifdef EGL_DEBUG            logMsg ("egl%d: *timeout* unable to initialize DMA workq\n",                    unit, 0, 0, 0, 0, 0);#endif            return (-1);            }        }    else        {#ifdef EGL_DEBUG        logMsg ("egl%d: initialize DMA workq done\n",                unit, 0, 0, 0, 0, 0);#endif  /* EGL_DEBUG */        }    /* receive MCE IOPB */    iopb->wqcf_CMD     = CNTR_INIT_WORKQ;    iopb->wqcf_OPTION |= itype;     /* 0 no int; 1 int (M_OPT_IE) */    iopb->wqcf_NVCT    = egl->qav_vec;    iopb->wqcf_EVCT    = egl->qav_vec;    bzero ((char*)iopb->wqcf_RES0, sizeof(iopb->wqcf_RES0));    iopb->wqcf_WORKQ    = EGL_RECVQ;            /* receive queue */    iopb->wqcf_WOPT     = 0;    iopb->wqcf_SLOTS    = EGL_RX_SLOTS;         /* receive queue size */    iopb->wqcf_PRIORITY = EGL_RX_PRIORITY;      /* receive queue priority */    iopb->wqcf_WDIV     = EGL_RX_WDIV;          /* receive q work division */    bzero ((char*)iopb->wqcf_RES1, sizeof(iopb->wqcf_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 initialize receive workq\n",                    unit, 0, 0, 0, 0, 0);#endif            return (-1);            }        else if (ix == 0x1000) /* unused value */            {#ifdef EGL_DEBUG            logMsg ("egl%d: *timeout* unable to initialize receive workq\n",                    unit, 0, 0, 0, 0, 0);#endif            return (-1);            }        }    else        {#ifdef EGL_DEBUG        logMsg ("egl%d: initialize receive workq done\n",                unit, 0, 0, 0, 0, 0);#endif  /* EGL_DEBUG */        }    /* transmit MCE IOPB */    iopb->wqcf_CMD     = CNTR_INIT_WORKQ;    iopb->wqcf_OPTION |= itype;     /* 0 no int; 1 int (M_OPT_IE) */    iopb->wqcf_NVCT    = egl->qav_vec;    iopb->wqcf_EVCT    = egl->qav_vec;    bzero ((char*)iopb->wqcf_RES0, sizeof(iopb->wqcf_RES0));    iopb->wqcf_WORKQ    = EGL_XMTQN(0);         /* transmit queue 0 */    iopb->wqcf_WOPT     = 0;    iopb->wqcf_SLOTS    = EGL_TX_SLOTS;         /* transmit queue size */    iopb->wqcf_PRIORITY = EGL_TX_PRIORITY;      /* transmit queue priority */    iopb->wqcf_WDIV     = EGL_TX_WDIV;          /* transmit q work division */    bzero ((char*)iopb->wqcf_RES1, sizeof(iopb->wqcf_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 initialize transmit workq\n",                    unit, 0, 0, 0, 0, 0);#endif            return (-1);            }        else if (ix == 0x1000) /* unused value */            {#ifdef EGL_DEBUG            logMsg ("egl%d: *timeout* unable to initialize transmit workq\n",                    unit, 0, 0, 0, 0, 0);#endif            return (-1);            }        }    else        {#ifdef EGL_DEBUG        logMsg ("egl%d: initialize transmit workq done\n",                unit, 0, 0, 0, 0, 0);#endif  /* EGL_DEBUG */        }    *mcr |= M_MCR_SQM;  /* start queue mode */    sysWbFlush();    return (0);    }#ifdef BSD43_DRIVER/********************************************************************************* egl_output - Ethernet output routine** RETURNS: ?*/LOCAL int egl_output    (    struct ifnet *ifp,    struct mbuf *m0,    struct sockaddr *dst    )    {    return (ether_output (ifp, m0, dst, (FUNCPTR) egl_start,                         &egl_softc [ifp->if_unit]->egl_ac));    }#endif/********************************************************************************* egl_physreset - physical reset of the Interphase Eagle card** RETURNS: 0 or -1 if reset or diagnostics fail.*/LOCAL STATUS egl_physreset    (    int unit    )    {    EGL_SOFTC *egl       = egl_softc [unit];    volatile SHIO *shio  = egl->eglAddr;    volatile USHORT *msr = &shio->sh_MCSB.mcsb_MSR;    volatile USHORT *mcr = &shio->sh_MCSB.mcsb_MCR;    int ix;#ifdef EGL_DEBUG    printf ("egl%d: egl_physreset - msr address = %#x\n", unit, msr);#endif  /* EGL_DEBUG */    for (ix = 0; ix < 1000; ix++)        {        if (!(*msr & M_MSR_CNA) && (*msr & M_MSR_BOK))            break;        DELAY(8000);        }    if (ix == 1000)        {#ifdef EGL_DEBUG        printf (        "egl%d: diagnostics failed, or controller not available; msr = %#x\n",                unit, *msr);#endif        return (-1);        }    *msr |= M_MSR_CNA;    sysWbFlush();    *mcr = M_MCR_RES;   /* reset the Eagle */    sysWbFlush();    DELAY(500);         /* at least 50usec required */    *mcr &= ~M_MCR_RES;    sysWbFlush();    for (ix = 0; ix < 1000; ix++)        {        if (!(*msr & M_MSR_CNA))            break;        DELAY(8000);        }    if (ix == 1000)        {#ifdef EGL_DEBUG        printf ("egl%d: diagnostics failed during phase 1; msr = %#x\n",                unit, *msr);#endif        return (-1);        }    /* more delay necessary as reset is not yet done! (Interphase bug) */    for (ix = 0; ix < 1000; ix++)        {        if (*msr & M_MSR_BOK)            break;        DELAY(8000);        }    if (ix == 1000)        {#ifdef EGL_DEBUG        printf ("egl%d: diagnostics failed during phase 2; msr = %#x\n",                unit, *msr);#endif        *msr |= M_MSR_BOK; /* re-set board OK (iphase bug) */        return (-1);        }    return (0);    }/********************************************************************************* egl_qint - Ethernet interface queue entry available interrupt*/LOCAL void egl_qint    (    int unit,    EGL_SOFTC *egl    )    {    volatile SHIO *shio  = egl->eglAddr;    volatile CRB *crb    = &shio->sh_CRB;    volatile CSB *csb    = &shio->sh_CSB;    volatile USHORT *msr = &shio->sh_MCSB.mcsb_MSR;    IOPB tiopb;    tiopb = shio->sh_RET_IOPB;    /* controller not available */    if (*msr & M_MSR_CNA)        {#ifdef EGL_DEBUG        logMsg ("egl%d: died and restarted; error status = %#x\n",                unit, tiopb.iopb_STATUS, 0, 0, 0, 0);#endif        /* these errors (among others) will turn the LANCE transmitter           off, which will send us here */        /* any new ones? */        if (csb->csb_CSR0MEM > egl->egl_csr0mem)            {            egl->egl_csr0mem = csb->csb_CSR0MEM;#ifdef EGL_DEBUG            logMsg ("egl%d: %d csr0 MEMORY ERRORS caught\n",                    unit, egl->egl_csr0mem, 0, 0, 0, 0);#endif            }#ifdef EGL_DEBUG        /* save the returned IOPB */        logMsg ("returned IOPB: cmd %#x options %#x status %#x nvect %#x\n",                tiopb.iopb_CMD, tiopb.iopb_OPTION, tiopb.iopb_STATUS,                tiopb.iopb_NVCT, 0, 0);        logMsg ("evect %#x topt %#x buff_addr %#x length %#x\n",                tiopb.iopb_EVCT, tiopb.iopb_TOPT,                tiopb.iopb_BUFF, tiopb.iopb_LENGTH, 0, 0);        logMsg ("host_buf %#x ptlf %#x sge_cnt %#x lan1 %#x lan3 %#x\n",                tiopb.iopb_HBUF, tiopb.iopb_PTLF, tiopb.iopb_SGEC,                tiopb.iopb_LAN1, tiopb.iopb_LAN3, 0);        logMsg ("src/dest node %x:%x:%x:%x:%x:%x\n",                tiopb.iopb_NODE[0],tiopb.iopb_NODE[1],tiopb.iopb_NODE[2],                tiopb.iopb_NODE[3],tiopb.iopb_NODE[4],tiopb.iopb_NODE[5]);#endif  /* EGL_DEBUG */        egl_init (unit);        return;        }    if (CRB_QAVAIL(crb->crb_CRSW))        {        /* feed queue is no longer full */        egl->egl_qfull = 0;     /* at least one slot open now */        }    if (CRB_QSTARTED(crb->crb_CRSW))        {        /* how about q mode started */        egl->egl_qmode++;       /* remember for later */        }    CRB_CLR_DONE(crb->crb_CRSW);        /* release Eagle */    }/********************************************************************************* egl_recv - process Ethernet receive completion** This procedure handles Ethernet receive completion interrupts.  If* input error just drop packet, otherwise examine packet to determine* type.  If can't determine length from type, then have to drop packet,* otherwise decapsulate packet based on type and pass to type-specific* higher-level input routine.** RETURNS: ?*/LOCAL void egl_recv    (    int unit,    int len,    ETH_BUF *eth_buf    )    {    EGL_SOFTC *egl = egl_softc [unit];    struct ether_header *eh;    struct mbuf *m;#ifdef BSD43_DRIVER    int off;#endif    unsigned char *pData;    egl->egl_if.if_ipackets++;    /* speed fix (in Eagle firmware) for 14 byte Ethernet header */    eh = (struct ether_header *) ((int)eth_buf->eth_dat + 2);    /* call input hook if any */    if (etherInputHookRtn != NULL &&        (* etherInputHookRtn) (&egl->egl_if, (char *) eh, len))        {        return;        }    len -=  SIZEOF_ETHERHEADER + 4; /* total length - (ether header + CRC) */    pData = ((unsigned char *) eh) + SIZEOF_ETHERHEADER;#ifdef BSD43_DRIVER    check_trailer (eh, pData, &len, &off, &egl->egl_if);    if (len == 0)        return;    /* copy data from Eagle to mbuf a word at a time */    m = bcopy_to_mbufs (pData, len, off, (struct ifnet *) &egl->egl_if,                        eglMemWidth);    if (m != NULL)        do_protocol_with_type (eh->ether_type, m, &egl->egl_ac, len);

⌨️ 快捷键说明

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