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

📄 if_elc.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        do_protocol_with_type (eh->ether_type, m, &sc->es_ac, len);#else        /* copy data from the ring buffer to mbuf a long-word at a time */        m = bcopy_to_mbufs (pData, len, 0, (struct ifnet *) &sc->es_if, 2);        if (m == NULL)            {            sc->es_if.if_ierrors++;         /* bump error statistic */            goto doneGet;            }        do_protocol (eh, m, &sc->es_ac, len);#endifdoneGet:	sc->next = pH->next;	sc->uppByteCnt = pH->uppByteCnt;	}    /* update BOUND Register */    if (sc->next <= SMC8013WC_PSTART)	sysOutByte (ELC_BOUND (sc->elcAddr), SMC8013WC_PSTOP - 1);    else	sysOutByte (ELC_BOUND (sc->elcAddr), sc->next - 1);    sc->flags &= ~RXING;    /* go back if we received an interrupt and a new packet */    if (sc->next != sc->current)	goto unlucky;    }#ifdef BSD43_DRIVER/********************************************************************************* elcoutput - 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: ?*/LOCAL int elcoutput     (    struct ifnet *ifp,    struct mbuf *m0,    struct sockaddr *dst     )    {    return (ether_output (ifp, m0, dst, (FUNCPTR)elcPut,			  &elc_softc [ifp->if_unit].es_ac));    }#endif/********************************************************************************* elcPut - copy a packet to the interface.** Copy from mbuf chain to transmitter buffer in shared memory.**/#ifdef BSD43_DRIVERLOCAL void elcPut     (    int unit    )    {    FAST ELC_SOFTC *sc   = &elc_softc [unit];#elseLOCAL void elcPut     (    ELC_SOFTC *sc    )    {#endif    FAST struct mbuf *m;    FAST int len;    UINT transmitPage = sc->transmitPage[sc->transmitCnt & 1];    UCHAR *pBuf = (UCHAR *)(sc->memAddr + (transmitPage << 8));#ifdef BSD43_DRIVER    int s = splnet ();    if (sc->es_if.if_snd.ifq_head != NULL)#else    while (sc->es_if.if_snd.ifq_head != NULL)#endif	{	semTake (&elcSyncSem, sysClkRateGet());	IF_DEQUEUE (&sc->es_if.if_snd, m);	copy_from_mbufs (pBuf, m, len);	len = max (ETHERSMALL, len);	cacheDrvFlush (&cacheDmaFuncs, pBuf, len);	/* call output hook if any */	if ((etherOutputHookRtn != NULL) &&	    (* etherOutputHookRtn) (&sc->es_if, pBuf, len))#ifdef BSD43_DRIVER	    goto donePut;#else            continue;#endif	/* kick Transmitter */        sysOutByte (ELC_INTMASK (sc->elcAddr), 0x00);	sysOutByte (ELC_TSTART (sc->elcAddr), transmitPage);	sysOutByte (ELC_TCNTH (sc->elcAddr), len >> 8);	sysOutByte (ELC_TCNTL (sc->elcAddr), len & 0xff);	sysOutByte (ELC_CMD (sc->elcAddr), CMD_TXP);	sc->transmitCnt++;        sysOutByte (ELC_INTMASK (sc->elcAddr), 	    IM_OVWE | IM_TXEE | IM_PTXE | IM_PRXE);#ifndef BSD43_DRIVER        sc->es_if.if_opackets++;#endif	}#ifdef BSD43_DRIVERdonePut:    splx (s);#endif    }/********************************************************************************* elcReset - reset the chip** Reset the chip.**/LOCAL void elcReset     (    int unit    )    {    FAST ELC_SOFTC *sc   = &elc_softc [unit];    int s = splnet ();    /* mask interrupt */    sysOutByte (ELC_INTMASK (sc->elcAddr), 0x00);    bicInit (unit);    elcInit (unit);    /* unmask interrupt */    sysOutByte (ELC_INTMASK (sc->elcAddr), 	IM_OVWE | IM_TXEE | IM_PTXE | IM_PRXE);    sc->elcStat.reset++;    splx (s);    }/********************************************************************************* elcioctl - ioctl for interface** RETURNS: ?*/LOCAL int elcioctl     (    FAST struct ifnet *ifp,    int cmd,    caddr_t data     )    {    int error = 0;    int s;    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:            /* Handled outside module - nothing more to do. */	    break;	default:	    error = EINVAL;	}    splx (s);    return (error);    }/********************************************************************************* bicInit - initialize SMC83c584 BIC (Bus Interface Controller)** RETURNS: N/A** NOMANUAL*/LOCAL void bicInit     (    int unit    )    {    FAST ELC_SOFTC *sc	= &elc_softc[unit];    IRQ_TABLE *p	= &irqTable[sc->intLevel];    char laar = (sc->memAddr & 0xf80000) >> 19;    char msr  = (sc->memAddr & 0x07e000) >> 13;    char iar  = (sc->bicAddr & 0xe000) >> 8 | (sc->bicAddr & 0x03e0) >> 5;    char irr;    char icr;    char eeromIrr;    /* get IRQ level bits */    if (p->ir2 == 0xff)        p = &irqTable[3];		/* default is IRQ3 */    irr  = p->ir01 << 5;    icr  = p->ir2 << 2;    /* Reset and Recall */    sysOutByte (BIC_MSR (sc->bicAddr), MSR_RST);    sysOutByte (BIC_MSR (sc->bicAddr), 0);    taskDelay (sysClkRateGet () >> 2);    sysOutByte (BIC_ICR (sc->bicAddr), ICR_RLA | ICR_RX7);    while (sysInByte (BIC_ICR (sc->bicAddr)) & (ICR_RLA | ICR_RX7))	;    /* get values set by EEROM */    eeromIrr = sysInByte (BIC_IRR (sc->bicAddr));    /* Memory Select Reg: Enable, 0x??000. */    sysOutByte (BIC_MSR (sc->bicAddr), MSR_MEN | msr);    /* Interface Config Reg: 16Kbytes, 16Bit. */    sysOutByte (BIC_ICR (sc->bicAddr), ICR_BIT16 | icr);    /* IO Address Reg: 0x??0 */    sysOutByte (BIC_IAR (sc->bicAddr), iar);    /* BIOS ROM Address Reg: Disable */    sysOutByte (BIC_BIO (sc->bicAddr), 0x00);    /* Interrupt Request Reg: Enable, IRQ? */    if (sc->config == 1)        sysOutByte (BIC_IRR (sc->bicAddr), IRR_IEN | irr | IRR_OUT1);    else if (sc->config == 2)        sysOutByte (BIC_IRR (sc->bicAddr), IRR_IEN | irr | IRR_OUT1 | IRR_OUT2);    else        sysOutByte (BIC_IRR (sc->bicAddr), IRR_IEN | irr | IRR_OUT1 |		    (eeromIrr & 0x0e));    /* LA Address Reg: 16Bit-memory, 16Bit-lan, 0x??000 */    sysOutByte (BIC_LAAR (sc->bicAddr), LAAR_M16EN | LAAR_L16EN | laar);    }/********************************************************************************* elcInit - initialize SMC83c690 ELC (Ethernet LAN Controller)** RETURNS: N/A** NOMANUAL*/LOCAL void elcInit     (    int unit    )    {    FAST ELC_SOFTC *sc          = &elc_softc[unit];    /* 1. program Command Register for page 0 */    sysOutByte (ELC_CMD (sc->elcAddr), CMD_CMD5 | CMD_STP);    while ((sysInByte (ELC_INTSTAT (sc->elcAddr)) & ISTAT_RST) != ISTAT_RST)	;    /* 2. initialize Data Configuration Register */    sysOutByte (ELC_DCON (sc->elcAddr), DCON_BSIZE1 | DCON_BUS16 | 0x08);    /* 3. clear Remote Byte Count Register */    sysOutByte (ELC_RBCR0 (sc->elcAddr), 0x00);    sysOutByte (ELC_RBCR1 (sc->elcAddr), 0x00);    /* 4. initialize Receive Configuration Register */    sysOutByte (ELC_RCON (sc->elcAddr), 0x04);    /* 5. place the ELC in LOOPBACK mode 1 or 2 */    sysOutByte (ELC_TCON (sc->elcAddr), TCON_LB1);    /* 6. initialize Receive Buffer Ring */    sysOutByte (ELC_RSTART (sc->elcAddr), SMC8013WC_PSTART);    sysOutByte (ELC_RSTOP (sc->elcAddr), SMC8013WC_PSTOP);    sysOutByte (ELC_BOUND (sc->elcAddr), SMC8013WC_PSTART);    /* 7. clear Interrupt Status Register */    sysOutByte (ELC_INTSTAT (sc->elcAddr), 0xff);    /* 8. initialize Interrupt Mask Register */    sysOutByte (ELC_INTMASK (sc->elcAddr), 0x00);    /* 9. program Command Register for page 1 */    sysOutByte (ELC_CMD (sc->elcAddr), CMD_PS0 | CMD_STP);    sysOutByte (ELC_STA0 (sc->elcAddr), sysInByte (BIC_LAR0 (sc->bicAddr)));    sysOutByte (ELC_STA1 (sc->elcAddr), sysInByte (BIC_LAR1 (sc->bicAddr)));    sysOutByte (ELC_STA2 (sc->elcAddr), sysInByte (BIC_LAR2 (sc->bicAddr)));    sysOutByte (ELC_STA3 (sc->elcAddr), sysInByte (BIC_LAR3 (sc->bicAddr)));    sysOutByte (ELC_STA4 (sc->elcAddr), sysInByte (BIC_LAR4 (sc->bicAddr)));    sysOutByte (ELC_STA5 (sc->elcAddr), sysInByte (BIC_LAR5 (sc->bicAddr)));    sysOutByte (ELC_MAR0 (sc->elcAddr), 0);    sysOutByte (ELC_MAR1 (sc->elcAddr), 0);    sysOutByte (ELC_MAR2 (sc->elcAddr), 0);    sysOutByte (ELC_MAR3 (sc->elcAddr), 0);    sysOutByte (ELC_MAR4 (sc->elcAddr), 0);    sysOutByte (ELC_MAR5 (sc->elcAddr), 0);    sysOutByte (ELC_MAR6 (sc->elcAddr), 0);    sysOutByte (ELC_MAR7 (sc->elcAddr), 0);    sc->next = SMC8013WC_PSTART + 1;    sysOutByte (ELC_CURR (sc->elcAddr), sc->next);    sysOutByte (ELC_CMD (sc->elcAddr), CMD_PS1 | CMD_STP);    sysOutByte (ELC_ENH (sc->elcAddr), 0x00);	/* 0 wait states */    sysOutByte (ELC_BLOCK (sc->elcAddr), 0x00);	/* 0x00xxxx */    /* 10. put the ELC in START mode */    sysOutByte (ELC_CMD (sc->elcAddr), CMD_STA);    /* 11. initialize Transmit Configuration Register */    sysOutByte (ELC_TCON (sc->elcAddr), 0x00);    }/********************************************************************************* elcGetAddr - get hardwired ethernet address.** Read the ethernet address off the board, one byte at a time.**/LOCAL void elcGetAddr     (    int unit     )    {    FAST ELC_SOFTC *sc          = &elc_softc[unit];    UCHAR *pAddr		= (UCHAR *)sc->es_enaddr;    *pAddr++ = sysInByte (BIC_LAR0 (sc->bicAddr));    *pAddr++ = sysInByte (BIC_LAR1 (sc->bicAddr));    *pAddr++ = sysInByte (BIC_LAR2 (sc->bicAddr));    *pAddr++ = sysInByte (BIC_LAR3 (sc->bicAddr));    *pAddr++ = sysInByte (BIC_LAR4 (sc->bicAddr));    *pAddr   = sysInByte (BIC_LAR5 (sc->bicAddr));    }/********************************************************************************* elcGetCurr - get current page** RETURNS: current page that ELC is working on** NOMANUAL*/LOCAL UCHAR elcGetCurr     (    int unit    )    {    FAST ELC_SOFTC *sc          = &elc_softc[unit];    UCHAR curr;    /* get CURR register */    sysOutByte (ELC_CMD (sc->elcAddr), CMD_PS0);    curr = sysInByte (ELC_CURR (sc->elcAddr));    sysOutByte (ELC_CMD (sc->elcAddr), 0);    return (curr);    }/********************************************************************************* elcShow - display statistics for the SMC 8013WC `elc' network interface** This routine displays statistics about the `elc' Ethernet network interface.* It has two parameters: * .iP <unit>* interface unit; should be 0.* .iP <zap>* if 1, all collected statistics are cleared to zero.* .LP** RETURNS: N/A*/void elcShow     (    int unit,   /* interface unit */    BOOL zap    /* 1 = zero totals */    )    {    FAST ELC_SOFTC *sc          = &elc_softc[unit];    FAST int ix;    static char *e_message [] = {	"collisions",	"crcs",	"aligns",	"missed",	"over-runs",	"disabled",	"deferring",	"under-run",	"aborts",	"out-of-window",	"heart-beats",	"bad-packet",	"short-packet",	"t-no-error",	"r-no-error",	"t-error",	"r-error",	"over-write",	"wrapped",	"interrupts",	"reset",	"stray-int"};    for (ix = 0; ix < NELEMENTS(e_message); ix++)	{	printf ("    %-30.30s  %4d\n", e_message [ix], sc->elcStat.stat [ix]);	if (zap)	    sc->elcStat.stat [ix] = 0;	}    printf ("    %-30.30s  0x%2x\n", "flags", sc->flags);    }/********************************************************************************* elcdetach - detach the card from the bus.** Dettach the card from the bus for reset.** RETURNS: N/A** NOMANUAL*/void elcdetach     (    int unit    )    {    FAST ELC_SOFTC *sc	= &elc_softc[unit];    if (elcAttached)	{        sysOutByte (ELC_INTMASK (sc->elcAddr), 0x00);        sysOutByte (ELC_CMD (sc->elcAddr), CMD_CMD5 | CMD_STP);        while ((sysInByte (ELC_INTSTAT (sc->elcAddr)) & ISTAT_RST) != ISTAT_RST)	    ;        sysOutByte (ELC_RCON (sc->elcAddr), 0x00);        sysOutByte (ELC_TCON (sc->elcAddr), TCON_LB1);        sysIntDisablePIC (sc->intLevel);        sysOutByte (BIC_MSR (sc->bicAddr), MSR_RST);        taskDelay (sysClkRateGet () >> 1);        sysOutByte (BIC_MSR (sc->bicAddr), 0x00);        taskDelay (sysClkRateGet () >> 1);	}    }

⌨️ 快捷键说明

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