📄 if_ene.c
字号:
#ifdef OLDSTUFF while ((sysInByte (ENE_INTSTAT (pSoftc->eneAddr)) & ISTAT_RST) != ISTAT_RST) ;#endif /* OLDSTUFF */ /* 2. initialize Data Configuration Register: * 16-bit bus, burst mode, 8-deep FIFO. */ sysOutByte (ENE_DCON (pSoftc->eneAddr), DCON_BSIZE1 | DCON_BUS16 | 0x08); eneGetAddr (unit); /* get ethernet address */ /* 3. clear Remote Byte Count Register */ sysOutByte (ENE_RBCR0 (pSoftc->eneAddr), 0x00); sysOutByte (ENE_RBCR1 (pSoftc->eneAddr), 0x00); /* 4. initialize Receive Configuration Register */ sysOutByte (ENE_RCON (pSoftc->eneAddr), pSoftc->rxFilter); /* 5. place the ENE in LOOPBACK mode 1 or 2 */ sysOutByte (ENE_TCON (pSoftc->eneAddr), TCON_LB1); /* 6. initialize Receive Buffer Ring */ sysOutByte (ENE_RSTART (pSoftc->eneAddr), NE2000_PSTART); sysOutByte (ENE_RSTOP (pSoftc->eneAddr), (char)NE2000_PSTOP); sysOutByte (ENE_BOUND (pSoftc->eneAddr), (char)NE2000_PSTART); /* 7. clear Interrupt Status Register */ sysOutByte (ENE_INTSTAT (pSoftc->eneAddr), (char)0xff); /* 8. initialize Interrupt Mask Register */ sysOutByte (ENE_INTMASK (pSoftc->eneAddr), 0x00); /* 9. program Command Register for page 1 */ sysOutByte (ENE_CMD (pSoftc->eneAddr), CMD_PAGE1 | CMD_STOP); /* i) initialize physical address registers */ sysOutByte (ENE_STA0 (pSoftc->eneAddr), *pAddr++); sysOutByte (ENE_STA1 (pSoftc->eneAddr), *pAddr++); sysOutByte (ENE_STA2 (pSoftc->eneAddr), *pAddr++); sysOutByte (ENE_STA3 (pSoftc->eneAddr), *pAddr++); sysOutByte (ENE_STA4 (pSoftc->eneAddr), *pAddr++); sysOutByte (ENE_STA5 (pSoftc->eneAddr), *pAddr); /* ii) initialize multicast address registers */ sysOutByte (ENE_MAR0 (pSoftc->eneAddr), 0); sysOutByte (ENE_MAR1 (pSoftc->eneAddr), 0); sysOutByte (ENE_MAR2 (pSoftc->eneAddr), 0); sysOutByte (ENE_MAR3 (pSoftc->eneAddr), 0); sysOutByte (ENE_MAR4 (pSoftc->eneAddr), 0); sysOutByte (ENE_MAR5 (pSoftc->eneAddr), 0); sysOutByte (ENE_MAR6 (pSoftc->eneAddr), 0); sysOutByte (ENE_MAR7 (pSoftc->eneAddr), 0); /* iii) initialize current page pointer */ sysOutByte (ENE_CURR (pSoftc->eneAddr), NE2000_PSTART + 1); pSoftc->nextPacket = NE2000_PSTART + 1; /* set memory parameters */ sysOutByte (ENE_CMD (pSoftc->eneAddr), (char)(CMD_NODMA | CMD_PAGE2 | CMD_STOP)); sysOutByte (ENE_ENH (pSoftc->eneAddr), 0x00); /* 0 wait states */ sysOutByte (ENE_BLOCK (pSoftc->eneAddr), 0x00); /* 0x00xxxx */ /* 10. put the ENE in START mode */ sysOutByte (ENE_CMD (pSoftc->eneAddr), CMD_NODMA | CMD_PAGE0 | CMD_START); /* 11. initialize Transmit Configuration Register */ sysOutByte (ENE_TCON (pSoftc->eneAddr), 0x00); }/********************************************************************************* eneGetAddr - get hardwired ethernet address.** Read the ethernet address from the board's byte-wide configuration memory,* one byte at a time. If we could read it in word-wide cycles, we could use* eneDataIn(), below. The on-board logic requires double the byte count!**/static void eneGetAddr ( int unit ) { FAST ENE_SOFTC * pSoftc = pEneSoftc [unit]; UCHAR * pAddr = (UCHAR *)pSoftc->es_enaddr; sysOutByte (ENE_CMD (pSoftc->eneAddr), CMD_NODMA | CMD_PAGE0 | CMD_START); sysOutByte (ENE_RSAR0 (pSoftc->eneAddr), NE2000_EADDR_LOC); sysOutByte (ENE_RSAR1 (pSoftc->eneAddr), NE2000_CONFIG_PAGE); sysOutByte (ENE_RBCR0 (pSoftc->eneAddr), (EA_SIZE * 2) & 0xff); sysOutByte (ENE_RBCR1 (pSoftc->eneAddr), (EA_SIZE * 2) >> 8); sysOutByte (ENE_CMD (pSoftc->eneAddr), CMD_RREAD | CMD_START); *pAddr++ = sysInByte (ENE_DATA (pSoftc->eneAddr)); *pAddr++ = sysInByte (ENE_DATA (pSoftc->eneAddr)); *pAddr++ = sysInByte (ENE_DATA (pSoftc->eneAddr)); *pAddr++ = sysInByte (ENE_DATA (pSoftc->eneAddr)); *pAddr++ = sysInByte (ENE_DATA (pSoftc->eneAddr)); *pAddr = sysInByte (ENE_DATA (pSoftc->eneAddr)); }/********************************************************************************* eneDataOut - output bytes to NE2000 memory** NOMANUAL*/static void eneDataOut ( int unit, char * pData, UINT16 len, UINT16 eneAddress ) { FAST ENE_SOFTC * pSoftc = pEneSoftc [unit]; if (len == 0) return; /* nothing to do */#ifndef BSD43_DRIVER /* Bump the statistic counter. */ pSoftc->es_if.if_opackets++;#endif sysOutByte (ENE_INTMASK (pSoftc->eneAddr), 0); /* disable board ints.*/ sysOutByte (ENE_RBCR0 (pSoftc->eneAddr), (char)0xff); sysOutByte (ENE_CMD (pSoftc->eneAddr), CMD_NODMA | CMD_PAGE0 | CMD_START); sysOutByte (ENE_RSAR0 (pSoftc->eneAddr), eneAddress & 0xff); sysOutByte (ENE_RSAR1 (pSoftc->eneAddr), eneAddress >> 8); sysOutByte (ENE_RBCR0 (pSoftc->eneAddr), len & 0xff); sysOutByte (ENE_RBCR1 (pSoftc->eneAddr), len >> 8); sysOutByte (ENE_CMD (pSoftc->eneAddr), CMD_RWRITE | CMD_START); sysOutWordString (ENE_DATA (pSoftc->eneAddr), (short *)pData, (len / 2)); if (len & 1) sysOutByte (ENE_DATA (pSoftc->eneAddr), *(pData + (len - 1))); eneIntEnable (unit); }/********************************************************************************* eneDataIn - input bytes from NE2000 memory** NOMANUAL*/static void eneDataIn ( int unit, UINT16 eneAddress, UINT16 len, char * pData ) { FAST ENE_SOFTC * pSoftc = pEneSoftc [unit]; sysOutByte (ENE_INTMASK (pSoftc->eneAddr), 0); sysOutByte (ENE_CMD (pSoftc->eneAddr), CMD_NODMA | CMD_PAGE0 | CMD_START); sysOutByte (ENE_RSAR0 (pSoftc->eneAddr), eneAddress & 0xff); sysOutByte (ENE_RSAR1 (pSoftc->eneAddr), eneAddress >> 8); sysOutByte (ENE_RBCR0 (pSoftc->eneAddr), len & 0xff); sysOutByte (ENE_RBCR1 (pSoftc->eneAddr), len >> 8); sysOutByte (ENE_CMD (pSoftc->eneAddr), CMD_RREAD | CMD_START); sysInWordString (ENE_DATA (pSoftc->eneAddr), (short *)pData, (len / 2)); if (len & 1) *(pData + (len - 1)) = sysInByte (ENE_DATA (pSoftc->eneAddr)); eneIntEnable (unit); }/********************************************************************************* eneGetCurr - get current page** RETURNS: current page that ENE is working on** NOMANUAL*/static UCHAR eneGetCurr ( int unit ) { FAST ENE_SOFTC * pSoftc = pEneSoftc [unit]; UCHAR curr; /* get CURR register */ sysOutByte (ENE_CMD (pSoftc->eneAddr), CMD_PAGE1); curr = sysInByte (ENE_CURR (pSoftc->eneAddr)); sysOutByte (ENE_CMD (pSoftc->eneAddr), CMD_PAGE0); return (curr); }/********************************************************************************* eneIntEnable - enable NE2000 interrupt conditions*/static void eneIntEnable ( int unit ) { FAST ENE_SOFTC * pSoftc = pEneSoftc [unit]; sysOutByte (ENE_INTMASK (pSoftc->eneAddr), IM_OVWE | IM_TXEE | IM_RXEE | IM_PTXE | IM_PRXE); }/********************************************************************************* eneOverwriteRecover - recover from receive buffer ring overflow** This procedure is mandated by National Semiconductor as the only safe* way to recover from an Overwrite Warning Error. The first two steps* of their procedure, reading the Command Register and stopping the NIC,* were accomplished in the interrupt handler. The rest occurs here.** This routine is scheduled to run in the net task since it must delay* to allow the STOP command to take effect.*/static void eneOverwriteRecover ( int unit, UCHAR cmdStatus ) { FAST ENE_SOFTC * pSoftc = pEneSoftc [unit]; BOOL reSend; /* 1. read the TXP bit in the command register (already in cmdStatus) */ /* 2. issue the STOP command (done in the interrupt handler) */ /* 3. delay at least 1.6 milliseconds (1/625 second) */ taskDelay ((sysClkRateGet () / 625) + 1); /* we are now supposedly sure the NIC is stopped */ /* 4. clear Remote Byte Count Register */ sysOutByte (ENE_RBCR0 (pSoftc->eneAddr), 0x00); sysOutByte (ENE_RBCR1 (pSoftc->eneAddr), 0x00); /* 5. read the stored value of the TXP bit (in cmdStatus) */ if ( (cmdStatus & CMD_TXP) == 0) reSend = FALSE; else { if ((sysInByte (ENE_INTSTAT (pSoftc->eneAddr)) & (ISTAT_PTX | ISTAT_TXE)) == 0) /* transmit was in progress but probably deferring */ reSend = TRUE; else /* transmit was completed (probably), don't repeat it */ reSend = FALSE; } /* 6. place the NIC in loopback mode */ sysOutByte (ENE_TCON (pSoftc->eneAddr), TCON_LB1); /* 7. issue the START command to the NIC */ sysOutByte (ENE_CMD (pSoftc->eneAddr), CMD_NODMA | CMD_PAGE0 | CMD_START); /* 8. remove one or more packets from the receive buffer ring */ pSoftc->current = eneGetCurr (unit); eneGet (unit); /* get all the packets there are */ /* 9. reset the overwrite warning bit in the ISR */ /* reset all active interrupt conditions */ sysOutByte (ENE_INTSTAT (pSoftc->eneAddr), sysInByte (ENE_INTSTAT (pSoftc->eneAddr))); /* 10. take the NIC out of loopback */ sysOutByte (ENE_TCON (pSoftc->eneAddr), 0x00); /* 11. if need to resend, do so, otherwise if anything queued, send that */ if (reSend) sysOutByte (ENE_CMD (pSoftc->eneAddr), CMD_TXP); else if (pSoftc->es_if.if_snd.ifq_head != NULL)#ifdef BSD43_DRIVER enePut (unit);#else enePut (pSoftc);#endif }/********************************************************************************* eneShow - display statistics for the NE2000 `ene' network interface** This routine displays statistics about the `ene' 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 eneShow ( int unit, /* interface unit */ BOOL zap /* 1 = zero totals */ ) { FAST ENE_SOFTC * pSoftc; FAST int ix; static char * e_message [] = { "collisions", "crcs", "aligns", "missed", "over-runs", "disabled", "deferring", "under-run", "aborts", "out-of-window coll", "heart-beats", "bad-packet", "short-packet", "t-no-error", "r-no-error", "t-error", "r-error", "over-write", "wrapped", "interrupts", "reset", "stray-int", "jabbers"}; if ((UINT)unit >= NENE) { printf ("eneShow: invalid unit number %d; valid range 0..%d\n", unit, NENE); return; } pSoftc = pEneSoftc [unit]; if ((pSoftc == NULL) || ! pSoftc->attached) { printf ("eneShow: unit %d not attached\n", unit); return; } for (ix = 0; ix < NELEMENTS(e_message); ix++) { printf (" %-30.30s %4d\n", e_message [ix], pSoftc->eneStat.stat [ix]); if (zap) pSoftc->eneStat.stat [ix] = 0; } printf (" %-30.30s 0x%02x\n", "flags", pSoftc->flags); }/********************************************************************************* enedetach - detach the card from the bus.** Dettach the card from the bus for reset.** RETURNS: N/A** NOMANUAL*/void enedetach ( int unit ) { FAST ENE_SOFTC * pSoftc = pEneSoftc [unit]; if (pSoftc->attached) { sysOutByte (ENE_INTMASK (pSoftc->eneAddr), 0x00); sysOutByte (ENE_CMD (pSoftc->eneAddr), CMD_NODMA | CMD_STOP); while ((sysInByte (ENE_INTSTAT (pSoftc->eneAddr)) & ISTAT_RST) != ISTAT_RST) ; sysOutByte (ENE_RCON (pSoftc->eneAddr), 0x00); sysOutByte (ENE_TCON (pSoftc->eneAddr), TCON_LB1); sysIntDisablePIC (pSoftc->intLevel); eneBoardReset (unit); } pSoftc->attached = FALSE; /* allow a new attach */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -