📄 if_ultra.c
字号:
{ FAST ULTRA_SOFTC *sc = &ultra_softc[unit]; FAST ULTRA_HEADER *pH; FAST struct ether_header *eh; FAST struct mbuf *m; int len;#ifdef BSD43_DRIVER int off;#endif int ix; USHORT wrapSize; USHORT packetSize; char *pSrc; char *pDst; UCHAR *pData;unlucky: ix = 0; while ((sc->next != sc->current) && (ix++ < ULTRA_PSTOP)) { /* Invalidate cache */ cacheDrvInvalidate (&cacheDmaFuncs, (UCHAR *)(sc->memAddr + (ULTRA_PSTART << 8)), (sc->memSize - (ULTRA_PSTART << 8))); pH = (ULTRA_HEADER *)(sc->memAddr + (sc->next << 8)); /* sanity check */ if ((pH->next < ULTRA_PSTART) || (pH->next >= ULTRA_PSTOP)) { sc->stat.badPacket++; pH->next = sc->next + sc->uppByteCnt + 1; if (pH->next >= ULTRA_PSTOP) pH->next = ULTRA_PSTART + (pH->next - ULTRA_PSTOP); } packetSize = *(USHORT *)(&pH->lowByteCnt); if (packetSize < (ULTRA_MIN_SIZE)) { sc->stat.shortPacket++; goto doneGet; } if (packetSize > (ULTRA_MAX_SIZE)) { sc->stat.longPacket++; goto doneGet; } sc->es_if.if_ipackets++; /* bump statistic */ if (pH->next > sc->next) wrapSize = 0; else wrapSize = min (packetSize, ((ULTRA_PSTOP - sc->next) << 8)); /* copy separated frame to a temporary buffer */ if (wrapSize) { sc->stat.wrapped++; pSrc = (char *)pH; pDst = (char *)sc->receiveBuf; bcopy (pSrc, pDst, wrapSize); pSrc = (char *)(sc->memAddr + (ULTRA_PSTART << 8)); pDst += wrapSize; len = packetSize - wrapSize; if (len) bcopy (pSrc, pDst, len); } len = packetSize - 4; /* remove CRCs 4 bytes */ if (wrapSize) eh = (struct ether_header *)((UINT)sc->receiveBuf + sizeof (ULTRA_HEADER)); else eh = (struct ether_header *)((UINT)pH + sizeof (ULTRA_HEADER)); /* call input hook if any */ if ((etherInputHookRtn != NULL) && (* etherInputHookRtn) (&sc->es_if, (char *) eh, len)) { goto doneGet; } if (len >= SIZEOF_ETHERHEADER) len -= SIZEOF_ETHERHEADER; else goto doneGet; pData = ((unsigned char *) eh) + SIZEOF_ETHERHEADER;#ifdef BSD43_DRIVER check_trailer (eh, pData, &len, &off, &sc->es_if); /* copy data from the ring buffer to mbuf a long-word at a time */ m = bcopy_to_mbufs (pData, len, off, (struct ifnet *) &sc->es_if, 2); if (m == NULL) { sc->es_if.if_ierrors++; /* bump error statistic */ goto doneGet; } 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 < ULTRA_PSTART) || (sc->next >= ULTRA_PSTOP)) sysOutByte (LAN_BOUND (sc->ioAddr), ULTRA_PSTART); else sysOutByte (LAN_BOUND (sc->ioAddr), sc->next); sc->flags &= ~RXING; /* go back if we received an interrupt and a new packet */ if (sc->next != sc->current) goto unlucky; }/********************************************************************************* ultraPut - copy a packet to the interface.** Copy from mbuf chain to transmitter buffer in shared memory.** RETURNS: N/A*/#ifdef BSD43_DRIVERLOCAL void ultraPut ( int unit /* device unit number */ ) { FAST ULTRA_SOFTC *sc = &ultra_softc [unit];#elseLOCAL void ultraPut ( ULTRA_SOFTC *sc /* device context */ ) {#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 ();#endif while (sc->es_if.if_snd.ifq_head != NULL) { semTake (&ultraSyncSem, sysClkRateGet ()); IF_DEQUEUE (&sc->es_if.if_snd, m); if (m != NULL) { 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)) continue; /* kick Transmitter */ sysOutByte (LAN_INTMASK (sc->ioAddr), 0x00); sysOutByte (LAN_TSTART (sc->ioAddr), transmitPage); sysOutByte (LAN_TCNTH (sc->ioAddr), len >> 8); sysOutByte (LAN_TCNTL (sc->ioAddr), len & 0xff); sysOutByte (LAN_CMD (sc->ioAddr), CMD_TXP); sc->transmitCnt++; sysOutByte (LAN_INTMASK (sc->ioAddr), IM_OVWE | IM_TXEE | IM_PTXE | IM_PRXE);#ifndef BSD43_DRIVER sc->es_if.if_opackets++;#endif } }#ifdef BSD43_DRIVER splx (s);#endif }/********************************************************************************* ultraInit - initialize Elite Ultra (Ethernet LAN Controller)** RETURNS: N/A*/LOCAL void ultraInit ( int unit /* device unit number */ ) { FAST ULTRA_SOFTC *sc = &ultra_softc[unit]; UCHAR *pAddr = (UCHAR *)sc->es_enaddr; UCHAR memAddr; UCHAR intLevel; UCHAR ioAddr; UCHAR eeromGcon; /* mask interrupt */ sysOutByte (LAN_INTMASK (sc->ioAddr), 0x00); /* reset */ sysOutByte (CTRL_CON (sc->ioAddr), CON_RESET); sysOutByte (CTRL_CON (sc->ioAddr), 0x00); sysOutByte (CTRL_HARD (sc->ioAddr), 0x08); taskDelay (sysClkRateGet () >> 2); sysOutByte (CTRL_CON (sc->ioAddr), CON_MENABLE); /* get values set by EEROM */ sysOutByte (CTRL_HARD (sc->ioAddr), 0x80); eeromGcon = sysInByte (CTRL_GCON(sc->ioAddr)); /* IO address, Memory address, Interrupt request */ memAddr = ((sc->memAddr & 0x1e000) >> 13) | ((sc->memAddr & 0x20000) >> 10); intLevel = ((sc->intLevel & 0x03) << 2) | ((sc->intLevel & 0x04) << 6); ioAddr = ((sc->ioAddr & 0xe000) >> 8) | ((sc->ioAddr & 0x01e0) >> 4); sysOutByte (CTRL_HARD (sc->ioAddr), 0x80); sysOutByte (CTRL_IOADDR (sc->ioAddr), ioAddr); sysOutByte (CTRL_MEMADDR (sc->ioAddr), memAddr | 0x10); if (sc->config == 1) sysOutByte (CTRL_GCON (sc->ioAddr), irqTable[sc->intLevel].reg | (eeromGcon & 0x20)); else if (sc->config == 2) sysOutByte (CTRL_GCON (sc->ioAddr), irqTable[sc->intLevel].reg | 0x02 | (eeromGcon & 0x20)); else sysOutByte (CTRL_GCON (sc->ioAddr), irqTable[sc->intLevel].reg | (eeromGcon & 0x22)); /* set FINE16 bit in BIO register to get finer resolution for M16CS decode */ sysOutByte (CTRL_BIO (sc->ioAddr), sysInByte (CTRL_BIO (sc->ioAddr) | 0x80)); sysOutByte (CTRL_HARD (sc->ioAddr), 0x00); /* 16 bit enable */ sysOutByte (CTRL_BIOS (sc->ioAddr), BIOS_M16EN); /* program Command Register for page 0 */ sysOutByte (LAN_CMD (sc->ioAddr), CMD_STP); while ((sysInByte (LAN_INTSTAT (sc->ioAddr)) & ISTAT_RST) != ISTAT_RST) ; /* initialize Data Configuration Register */ sysOutByte (LAN_DCON (sc->ioAddr), DCON_BSIZE1 | DCON_BUS16); /* initialize Receive Configuration Register */ sysOutByte (LAN_RCON (sc->ioAddr), 0x04); /* place the Ultra in LOOPBACK mode 1 or 2 */ sysOutByte (LAN_TCON (sc->ioAddr), TCON_LB1); /* initialize Receive Buffer Ring */ sysOutByte (LAN_RSTART (sc->ioAddr), ULTRA_PSTART); sysOutByte (LAN_RSTOP (sc->ioAddr), ULTRA_PSTOP); sysOutByte (LAN_BOUND (sc->ioAddr), ULTRA_PSTART); /* clear Interrupt Status Register */ sysOutByte (LAN_INTSTAT (sc->ioAddr), 0xff); /* initialize Interrupt Mask Register */ sysOutByte (LAN_INTMASK (sc->ioAddr), 0x00); /* program Command Register for page 1 */ sysOutByte (LAN_CMD (sc->ioAddr), CMD_PS0 | CMD_STP); sysOutByte (LAN_STA0 (sc->ioAddr), sysInByte (CTRL_LAN0 (sc->ioAddr))); sysOutByte (LAN_STA1 (sc->ioAddr), sysInByte (CTRL_LAN1 (sc->ioAddr))); sysOutByte (LAN_STA2 (sc->ioAddr), sysInByte (CTRL_LAN2 (sc->ioAddr))); sysOutByte (LAN_STA3 (sc->ioAddr), sysInByte (CTRL_LAN3 (sc->ioAddr))); sysOutByte (LAN_STA4 (sc->ioAddr), sysInByte (CTRL_LAN4 (sc->ioAddr))); sysOutByte (LAN_STA5 (sc->ioAddr), sysInByte (CTRL_LAN5 (sc->ioAddr))); *pAddr++ = sysInByte (CTRL_LAN0 (sc->ioAddr)); *pAddr++ = sysInByte (CTRL_LAN1 (sc->ioAddr)); *pAddr++ = sysInByte (CTRL_LAN2 (sc->ioAddr)); *pAddr++ = sysInByte (CTRL_LAN3 (sc->ioAddr)); *pAddr++ = sysInByte (CTRL_LAN4 (sc->ioAddr)); *pAddr = sysInByte (CTRL_LAN5 (sc->ioAddr)); sysOutByte (LAN_MAR0 (sc->ioAddr), 0); sysOutByte (LAN_MAR1 (sc->ioAddr), 0); sysOutByte (LAN_MAR2 (sc->ioAddr), 0); sysOutByte (LAN_MAR3 (sc->ioAddr), 0); sysOutByte (LAN_MAR4 (sc->ioAddr), 0); sysOutByte (LAN_MAR5 (sc->ioAddr), 0); sysOutByte (LAN_MAR6 (sc->ioAddr), 0); sysOutByte (LAN_MAR7 (sc->ioAddr), 0); sc->next = ULTRA_PSTART + 1; sysOutByte (LAN_CURR (sc->ioAddr), sc->next); sysOutByte (LAN_CMD (sc->ioAddr), CMD_PS1 | CMD_STP); sysOutByte (LAN_ENH (sc->ioAddr), 0x00); /* 0 wait states */ /* put the Ultra in START mode */ sysOutByte (LAN_CMD (sc->ioAddr), CMD_STA); /* initialize Transmit Configuration Register */ sysOutByte (LAN_TCON (sc->ioAddr), 0x00); /* enable interrupt */ sysOutByte (CTRL_INT (sc->ioAddr), INT_ENABLE); sysOutByte (LAN_INTMASK (sc->ioAddr), IM_OVWE | IM_TXEE | IM_PTXE | IM_PRXE); }/********************************************************************************* ultraShow - display statistics for the `ultra' 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 ultraShow ( int unit, /* interface unit */ BOOL zap /* zero totals */ ) { FAST ULTRA_SOFTC *sc = &ultra_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", "long-packet", "t-no-error", "r-no-error", "t-error", "r-error", "over-write", "wrapped", "interrupts", "reset", "stray-int"}; printf ("ioAddr=0x%x memAddr=0x%x memSize=0x%x vector=0x%x level=0x%x\n", sc->ioAddr, sc->memAddr, sc->memSize, sc->intVec, sc->intLevel); for (ix = 0; ix < NELEMENTS(e_message); ix++) { printf (" %-30.30s %4d\n", e_message [ix], sc->stat.stat [ix]); if (zap) sc->stat.stat [ix] = 0; } printf (" %-30.30s 0x%2x\n", "flags", sc->flags); }/********************************************************************************* ultradetach - detach the card from the bus.** Dettach the card from the bus for reset.** RETURNS: N/A** NOMANUAL*/void ultradetach ( int unit /* device unit number */ ) { FAST ULTRA_SOFTC *sc = &ultra_softc[unit]; if (ultraAttached) { sysOutByte (LAN_INTMASK (sc->ioAddr), 0x00); sysOutByte (LAN_CMD (sc->ioAddr), CMD_STP); while ((sysInByte (LAN_INTSTAT (sc->ioAddr)) & ISTAT_RST) != ISTAT_RST) ; sysOutByte (LAN_RCON (sc->ioAddr), 0x00); sysOutByte (LAN_TCON (sc->ioAddr), TCON_LB1); sysIntDisablePIC (sc->intLevel); sysOutByte (CTRL_CON (sc->ioAddr), CON_RESET); taskDelay (sysClkRateGet () >> 1); sysOutByte (CTRL_CON (sc->ioAddr), 0x00); taskDelay (sysClkRateGet () >> 1); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -